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.65 2008/01/22 12:32:50 vchauhan ship $ */
3 
4                       ------------------------
5                       -- Private Data Types --
6                       ------------------------
7 
8     TYPE LOCAL_NUMBER_TABLE IS TABLE OF NUMBER
9       INDEX BY BINARY_INTEGER;
10 
11     TYPE LOCAL_VARCHAR_TABLE IS TABLE OF VARCHAR2(30)
12       INDEX BY BINARY_INTEGER;
13 
14     TYPE LOCAL_MEDIUM_VARCHAR_TABLE IS TABLE OF VARCHAR2(300)
15       INDEX BY BINARY_INTEGER;
16 
17     TYPE LOCAL_BIG_VARCHAR_TABLE IS TABLE OF VARCHAR2(5000)
18       INDEX BY BINARY_INTEGER;
19 
20     TYPE LOCAL_COL_NV_PAIR_TABLE IS TABLE OF EGO_COL_NAME_VALUE_PAIR_OBJ
21       INDEX BY BINARY_INTEGER;
22 
23     TYPE LOCAL_USER_ATTR_DATA_TABLE IS TABLE OF EGO_USER_ATTR_DATA_OBJ
24       INDEX BY BINARY_INTEGER;
25 
26     TYPE LOCAL_USER_ATTR_ROW_TABLE IS TABLE OF EGO_USER_ATTR_ROW_OBJ
27       INDEX BY BINARY_INTEGER;
28 
29     TYPE VARCHAR2_TBL_TYPE         IS VARRAY(100) OF VARCHAR2(2000);
30     TYPE DATE_TBL_TYPE             IS VARRAY(100) OF DATE;
31     TYPE NUMBER_TBL_TYPE           IS VARRAY(100) OF NUMBER;
32 
33     ----------------------------------------------------------------------
34     -- Type for tracking Attr Data for Get_User_Attrs_Data, including a --
35     -- field for DATABASE_COLUMN so we can match up columns from query  --
36     ----------------------------------------------------------------------
37     TYPE LOCAL_USER_ATTR_DATA_REC IS RECORD
38     (
39         ATTR_GROUP_ID                        NUMBER
40        ,APPLICATION_ID                       NUMBER
41        ,ATTR_GROUP_TYPE                      VARCHAR2(40)
42        ,ATTR_GROUP_NAME                      VARCHAR2(30)
43        ,ATTR_NAME                            VARCHAR2(30)
44        ,ATTR_DISP_NAME                       VARCHAR2(80)
45        ,ATTR_DISP_VALUE                      VARCHAR2(1000)
46        ,ATTR_UNIT_OF_MEASURE                 VARCHAR2(3)
47        ,DATABASE_COLUMN                      VARCHAR2(30)
48        --To pass the internal Value along with the display value
49        ,ATTR_VALUE_STR                      VARCHAR(1000)
50        ,ATTR_VALUE_NUM                      NUMBER
51        ,ATTR_VALUE_DATE                     DATE
52        ,DATA_TYPE_CODE                      VARCHAR2(8)
53 
54 
55     );
56 
57     TYPE LOCAL_AUGMENTED_DATA_TABLE IS TABLE OF LOCAL_USER_ATTR_DATA_REC
58       INDEX BY BINARY_INTEGER;
59 
60     TYPE LOCAL_HIERARCHY_REC IS RECORD
61     (
62         ATTR_GROUP_TYPE    VARCHAR2(40)
63       , IS_ROOT_NODE       VARCHAR2(1)
64       , IS_LEAF_NODE       VARCHAR2(1)
65     );
66 
67     TYPE LOCAL_HIERARCHY_REC_TABLE IS TABLE OF LOCAL_HIERARCHY_REC
68       INDEX BY BINARY_INTEGER;
69 
70                    ------------------------------
71                    -- Private Global Variables --
72                    ------------------------------
73 
74     G_PKG_NAME           CONSTANT   VARCHAR2(30) := 'EGO_USER_ATTRS_DATA_PVT';
75     G_CURRENT_USER_PRIVILEGES       EGO_VARCHAR_TBL_TYPE;
76 
77     G_BULK_PROCESSING_FLAG          BOOLEAN := FALSE;
78     G_DEFAULT_ON_INSERT_FLAG        BOOLEAN := FALSE;
79     G_NEED_TO_RESET_AG_CACHE        BOOLEAN := TRUE;
80 
81     G_OBJECT_NAME_TO_ID_CACHE       LOCAL_VARCHAR_TABLE;
82     G_ASSOCIATION_DATA_LEVEL_CACHE  LOCAL_BIG_VARCHAR_TABLE;
83 
84     G_DEBUG_OUTPUT_LEVEL            NUMBER := 0;
85     G_ADD_ERRORS_TO_FND_STACK       VARCHAR2(1) := 'N';
86     G_USER_ROW_IDENTIFIER           NUMBER := 0;
87 
88     G_B_TABLE_DML                   VARCHAR2(32767);
89     G_TL_TABLE_DML                  VARCHAR2(32767);
90 
91     G_BIND_INDEX                    NUMBER := 0;
92     G_BIND_DATATYPE_TBL             VARCHAR2_TBL_TYPE;
93     G_BIND_TEXT_TBL                 VARCHAR2_TBL_TYPE;
94     G_BIND_DATE_TBL                 DATE_TBL_TYPE;
95     G_BIND_NUMBER_TBL               NUMBER_TBL_TYPE;
96     G_BIND_IDENTIFIER_TBL           VARCHAR2_TBL_TYPE;
97     G_B_BIND_IDENTIFIER_TBL         VARCHAR2_TBL_TYPE;
98     G_TL_BIND_IDENTIFIER_TBL        VARCHAR2_TBL_TYPE;
99 
100     G_B_BIND_INDEX                  NUMBER := 0;
101     G_B_BIND_DATATYPE_TBL           VARCHAR2_TBL_TYPE;
102     G_B_BIND_TEXT_TBL               VARCHAR2_TBL_TYPE;
103     G_B_BIND_DATE_TBL               DATE_TBL_TYPE;
104     G_B_BIND_NUMBER_TBL             NUMBER_TBL_TYPE;
105 
106     G_TL_BIND_INDEX                 NUMBER := 0;
107     G_TL_BIND_DATATYPE_TBL          VARCHAR2_TBL_TYPE;
108     G_TL_BIND_TEXT_TBL              VARCHAR2_TBL_TYPE;
109     G_TL_BIND_DATE_TBL              DATE_TBL_TYPE;
110     G_TL_BIND_NUMBER_TBL            NUMBER_TBL_TYPE;
111 
112     G_DATA_LEVEL_NAME               VARCHAR2(30);
113     G_DATA_LEVEL_ID                 NUMBER;
114     -----------------------------------------------------
115     -- This is a private additional mode for use in    --
116     -- calls to Process_Row from Implement_Change_Line --
117     -----------------------------------------------------
118     G_IMPLEMENT_CREATE_MODE  CONSTANT VARCHAR2(10) := 'IMP_CREATE';
119 
120     G_HIERARCHY_CACHE                 LOCAL_HIERARCHY_REC_TABLE;
121     --in GTIN while creating a row 'SYNC' is passed which changes to 'UPDATE' or 'CREATE'
122     G_SYNC_TO_UPDATE                  VARCHAR2(1) := 'N';
123 
124     G_RET_STS_SUCCESS       VARCHAR2(1) := 'S';
125     G_RET_STS_ERROR         VARCHAR2(1) := 'E';
126     G_RET_STS_UNEXP_ERROR   VARCHAR2(1) := 'U';
127 
128 -- for development user to enable and disable debug
129 G_ENABLE_DEBUG BOOLEAN := FALSE;
130                  ---------------------------------
131                  -- Private Debugging Procedure --
132                  ---------------------------------
133 
134 ----------------------------------------------------------------------
135 /*
136  * The following procedure is for debugging purposes.  Its functionality is
137  * controlled by the global variable G_DEBUG_OUTPUT_LEVEL, whose values are:
138  *
139  * 3: LONG debug messages
140  * 2: MEDIUM debug messages
141  * 1: SHORT debug messages
142  * 0: NO debug messages
143  *
144  * The procedure will only print messages at the specified level or lower.
145  * When logging messages, specify their debug level or let it default to 3.
146  *(You will also have to call "set serveroutput on" to see the output.)
147  */
148 
149 PROCEDURE Debug_Msg(
150         p_message                       IN   VARCHAR2
151        ,p_level_of_debug                IN   NUMBER       DEFAULT 3
152 )
153 IS
154 
155 PRAGMA AUTONOMOUS_TRANSACTION;
156 
157 BEGIN
158 -- IF G_ENABLE_DEBUG THEN
159 --    sri_debug('EGOPEFDB ' ||p_message);
160 -- END IF;
161  IF (LENGTH(p_message) > 200) THEN
162    Debug_Msg(SUBSTR(p_message, 1, 200), p_level_of_debug);
163    Debug_Msg(SUBSTR(p_message, 201), p_level_of_debug);
164  ELSIF (LENGTH(p_message) > 0) THEN
165    ERROR_HANDLER.Write_Debug('['||TO_CHAR(SYSDATE, EGO_USER_ATTRS_COMMON_PVT.G_DATE_FORMAT)||'] '||p_message);
166  END IF;
167 END Debug_Msg;
168 
169 ----------------------------------------------------------------------
170 
171 /*
172  * For debugging of SQL strings whose length exceeds the 2000 byte
173  * buffer limit on DBMS_OUTPUT.PUT_LINE.  This procedure handles
174  * strings of any length up to the VARCHAR2 PL/SQL limit of 32767
175  * bytes by making recursive calls as necessary.
176  * (Debug_Msg is defined at the end of this package body.)
177  */
178 
179 PROCEDURE Debug_SQL (
180         p_long_message                  IN   VARCHAR2
181        ,p_level_of_debug                IN   NUMBER := 3
182 )
183 IS
184 
185   BEGIN
186 NULL;
187 /***
188     IF (p_level_of_debug <= G_DEBUG_OUTPUT_LEVEL) THEN
189       IF (LENGTH(p_long_message) > 5000) THEN
190         Debug_SQL(SUBSTR(p_long_message, 1, 5000), p_level_of_debug);
191         Debug_SQL(SUBSTR(p_long_message, 5001), p_level_of_debug);
192       ELSE
193         Debug_Msg(SUBSTR(p_long_message, 1, 200), p_level_of_debug);
194         Debug_Msg(SUBSTR(p_long_message, 201, 200), p_level_of_debug);
195         Debug_Msg(SUBSTR(p_long_message, 401, 200), p_level_of_debug);
196         Debug_Msg(SUBSTR(p_long_message, 601, 200), p_level_of_debug);
197         Debug_Msg(SUBSTR(p_long_message, 801, 200), p_level_of_debug);
198         Debug_Msg(SUBSTR(p_long_message, 1001, 200), p_level_of_debug);
199         Debug_Msg(SUBSTR(p_long_message, 1201, 200), p_level_of_debug);
200         Debug_Msg(SUBSTR(p_long_message, 1401, 200), p_level_of_debug);
201         Debug_Msg(SUBSTR(p_long_message, 1601, 200), p_level_of_debug);
202         Debug_Msg(SUBSTR(p_long_message, 1801, 200), p_level_of_debug);
203         Debug_Msg(SUBSTR(p_long_message, 2001, 200), p_level_of_debug);
204         Debug_Msg(SUBSTR(p_long_message, 2201, 200), p_level_of_debug);
205         Debug_Msg(SUBSTR(p_long_message, 2401, 200), p_level_of_debug);
206         Debug_Msg(SUBSTR(p_long_message, 2601, 200), p_level_of_debug);
207         Debug_Msg(SUBSTR(p_long_message, 2801, 200), p_level_of_debug);
208         Debug_Msg(SUBSTR(p_long_message, 3001, 200), p_level_of_debug);
209         Debug_Msg(SUBSTR(p_long_message, 3201, 200), p_level_of_debug);
210         Debug_Msg(SUBSTR(p_long_message, 3401, 200), p_level_of_debug);
211         Debug_Msg(SUBSTR(p_long_message, 3601, 200), p_level_of_debug);
212         Debug_Msg(SUBSTR(p_long_message, 3801, 200), p_level_of_debug);
213         Debug_Msg(SUBSTR(p_long_message, 4001, 200), p_level_of_debug);
214         Debug_Msg(SUBSTR(p_long_message, 4201, 200), p_level_of_debug);
215         Debug_Msg(SUBSTR(p_long_message, 4401, 200), p_level_of_debug);
216         Debug_Msg(SUBSTR(p_long_message, 4601, 200), p_level_of_debug);
217         Debug_Msg(SUBSTR(p_long_message, 4801, 200), p_level_of_debug);
218       END IF;
219     END IF;
220 ***/
221 END Debug_SQL;
222 
223 ----------------------------------------------------------------------
224 
225 
226 
227            ---------------------------------------------
228            -- Private Helper Procedures and Functions --
229            ---------------------------------------------
230 
231 ----------------------------------------------------------------------
232 --
233 -- Private
234 --
235 ----------------------------------
236 -- Covert data level name to Id --
237 ----------------------------------
238 FUNCTION Get_Data_Level_Id ( p_application_id    IN VARCHAR2
239                             ,p_attr_group_type   IN VARCHAR2
240                             ,p_data_level_name   IN VARCHAR2
241 )
242 RETURN NUMBER
243 IS
244    l_data_level_id   NUMBER;
245 BEGIN
246 
247    IF(p_data_level_name IS NULL) THEN
248      RETURN NULL;
249    END IF;
250 
251    IF(p_data_level_name = G_DATA_LEVEL_NAME) THEN
252      RETURN G_DATA_LEVEL_ID;
253    END IF;
254 
255    SELECT DATA_LEVEL_ID
256      INTO l_data_level_id
257      FROM EGO_DATA_LEVEL_B
258     WHERE APPLICATION_ID = p_application_id
259       AND ATTR_GROUP_TYPE = p_attr_group_type
260       AND DATA_LEVEL_NAME = p_data_level_name;
261 
262    IF(l_data_level_id IS NOT NULL) THEN
263      G_DATA_LEVEL_ID := l_data_level_id;
264      G_DATA_LEVEL_NAME := p_data_level_name;
265    END IF;
266 
267    RETURN l_data_level_id;
268 EXCEPTION
269    WHEN OTHERS THEN
270    Debug_Msg('Failed Get_Data_Level_Id-'||SQLERRM,0);
271    RAISE FND_API.G_EXC_ERROR;
272 END Get_Data_Level_Id;
273 ---------------------------------------------------------------------
274 
275 --
276 -- Private
277 --
278 --------------------------------
279 -- Is name value pairs valid  --
280 --------------------------------
281 PROCEDURE Is_Name_Value_Pairs_Valid
282    ( p_attr_group_id               IN NUMBER
283     ,p_data_level_name             IN VARCHAR2
284     ,p_class_code_hierarchy        IN VARCHAR2
285     ,p_data_level_name_value_pairs IN EGO_COL_NAME_VALUE_PAIR_ARRAY
286     ,x_data_level_id               OUT NOCOPY NUMBER
287     ,x_name_value_pair_valid       OUT NOCOPY VARCHAR2
288    ) IS
289 
290   l_api_name               VARCHAR2(30) := 'Is_Name_Value_Pairs_Valid';
291   l_dynamic_sql            VARCHAR2(5000);
292   l_name_value_pair_valid  BOOLEAN := FALSE;
293   l_dl_metadata_obj        EGO_DATA_LEVEL_METADATA_OBJ;
294 
295 BEGIN
296   Debug_Msg(l_api_name || '  cannot find an unique data level using  ag_ID, DATA_LEVEL, CLASS_CODE '||
297              p_attr_group_id ||', '||p_data_level_name||', '||p_class_code_hierarchy,1);
298   --
299   -- if the passed in pk values satisfy the data level, call perform_dml_on_temlate_row
300   -- old code will return only one record
301   -- new code will have p_data_level and must return only one record
302   --
303   BEGIN
304     l_dynamic_sql := 'SELECT DISTINCT(assoc.data_level_id) ' ||
305                       ' FROM ego_data_level_b dl, ego_obj_ag_assocs_b assoc, ego_fnd_dsc_flx_ctx_ext ag '||
306                      ' WHERE ag.attr_group_id = '||p_attr_group_id ||
307                        ' AND dl.attr_group_type = ag.descriptive_flexfield_name '||
308                        ' AND dl.application_id = ag.application_id ';
309     IF p_data_level_name IS NOT NULL THEN
310       l_dynamic_sql := l_dynamic_sql ||
311                        ' AND dl.data_level_name = '''||p_data_level_name||'''';
312     END IF;
313    l_dynamic_sql := l_dynamic_sql ||
314                        ' AND dl.data_level_id = assoc.data_level_id ' ||
315                        ' AND assoc.attr_group_id = ag.attr_group_id '||
316                        ' AND assoc.classification_code IN ('||p_class_code_hierarchy ||')';
317     Debug_Msg(l_api_name || '   complete query '|| l_dynamic_sql,1);
318     EXECUTE IMMEDIATE l_dynamic_sql
319     INTO x_data_level_id;
320   EXCEPTION
321     WHEN OTHERS THEN
322      Debug_Msg(l_api_name || '   EXCEPTION '||SQLERRM,1);
323      x_data_level_id := NULL;
324      x_name_value_pair_valid := FND_API.G_FALSE;
325   END;
326   l_name_value_pair_valid := FALSE;
327   IF x_data_level_id IS NOT NULL THEN
328     -- if the pk's passed satisfy this data_level, call Perform_DML_On_Template_Row
329     Debug_Msg(l_api_name || '  we have valid data_level_id as  '|| x_data_level_id,1);
330     l_dl_metadata_obj := EGO_USER_ATTRS_COMMON_PVT.Get_Data_Level_Metadata(x_data_level_id);
331     IF l_dl_metadata_obj IS NULL THEN
332       Debug_Msg(l_api_name || '  in invalid as we cannot have dl metadata object '|| x_data_level_id,1);
333       l_name_value_pair_valid := FALSE;
334     ELSE
335       IF (p_data_level_name_value_pairs IS NULL OR p_data_level_name_value_pairs.COUNT = 0) THEN
336         Debug_Msg(l_api_name || '  101 ',1);
337         IF l_dl_metadata_obj.pk_column_name1 IS NULL AND
338            l_dl_metadata_obj.pk_column_name2 IS NULL AND
339            l_dl_metadata_obj.pk_column_name3 IS NULL AND
340            l_dl_metadata_obj.pk_column_name4 IS NULL AND
341            l_dl_metadata_obj.pk_column_name5 IS NULL THEN
342         Debug_Msg(l_api_name || '  102 ',1);
343           l_name_value_pair_valid := TRUE;
344         END IF;
345       ELSE
346         FOR i IN p_data_level_name_value_pairs.FIRST .. p_data_level_name_value_pairs.LAST LOOP
347         Debug_Msg(l_api_name || '  103 ',1);
348           IF (p_data_level_name_value_pairs(i).name IS NOT NULL
349               AND
350               (
351                 (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)
352                 OR
353                 (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)
354                 OR
355                 (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)
356                 OR
357                 (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)
358                 OR
359                 (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)
360               )
361              ) THEN
362         Debug_Msg(l_api_name || '  104 ',1);
363             l_name_value_pair_valid := TRUE;
364           ELSE
365         Debug_Msg(l_api_name || '  105 ',1);
366             l_name_value_pair_valid := FALSE;
367             EXIT; -- exit the loop
368           END IF;
369         END LOOP;
370       END IF;
371     END IF;
372   END IF;
373 
374         Debug_Msg(l_api_name || '  106 ',1);
375   IF l_name_value_pair_valid THEN
376         Debug_Msg(l_api_name || '  107 ',1);
377     x_name_value_pair_valid := FND_API.G_TRUE;
378   ELSE
379         Debug_Msg(l_api_name || '  108 ',1);
380     x_name_value_pair_valid := FND_API.G_FALSE;
381   END IF;
382 
383 END Is_Name_Value_Pairs_Valid;
384 
385 --
386 -- Private
387 -- To Check whether the attribute is null or not
388 --
389 FUNCTION All_Attr_Values_Are_Null (
390         p_attr_name_value_pairs    IN   EGO_USER_ATTR_DATA_TABLE
391 )
392 RETURN BOOLEAN
393 IS
394 
395     l_attr_count      NUMBER;
396     l_all_are_null    BOOLEAN := TRUE;
397 
398   BEGIN
399 
400     Debug_Msg('In All_Attr_Values_Are_Null, starting', 2);
401 
402     IF (p_attr_name_value_pairs IS NOT NULL AND p_attr_name_value_pairs.COUNT > 0) THEN
403 
404       l_attr_count := p_attr_name_value_pairs.FIRST;
405 
406       WHILE (l_attr_count <= p_attr_name_value_pairs.LAST)
407       LOOP
408         EXIT WHEN (NOT l_all_are_null);
409 
410           IF (p_attr_name_value_pairs(l_attr_count).ATTR_VALUE_STR IS NOT NULL OR
411               p_attr_name_value_pairs(l_attr_count).ATTR_VALUE_NUM IS NOT NULL OR
412               p_attr_name_value_pairs(l_attr_count).ATTR_VALUE_DATE IS NOT NULL OR
413               p_attr_name_value_pairs(l_attr_count).ATTR_DISP_VALUE IS NOT NULL) THEN
414             l_all_are_null := FALSE;
415           END IF;
416 
417         l_attr_count := p_attr_name_value_pairs.NEXT(l_attr_count);
418       END LOOP;
419     END IF;
420 
421     Debug_Msg('In All_Attr_Values_Are_Null, done', 2);
422 
423     RETURN l_all_are_null;
424 
425 END All_Attr_Values_Are_Null;
426 
427 ----------------------------------------------------------------------
428 
429 --
430 -- Private
431 --
432 FUNCTION Get_Hierarchy_For_AG_Type (
433         p_ag_type                       IN   VARCHAR2
434        ,p_pk_column_name_value_pairs    IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
435 )
436 RETURN LOCAL_HIERARCHY_REC
437 IS
438 
439     l_hierarchy_cache_index NUMBER;
440     l_hierarchy_row_index   NUMBER;
441     l_dynamic_sql           VARCHAR2(200);
442     l_hierarchy_query       VARCHAR2(4000);
443     l_pk_column_index       NUMBER;
444     l_pk_value1             VARCHAR2(150);
445     l_pk_value2             VARCHAR2(150);
446     l_pk_value3             VARCHAR2(150);
447     l_pk_value4             VARCHAR2(150);
448     l_pk_value5             VARCHAR2(150);
449 
450     TYPE LOCAL_RESULT_PAIR IS RECORD
451     (
452         IS_ROOT_NODE        VARCHAR2(1)
453       , IS_LEAF_NODE        VARCHAR2(1)
454     );
455 
456     l_result                LOCAL_RESULT_PAIR;
457     l_return_value          LOCAL_HIERARCHY_REC;
458 
459     --Variables for Dynamic Cursor execution
460     TYPE cur_typ IS REF CURSOR;
461 
462     c_cursor              cur_typ;
463     l_hier_res_found      BOOLEAN := FALSE;
464 
465   BEGIN
466 
467     Debug_Msg('In Get_Hierarchy_From_AG_Type, starting for p_ag_type '||p_ag_type, 2);
468 
469     IF (G_HIERARCHY_CACHE.FIRST IS NOT NULL) THEN
470 
471       l_hierarchy_cache_index := G_HIERARCHY_CACHE.FIRST;
472       WHILE (l_hierarchy_cache_index <= G_HIERARCHY_CACHE.LAST)
473       LOOP
474         EXIT WHEN (l_hierarchy_row_index IS NOT NULL);
475         IF (G_HIERARCHY_CACHE(l_hierarchy_cache_index).ATTR_GROUP_TYPE = p_ag_type) THEN
476           l_hierarchy_row_index := l_hierarchy_cache_index;
477         END IF;
478         l_hierarchy_cache_index := G_HIERARCHY_CACHE.NEXT(l_hierarchy_cache_index);
479       END LOOP;
480     ELSE
481        Debug_Msg(' G_HIERARCHY_CACHE IS NULL ');
482        l_hierarchy_cache_index := 1;
483     END IF;
484 
485     IF (l_hierarchy_row_index IS NULL) THEN
486 
487       -- get hierarchy query for this object and run it
488       l_dynamic_sql := 'SELECT HIERARCHY_NODE_QUERY FROM EGO_FND_DESC_FLEXS_EXT '||
489                        'WHERE DESCRIPTIVE_FLEXFIELD_NAME = :1';
490 
491       EXECUTE IMMEDIATE l_dynamic_sql INTO l_hierarchy_query USING p_ag_type;
492 
493       Debug_Msg('In Get_Hierarchy_From_AG_Type,  l_hierarchy_query = '||l_hierarchy_query);
494 
495       IF (l_hierarchy_query IS NOT NULL) THEN
496 
497         -- prepare the hierarchy query binds and run it
498         IF (p_pk_column_name_value_pairs IS NOT NULL AND p_pk_column_name_value_pairs.COUNT > 0) THEN
499 
500           l_pk_column_index := p_pk_column_name_value_pairs.FIRST;
501           WHILE (l_pk_column_index <= p_pk_column_name_value_pairs.LAST)
502           LOOP
503 
504             IF (p_pk_column_name_value_pairs(l_pk_column_index).VALUE IS NOT NULL AND
505                 LENGTH(p_pk_column_name_value_pairs(l_pk_column_index).VALUE) > 0) THEN
506 
507               IF (l_pk_column_index = p_pk_column_name_value_pairs.FIRST) THEN
508                 l_pk_value1 := p_pk_column_name_value_pairs(l_pk_column_index).VALUE;
509               ELSIF (l_pk_column_index = p_pk_column_name_value_pairs.FIRST+1) THEN
510                 l_pk_value2 := p_pk_column_name_value_pairs(l_pk_column_index).VALUE;
511               ELSIF (l_pk_column_index = p_pk_column_name_value_pairs.FIRST+2) THEN
512                 l_pk_value3 := p_pk_column_name_value_pairs(l_pk_column_index).VALUE;
513               ELSIF (l_pk_column_index = p_pk_column_name_value_pairs.FIRST+3) THEN
514                 l_pk_value4 := p_pk_column_name_value_pairs(l_pk_column_index).VALUE;
515               ELSIF (l_pk_column_index = p_pk_column_name_value_pairs.FIRST+4) THEN
516                 l_pk_value5 := p_pk_column_name_value_pairs(l_pk_column_index).VALUE;
517               END IF;
518 
519           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);
520 
521             END IF;
522 
523             l_pk_column_index := p_pk_column_name_value_pairs.NEXT(l_pk_column_index);
524           END LOOP;
525 
526         END IF;
527 
528         -- assuming that if pk_value3 is defined, pk_value1 and 2 are defined as well
529         IF (l_pk_value5 IS NOT NULL) THEN
530           OPEN c_cursor FOR l_hierarchy_query USING l_pk_value1, l_pk_value2, l_pk_value3, l_pk_value4, l_pk_value5;
531           FETCH c_cursor INTO l_result;
532           IF c_cursor%FOUND THEN
533             l_hier_res_found := TRUE;
534           END IF;
535           CLOSE c_cursor;
536 
537         ELSIF (l_pk_value4 IS NOT NULL) THEN
538           OPEN c_cursor FOR l_hierarchy_query USING l_pk_value1, l_pk_value2, l_pk_value3, l_pk_value4;
539           FETCH c_cursor INTO l_result;
540           IF c_cursor%FOUND THEN
541             l_hier_res_found := TRUE;
542           END IF;
543           CLOSE c_cursor;
544 
545         ELSIF (l_pk_value3 IS NOT NULL) THEN
546           OPEN c_cursor FOR l_hierarchy_query USING l_pk_value1, l_pk_value2, l_pk_value3;
547           FETCH c_cursor INTO l_result;
548           IF c_cursor%FOUND THEN
549             l_hier_res_found := TRUE;
550           END IF;
551           CLOSE c_cursor;
552 
553         ELSIF (l_pk_value2 IS NOT NULL) THEN
554 
555           OPEN c_cursor FOR l_hierarchy_query USING l_pk_value1, l_pk_value2;
556           FETCH c_cursor INTO l_result;
557           IF c_cursor%FOUND THEN
558             l_hier_res_found := TRUE;
559           END IF;
560           CLOSE c_cursor;
561 
562         ELSIF (l_pk_value1 IS NOT NULL) THEN
563           OPEN c_cursor FOR l_hierarchy_query USING l_pk_value1;
564           FETCH c_cursor INTO l_result;
565           IF c_cursor%FOUND THEN
566             l_hier_res_found := TRUE;
567           END IF;
568           CLOSE c_cursor;
569 
570         ELSE
571           OPEN c_cursor FOR l_hierarchy_query;
572           FETCH c_cursor INTO l_result;
573           IF c_cursor%FOUND THEN
574             l_hier_res_found := TRUE;
575           END IF;
576           CLOSE c_cursor;
577 
578         END IF;
579 
580         -- cache the results
581         IF l_hier_res_found THEN
582           l_return_value.IS_ROOT_NODE := l_result.IS_ROOT_NODE;
583           l_return_value.IS_LEAF_NODE := l_result.IS_LEAF_NODE;
584         ELSE
585           -- default values if query returned no results
586           l_return_value.IS_ROOT_NODE := 'N';
587           l_return_value.IS_LEAF_NODE := 'N';
588         END IF;
589 
590       ELSE
591        -- if no query was found, return default values
592         l_return_value.IS_ROOT_NODE := 'N';
593         l_return_value.IS_LEAF_NODE := 'N';
594       END IF;
595 
596       l_return_value.ATTR_GROUP_TYPE := p_ag_type;
597       Debug_Msg('In Get_Hierarchy_From_AG_Type, l_hierarchy_cache_index = '||To_Char(l_hierarchy_cache_index));
598       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);
599       IF(l_hierarchy_cache_index IS NULL) THEN
600         l_hierarchy_cache_index := G_HIERARCHY_CACHE.LAST + 1;
601       END IF;
602       G_HIERARCHY_CACHE(l_hierarchy_cache_index) := l_return_value;
603 
604     ELSE
605       l_return_value := G_HIERARCHY_CACHE(l_hierarchy_row_index);
606     END IF;
607 
608     RETURN l_return_value;
609 
610   EXCEPTION
611     WHEN NO_DATA_FOUND THEN
612       Debug_Msg('In Get_Hierarchy_From_AG_Type, EXCEPTION  NO_DATA_FOUND ');
613       RETURN NULL;
614 
615 END Get_Hierarchy_For_AG_Type;
616 
617 ----------------------------------------------------------------------
618 
619 --
620 -- Private
621 --  Get_Changed_Attributes - returns an attribute diff table that lists
622 --  the old and new attribute values for the given DML operation
623 --
624 PROCEDURE Get_Changed_Attributes (
625      p_dml_operation                IN  VARCHAR2
626     ,p_object_name                  IN  VARCHAR2
627     ,p_pk_column_name_value_pairs   IN  EGO_COL_NAME_VALUE_PAIR_ARRAY
628     ,p_attr_group_metadata_obj      IN  EGO_ATTR_GROUP_METADATA_OBJ
629     ,p_ext_table_metadata_obj       IN  EGO_EXT_TABLE_METADATA_OBJ
630     ,p_data_level                   IN  VARCHAR2   DEFAULT NULL --R12C
631     ,p_data_level_name_value_pairs  IN  EGO_COL_NAME_VALUE_PAIR_ARRAY
632     ,p_attr_name_value_pairs        IN  EGO_USER_ATTR_DATA_TABLE
633     ,p_extension_id                 IN  NUMBER     DEFAULT NULL
634     ,p_entity_id                    IN  NUMBER     DEFAULT NULL
635     ,p_entity_index                 IN  NUMBER     DEFAULT NULL
636     ,p_entity_code                  IN  VARCHAR2   DEFAULT NULL
637     ,px_attr_diffs                  IN  OUT NOCOPY EGO_USER_ATTR_DIFF_TABLE
638                                  )
639   IS
640 
641     l_api_name                      VARCHAR2(30) := 'Get_Changed_Attributes';
642     l_attrs_index                   NUMBER;
643     l_dynamic_sql                   VARCHAR2(32767);
644 
645     l_data_level_string             VARCHAR2(1000);
646     l_ag_predicate_list             VARCHAR2(20000);
647     l_db_column_query_table         LOCAL_BIG_VARCHAR_TABLE;
648     l_curr_ag_request_obj           EGO_ATTR_GROUP_REQUEST_OBJ;
649     l_curr_attr_metadata_obj        EGO_ATTR_METADATA_OBJ;
650     l_curr_augmented_attr_rec       LOCAL_USER_ATTR_DATA_REC;
651     l_curr_aug_table_index          NUMBER;
652     l_augmented_data_table          LOCAL_AUGMENTED_DATA_TABLE;
653     l_table_of_high_ind_for_AG_ID   LOCAL_NUMBER_TABLE;
654     l_curr_db_column_name           VARCHAR2(30);
655     l_db_column_list                VARCHAR2(10000);
656     l_to_char_db_col_expression     VARCHAR2(90);
657     l_db_column_tables_index        NUMBER;
658     l_int_to_disp_val_string        VARCHAR2(32767);
659     l_db_column_name_table          LOCAL_VARCHAR_TABLE;
660     l_start_index                   NUMBER;
661     l_substring_length              NUMBER;
662     l_temp_db_query_string          VARCHAR2(32767);
663     l_pk_col_string                 VARCHAR2(1000);
664     l_cursor_id                     NUMBER;
665     l_extension_id                  NUMBER;
666     l_dummy                         NUMBER;
667 
668     l_attr_name_value_rec           EGO_USER_ATTR_DATA_OBJ;
669     l_retrieved_value               VARCHAR2(1000);
670     l_data_type_codes_table         LOCAL_VARCHAR_TABLE;
671     l_attr_diffs_last               NUMBER;
672     l_data_level_id                 NUMBER;
673     l_dl_col_mdata_array            EGO_COL_METADATA_ARRAY;
674 
675   BEGIN
676 
677     Debug_Msg(l_api_name||' starting', 1);
678 
679     IF (p_dml_operation = 'INSERT') THEN
680 
681       -----------------------------------------------------------------------
682       -- For the INSERT case, just record the new attribute values         --
683       -----------------------------------------------------------------------
684       Debug_Msg(l_api_name||' insert', 1);
685 
686       px_attr_diffs := EGO_USER_ATTR_DIFF_TABLE();
687       l_attrs_index := p_attr_name_value_pairs.FIRST;
688       WHILE (l_attrs_index <= p_attr_name_value_pairs.LAST)
689       LOOP
690 
691         l_attr_name_value_rec := p_attr_name_value_pairs(l_attrs_index);
692 
693         l_curr_attr_metadata_obj := EGO_USER_ATTRS_COMMON_PVT.Find_Metadata_For_Attr(
694                                       p_attr_group_metadata_obj.attr_metadata_table
695                                      ,l_attr_name_value_rec.ATTR_NAME
696                                     );
697 
698         px_attr_diffs.EXTEND();
699         px_attr_diffs(px_attr_diffs.LAST) :=
700           EGO_USER_ATTR_DIFF_OBJ(l_curr_attr_metadata_obj.ATTR_ID            --  attr_id
701                                 ,l_curr_attr_metadata_obj.ATTR_NAME          --  attr_name
702                                 ,null                                        --  old_attr_value_str
703                                 ,null                                        --  old_attr_value_num
704                                 ,null                                        --  old_attr_value_date
705                                 ,null                                        --  old_attr_uom
706                                 ,l_attr_name_value_rec.ATTR_VALUE_STR        --  new_attr_value_str
707                                 ,l_attr_name_value_rec.ATTR_VALUE_NUM        --  new_attr_value_num
708                                 ,l_attr_name_value_rec.ATTR_VALUE_DATE       --  new_attr_value_date
709                                 ,l_attr_name_value_rec.ATTR_UNIT_OF_MEASURE  --  new_attr_uom
710                                 ,l_curr_attr_metadata_obj.UNIQUE_KEY_FLAG    --  unique_key_flag
711                                 ,null                                        --  extension_id
712                                 );
713 
714         l_attrs_index := p_attr_name_value_pairs.NEXT(l_attrs_index);
715 
716         Debug_Msg(l_api_name||' attr('||to_char(l_attrs_index)||
717                   '):'||l_attr_name_value_rec.ATTR_NAME||
718                   ' str:'||l_attr_name_value_rec.ATTR_VALUE_STR||
719                   ' num:'||l_attr_name_value_rec.ATTR_VALUE_NUM||
720                   ' date:'||l_attr_name_value_rec.ATTR_VALUE_DATE||
721                   ' uom:'||l_attr_name_value_rec.ATTR_UNIT_OF_MEASURE);
722 
723       END LOOP;
724 
725     ELSIF (p_dml_operation = 'UPDATE' ) THEN
726 
727       -----------------------------------------------------------------------
728       -- For the UPDATE case, record the new attribute values, then query  --
729       -- for the old values, and pack both into the attr diffs table       --
730       -----------------------------------------------------------------------
731       Debug_Msg(l_api_name||' update', 1);
732 
733       -----------------------------------------------------------------------
734       -- For every Attribute in our table of Attribute names, we find its  --
735       -- metadata and build an augmented version of a Data record for it,  --
736       -- which we then add to a table for later use in correlating a given --
737       -- Database Column to the appropriate Attribute and then building an --
738       -- Attr Data object for that Attr and its value.                     --
739       -----------------------------------------------------------------------
740       px_attr_diffs := EGO_USER_ATTR_DIFF_TABLE();
741       l_attrs_index := p_attr_name_value_pairs.FIRST;
742       WHILE (l_attrs_index <= p_attr_name_value_pairs.LAST)
743       LOOP
744 
745         l_attr_name_value_rec := p_attr_name_value_pairs(l_attrs_index);
746         l_curr_attr_metadata_obj := EGO_USER_ATTRS_COMMON_PVT.Find_Metadata_For_Attr(
747                                       p_attr_group_metadata_obj.attr_metadata_table
748                                      ,l_attr_name_value_rec.ATTR_NAME
749                                     );
750         l_curr_augmented_attr_rec.ATTR_GROUP_ID := p_attr_group_metadata_obj.ATTR_GROUP_ID;
751         l_curr_augmented_attr_rec.APPLICATION_ID := p_attr_group_metadata_obj.APPLICATION_ID;
752         l_curr_augmented_attr_rec.ATTR_GROUP_TYPE := p_attr_group_metadata_obj.ATTR_GROUP_TYPE;
753         l_curr_augmented_attr_rec.ATTR_GROUP_NAME := p_attr_group_metadata_obj.ATTR_GROUP_NAME;
754         l_curr_augmented_attr_rec.ATTR_NAME := l_curr_attr_metadata_obj.ATTR_NAME;
755         l_curr_augmented_attr_rec.ATTR_DISP_NAME := l_curr_attr_metadata_obj.ATTR_DISP_NAME;
756         l_curr_augmented_attr_rec.DATABASE_COLUMN := l_curr_attr_metadata_obj.DATABASE_COLUMN;
757 
758         -----------------------------------------------------------------------
759         -- Store data type codes in a local table so we don't have to call   --
760         -- Find_Metadata_For_Attr again for each attribute                   --
761         -----------------------------------------------------------------------
762         l_data_type_codes_table(l_data_type_codes_table.COUNT+1) := l_curr_attr_metadata_obj.DATA_TYPE_CODE;
763 
764         Debug_Msg(l_api_name||' attr '||to_char(l_attrs_index)||':'||l_curr_attr_metadata_obj.ATTR_NAME, 1);
765 
766         -----------------------------------------------------------------------
767         -- For now, store the new values in the diff table. Later we'll get  --
768         -- the old values                                                    --
769         -----------------------------------------------------------------------
770         px_attr_diffs.EXTEND();
771         px_attr_diffs(px_attr_diffs.LAST) :=
772           EGO_USER_ATTR_DIFF_OBJ(l_curr_attr_metadata_obj.ATTR_ID           --  attr_id
773                                 ,l_curr_attr_metadata_obj.ATTR_NAME         --  attr_name
774                                 ,null                                       --  old_attr_value_str
775                                 ,null                                       --  old_attr_value_num
776                                 ,null                                       --  old_attr_value_date
777                                 ,null                                       --  old_attr_uom
778                                 ,l_attr_name_value_rec.ATTR_VALUE_STR       --  new_attr_value_str
779                                 ,l_attr_name_value_rec.ATTR_VALUE_NUM       --  new_attr_value_num
780                                 ,l_attr_name_value_rec.ATTR_VALUE_DATE      --  new_attr_value_date
781                                 ,l_attr_name_value_rec.ATTR_UNIT_OF_MEASURE --  new_attr_uom
782                                 ,l_curr_attr_metadata_obj.UNIQUE_KEY_FLAG   --  unique_key_flag
783                                 ,null                                       --  extension_id
784                                 );
785 
786         ----------------------------------------------------
787         -- Record the index at which we store this record --
788         ----------------------------------------------------
789         l_curr_aug_table_index := l_augmented_data_table.COUNT+1;
790         l_augmented_data_table(l_curr_aug_table_index) := l_curr_augmented_attr_rec;
791 
792         -----------------------------------------------------------------------------
793         -- If the Database Column for this Attribute is one that has not yet been  --
794         -- processed, put it into the l_db_column_name_table and put its name and  --
795         -- its l_db_column_name_table index into the l_db_column_list. If this has --
796         -- already been done for this column, get the index from l_db_column_list. --
797         -----------------------------------------------------------------------------
798         l_curr_db_column_name := l_curr_augmented_attr_rec.DATABASE_COLUMN;
799 
800         IF (l_db_column_list IS NULL OR
801             INSTR(l_db_column_list, l_curr_db_column_name||':') = 0) THEN
802 
803           l_db_column_tables_index := l_db_column_name_table.COUNT+1;
804           l_db_column_name_table(l_db_column_tables_index) := l_curr_db_column_name;
805           l_db_column_list := l_db_column_list || l_curr_db_column_name || ':'||l_db_column_tables_index||', ';
806 
807         ELSE
808 
809           l_start_index := INSTR(l_db_column_list, l_curr_db_column_name||':') + LENGTH(l_curr_db_column_name||':');
810           l_substring_length := INSTR(l_db_column_list, ',', l_start_index) - l_start_index;
811           l_db_column_tables_index := TO_NUMBER(SUBSTR(l_db_column_list, l_start_index, l_substring_length));
812 
813         END IF;
814 
815         l_to_char_db_col_expression := EGO_USER_ATTRS_COMMON_PVT.Create_DB_Col_Alias_If_Needed(l_curr_attr_metadata_obj);
816 
817         ----------------------------------------------------------------------
818         -- If this Attribute does not have a Value Set that distinguishes   --
819         -- between Internal and Display Values, we just make sure that a    --
820         -- query for this Database Column name (as determined by the index) --
821         -- is in the l_db_column_query_table (we don't want to overwrite a  --
822         -- possibly more complicated query with our simple formatted one,   --
823         -- which is why we only add it if one doesn't already exist).       --
824         ----------------------------------------------------------------------
825         IF (NOT l_db_column_query_table.EXISTS(l_db_column_tables_index)) THEN
826           l_db_column_query_table(l_db_column_tables_index) := l_to_char_db_col_expression;
827         END IF;
828 
829         ------------------------------------------------------------
830         -- We now have the formatted database column name and the --
831         -- Int -> Disp value conversion query; now we see whether --
832         -- there is yet a DECODE query for this database column,  --
833         -- and either create one or add to the existing one       --
834         ------------------------------------------------------------
835         IF ((NOT l_db_column_query_table.EXISTS(l_db_column_tables_index)) OR
836             l_db_column_query_table(l_db_column_tables_index) = l_to_char_db_col_expression) THEN
837 
838           IF (p_attr_group_metadata_obj.ATTR_GROUP_ID_FLAG = 'Y') THEN
839             l_db_column_query_table(l_db_column_tables_index) := '' ||
840             'DECODE(ATTR_GROUP_ID,'||l_curr_attr_metadata_obj.ATTR_GROUP_ID||',('||
841             l_int_to_disp_val_string||l_to_char_db_col_expression||'),'||
842             l_to_char_db_col_expression||') '||l_curr_db_column_name;
843           ELSE
844             l_db_column_query_table(l_db_column_tables_index) := '' ||
845               l_to_char_db_col_expression||' '||l_curr_db_column_name;
846           END IF;
847 
848         ELSE
849 
850           ---------------------------------------------------
851           -- Otherwise, we get the current DECODE query... --
852           ---------------------------------------------------
853           l_temp_db_query_string := l_db_column_query_table(l_db_column_tables_index);
854 
855           ---------------------------------------------
856           -- ...insert our new portion at index 22   --
857           -- (i.e., after 'DECODE(ATTR_GROUP_ID,'... --
858           ---------------------------------------------
859           l_temp_db_query_string := SUBSTR(l_temp_db_query_string, 1, 21) ||
860                                       l_curr_attr_metadata_obj.ATTR_GROUP_ID||',('||
861                                       l_int_to_disp_val_string||
862                                       l_to_char_db_col_expression||'),'||
863                                       SUBSTR(l_temp_db_query_string, 22);
864 
865           -------------------------------------------------------------------------
866           -- ...and put the updated query back into the l_db_column_query_table. --
867           -------------------------------------------------------------------------
868           l_db_column_query_table(l_db_column_tables_index) := l_temp_db_query_string;
869 
870         END IF;
871 
872         l_attrs_index := p_attr_name_value_pairs.NEXT(l_attrs_index);
873       END LOOP;
874 
875       --------------------------------------------------------------------------------
876       -- Now we build a query list with all of our Database Column query components --
877       --------------------------------------------------------------------------------
878       l_db_column_list := '';
879       FOR i IN l_db_column_query_table.FIRST .. l_db_column_query_table.LAST
880       LOOP
881 
882         l_db_column_list := l_db_column_list || l_db_column_query_table(i) || ',';
883 
884       END LOOP;
885 
886       -----------------------------------------------------
887       -- Trim the trailing bits from the DB Column lists --
888       -----------------------------------------------------
889       l_db_column_list := RTRIM(l_db_column_list, ',');
890 
891       Debug_Msg(l_api_name||' pk cols '||l_pk_col_string);
892 
893       Init();
894       FND_DSQL.Add_Text('SELECT EXTENSION_ID, ' ||l_db_column_list||
895                          ' FROM ' ||NVL(p_attr_group_metadata_obj.EXT_TABLE_VL_NAME
896                                        ,p_attr_group_metadata_obj.EXT_TABLE_B_NAME)||
897                         ' WHERE ');
898 
899       ----------------------------------------------------------------------
900       -- We know this call will succeed because we checked the PK columns --
901       -- against the metadata in Perform_Preliminary_Checks, above        --
902       ----------------------------------------------------------------------
903       l_pk_col_string := EGO_USER_ATTRS_COMMON_PVT.Get_List_For_Table_Cols(
904                            p_ext_table_metadata_obj.pk_column_metadata
905                           ,p_pk_column_name_value_pairs
906                           ,'EQUALS'
907                           ,TRUE);
908 
909       -----------------------------------------------------------------------
910       -- If extension ID info is available, select on it.                  --
911       -----------------------------------------------------------------------
912       IF (p_extension_id IS NOT NULL) THEN
913         FND_DSQL.Add_Text(' AND EXTENSION_ID = ');
914         Add_Bind(p_value => p_extension_id);
915       END IF;
916 
917       ----------------------------------------------------------------------------
918       --We add the data_level_id to the where clause, it would be passed in
919       --by the implementing team if the R12C changes for enhanced data level
920       --support have been taken up.
921       ----------------------------------------------------------------------------
922       IF(p_data_level IS NOT NULL
923          AND
924          FND_API.TO_BOOLEAN(
925               EGO_USER_ATTRS_COMMON_PVT.has_column_in_table(p_table_name  => p_attr_group_metadata_obj.ext_table_vl_name
926                                                            ,p_column_name => 'DATA_LEVEL_ID'
927                                                            )
928                            )
929          ) THEN
930 
931         l_data_level_id := Get_Data_Level_Id( p_attr_group_metadata_obj.APPLICATION_ID
932                                              ,p_attr_group_metadata_obj.ATTR_GROUP_TYPE
933                                              ,p_data_level);
934 
935         FND_DSQL.Add_Text(' AND DATA_LEVEL_ID = ');
936         Add_Bind (p_bind_identifier => 'DATA_LEVEL_ID'
937                  ,p_value           =>  l_data_level_id);
938 
939       END IF;
940 
941 --AMAY TODO: just use EXT ID here and nothing else!!!
942 -- check with dylan: can we assume we have ext id at perform dml on row pvt
943       Debug_Msg(l_api_name||' dyn_sql '||l_dynamic_sql);
944 
945       IF (p_attr_group_metadata_obj.ATTR_GROUP_ID_FLAG = 'Y') THEN
946 
947         ------------------------------------------------
948         -- Build a predicate for each Attribute Group --
949         -- and concatenate it into a master predicate --
950         ------------------------------------------------
951         FND_DSQL.Add_Text(' AND (ATTR_GROUP_ID = ');
952         Add_Bind(p_value => p_attr_group_metadata_obj.ATTR_GROUP_ID);
953 
954         ---------------------------------------------------------------
955         -- Make a string to use in the query; it will be of the form --
956         -- 'DATA_LEVEL_1 = <value> AND ... DATA_LEVEL_N = <value>';  --
957         -- we know this call will succeed because we built the array --
958         -- of data level name/value pairs ourselves using metadata.  --
959         ---------------------------------------------------------------
960 
961         l_dl_col_mdata_array:= EGO_USER_ATTRS_COMMON_PVT.Get_Data_Level_Col_Array(p_attr_group_metadata_obj.APPLICATION_ID,
962                                                                                   p_attr_group_metadata_obj.ATTR_GROUP_TYPE);
963 
964         l_data_level_string := EGO_USER_ATTRS_COMMON_PVT.Get_List_For_Table_Cols(
965                                  l_dl_col_mdata_array
966                                 ,p_data_level_name_value_pairs
967                                 ,'EQUALS'
968                                 ,TRUE
969                                 ,' AND '
970                                );
971         FND_DSQL.Add_Text(')');
972 
973       END IF;
974 
975       Debug_SQL(l_dynamic_sql);
976 
977       ----------------------------------
978       -- Open a cursor for processing --
979       ----------------------------------
980       l_cursor_id := DBMS_SQL.OPEN_CURSOR;
981       FND_DSQL.Set_Cursor(l_cursor_id);
982 
983       -------------------------------------
984       -- Parse our dynamic SQL statement --
985       -------------------------------------
986       DBMS_SQL.PARSE(l_cursor_id, FND_DSQL.Get_Text(), DBMS_SQL.NATIVE);
987 
988       ------------------------
989       -- Bind our variables --
990       ------------------------
991       FND_DSQL.Do_Binds();
992 
993       --------------------------------------------------------------------------
994       -- Register the data types of the columns we are selecting in our query --
995       -- (in the VARCHAR2 case, that includes stating the maximum size that a --
996       -- value in the column might be; to be safe we will use 1000 bytes).    --
997       -- First we register the EXTENSION_ID and ATTR_GROUP_ID...              --
998       --------------------------------------------------------------------------
999       DBMS_SQL.Define_Column(l_cursor_id, 1, l_extension_id);
1000 
1001       -----------------------------------
1002       -- ...then the Database Columns. --
1003       -----------------------------------
1004       FOR i IN l_db_column_name_table.FIRST .. l_db_column_name_table.LAST
1005       LOOP
1006 
1007         --------------------------------------------------------------------
1008         -- We cast everything to string for assignment to ATTR_DISP_VALUE --
1009         --------------------------------------------------------------------
1010         DBMS_SQL.Define_Column(l_cursor_id, i+1, l_retrieved_value, 1000);
1011 
1012       END LOOP;
1013 
1014       -------------------------------
1015       -- Execute our dynamic query --
1016       -------------------------------
1017       l_dummy := DBMS_SQL.Execute(l_cursor_id);
1018 
1019       Debug_Msg(l_api_name||' executed the query', 3);
1020 
1021       -----------------------------------------------------------------------
1022       -- Loop through the result set rows and decode the results into the  --
1023       -- appropriate fields of the attr diff object based on data type     --
1024       -----------------------------------------------------------------------
1025 
1026       l_attr_diffs_last := px_attr_diffs.LAST;
1027       WHILE (DBMS_SQL.FETCH_ROWS(l_cursor_id) > 0)
1028       LOOP
1029 
1030         FOR i IN l_db_column_name_table.FIRST .. l_db_column_name_table.LAST
1031         LOOP
1032 
1033           ----------------------------------------------------------------------
1034           -- Update the correct record in attr diffs.  Use l_attr_diffs_last  --
1035           -- so that insertions do not affect loop iteration                  --
1036           ----------------------------------------------------------------------
1037           FOR j IN px_attr_diffs.FIRST .. l_attr_diffs_last
1038           LOOP
1039 
1040             IF (l_db_column_name_table(i) = l_augmented_data_table(j).DATABASE_COLUMN) THEN
1041 
1042               DBMS_SQL.COLUMN_VALUE(l_cursor_id, 1, l_extension_id);
1043 
1044               ------------------------------------------------
1045               -- We use i+1 because of the offset caused by --
1046               -- requesting EXTENSION_ID                    --
1047               ------------------------------------------------
1048               DBMS_SQL.COLUMN_VALUE(l_cursor_id, i+1, l_retrieved_value);
1049 
1050               Debug_Msg(l_api_name||' db col: '||l_db_column_name_table(i)||' val: '||l_retrieved_value, 1);
1051 
1052               IF (px_attr_diffs(j).OLD_ATTR_VALUE_NUM IS NULL AND
1053                   px_attr_diffs(j).OLD_ATTR_VALUE_DATE IS NULL AND
1054                   px_attr_diffs(j).OLD_ATTR_VALUE_STR IS NULL) THEN
1055 
1056                 ---------------------------------------------------
1057                 -- No entry exists in diff table for this column --
1058                 ---------------------------------------------------
1059                 px_attr_diffs(j).EXTENSION_ID := l_extension_id;
1060 
1061                 IF (l_data_type_codes_table(j) = 'N') THEN
1062                   px_attr_diffs(j).OLD_ATTR_VALUE_NUM :=
1063                     TO_NUMBER(l_retrieved_value);
1064                 ELSIF (l_data_type_codes_table(j) = 'X') THEN
1065                   px_attr_diffs(j).OLD_ATTR_VALUE_DATE :=
1066                     TRUNC(TO_DATE(l_retrieved_value, EGO_USER_ATTRS_COMMON_PVT.G_DATE_FORMAT));
1067                 ELSIF (l_data_type_codes_table(j) = 'Y') THEN
1068                   px_attr_diffs(j).OLD_ATTR_VALUE_DATE :=
1069                     TO_DATE(l_retrieved_value, EGO_USER_ATTRS_COMMON_PVT.G_DATE_FORMAT);
1070                 ELSE
1071                   px_attr_diffs(j).OLD_ATTR_VALUE_STR := l_retrieved_value;
1072                 END IF;
1073 
1074               ELSE
1075 
1076                 ---------------------------------------------------
1077                 -- An entry already exists in diff table for     --
1078                 -- this column, so add a new record at the end   --
1079                 ---------------------------------------------------
1080                 px_attr_diffs.EXTEND();
1081                 px_attr_diffs(px_attr_diffs.LAST) :=
1082                        EGO_USER_ATTR_DIFF_OBJ(px_attr_diffs(j).ATTR_ID         --  attr_id
1083                                              ,px_attr_diffs(j).ATTR_NAME       --  attr_name
1084                                              ,null                             --  old_attr_value_str
1085                                              ,null                             --  old_attr_value_num
1086                                              ,null                             --  old_attr_value_date
1087                                              ,null                             --  old_attr_uom
1088                                              ,null                             --  new_attr_value_str
1089                                              ,null                             --  new_attr_value_num
1090                                              ,null                             --  new_attr_value_date
1091                                              ,null                             --  new_attr_uom
1092                                              ,px_attr_diffs(j).UNIQUE_KEY_FLAG --  unique_key_flag
1093                                              ,l_extension_id                   --  extension_id
1094                                              );
1095                 IF (l_data_type_codes_table(j) = 'N') THEN
1096                   px_attr_diffs(px_attr_diffs.LAST).OLD_ATTR_VALUE_NUM :=
1097                     TO_NUMBER(l_retrieved_value);
1098                 ELSIF (l_data_type_codes_table(j) = 'X') THEN
1099                   px_attr_diffs(px_attr_diffs.LAST).OLD_ATTR_VALUE_DATE :=
1100                     TRUNC(TO_DATE(l_retrieved_value, EGO_USER_ATTRS_COMMON_PVT.G_DATE_FORMAT));
1101                 ELSIF (l_data_type_codes_table(j) = 'Y') THEN
1102                   px_attr_diffs(px_attr_diffs.LAST).OLD_ATTR_VALUE_DATE :=
1103                     TO_DATE(l_retrieved_value, EGO_USER_ATTRS_COMMON_PVT.G_DATE_FORMAT);
1104                 ELSE
1105                   px_attr_diffs(px_attr_diffs.LAST).OLD_ATTR_VALUE_STR := l_retrieved_value;
1106                 END IF;
1107 
1108               END IF;
1109 
1110             END IF;
1111           END LOOP;
1112         END LOOP;
1113       END LOOP;
1114 
1115       -----------------------------------------
1116       -- Close the cursor when we're through --
1117       -----------------------------------------
1118       IF (l_cursor_id IS NOT NULL) THEN
1119         DBMS_SQL.Close_Cursor(l_cursor_id);
1120         l_cursor_id := NULL;
1121       END IF;
1122     -- Start ssingal -For Ucc Net Attribute Propagation
1123     ELSIF (p_dml_operation = 'DELETE' ) THEN
1124       Debug_Msg(l_api_name||' Transaction Type is Delete ', 1);
1125 
1126       px_attr_diffs    :=      EGO_USER_ATTR_DIFF_TABLE();
1127       l_attrs_index    :=      p_attr_name_value_pairs.FIRST;
1128 
1129       WHILE (l_attrs_index <= p_attr_name_value_pairs.LAST)
1130       LOOP
1131         l_attr_name_value_rec :=  p_attr_name_value_pairs(l_attrs_index);
1132         l_curr_attr_metadata_obj :=   EGO_USER_ATTRS_COMMON_PVT.Find_Metadata_For_Attr
1133                                       (
1134                                         p_attr_group_metadata_obj.attr_metadata_table,
1135                                         l_attr_name_value_rec.ATTR_NAME
1136                                       );
1137          px_attr_diffs.EXTEND();
1138          -- For Transaction Type Delete
1139          -- Pass the old Attribute Data
1140          -- in the Diff Object
1141          px_attr_diffs(px_attr_diffs.LAST) :=
1142                        EGO_USER_ATTR_DIFF_OBJ(l_curr_attr_metadata_obj.ATTR_ID            --  attr_id
1143                                              ,l_curr_attr_metadata_obj.ATTR_NAME          --  attr_name
1144                                              ,l_attr_name_value_rec.ATTR_VALUE_STR        --  old_attr_value_str
1145                                              ,l_attr_name_value_rec.ATTR_VALUE_NUM        --  old_attr_value_num
1146                                              ,l_attr_name_value_rec.ATTR_VALUE_DATE       --  old_attr_value_date
1147                                              ,l_attr_name_value_rec.ATTR_UNIT_OF_MEASURE  --  old_attr_uom
1148                                              ,null                                        --  new_attr_value_str
1149                                              ,null                                        --  new_attr_value_num
1150                                              ,null                                        --  new_attr_value_date
1151                                              ,null                                        --  new_attr_uom
1152                                              ,l_curr_attr_metadata_obj.UNIQUE_KEY_FLAG    --  unique_key_flag
1153                                              ,null                                        --  extension_id
1154                                              );
1155         l_attrs_index         :=      p_attr_name_value_pairs.NEXT(l_attrs_index);
1156 
1157       END LOOP;
1158     END IF;
1159     -- End ssingal -For Ucc Net Attribute Propagation
1160 
1161     -----------------------------------------
1162     -- Display what's in the diff object   --
1163     -----------------------------------------
1164     FOR a IN px_attr_diffs.FIRST .. px_attr_diffs.LAST
1165     LOOP
1166 
1167       Debug_Msg(l_api_name||' diff '||a||':'||
1168                 px_attr_diffs(a).ATTR_ID||','||px_attr_diffs(a).OLD_ATTR_VALUE_STR||','||
1169                 px_attr_diffs(a).OLD_ATTR_VALUE_NUM||','||px_attr_diffs(a).OLD_ATTR_VALUE_DATE||','||
1170                 px_attr_diffs(a).OLD_ATTR_UOM||','||px_attr_diffs(a).NEW_ATTR_VALUE_STR||','||
1171                 px_attr_diffs(a).NEW_ATTR_VALUE_NUM||','||px_attr_diffs(a).NEW_ATTR_VALUE_DATE||','||
1172                 px_attr_diffs(a).NEW_ATTR_UOM||','||px_attr_diffs(a).UNIQUE_KEY_FLAG||','||
1173                 px_attr_diffs(a).EXTENSION_ID);
1174 
1175     END LOOP;
1176 
1177     Debug_Msg(l_api_name||' done', 1);
1178 
1179   EXCEPTION
1180   WHEN OTHERS THEN
1181     Debug_Msg(l_api_name||' API failed: '||SQLERRM, 1);
1182     RETURN;
1183 
1184 END Get_Changed_Attributes;
1185 
1186 ----------------------------------------------------------------------
1187 
1188 --
1189 -- Private
1190 --
1191 PROCEDURE Propagate_Attributes (
1192           p_pk_column_name_value_pairs    IN  EGO_COL_NAME_VALUE_PAIR_ARRAY
1193         , p_class_code_name_value_pairs   IN  EGO_COL_NAME_VALUE_PAIR_ARRAY
1194         , p_data_level_name_value_pairs   IN  EGO_COL_NAME_VALUE_PAIR_ARRAY
1195         , p_attr_diffs                    IN  EGO_USER_ATTR_DIFF_TABLE
1196         , p_transaction_type              IN  VARCHAR2
1197         , p_attr_group_metadata_obj       IN  EGO_ATTR_GROUP_METADATA_OBJ
1198         , x_return_status                 OUT NOCOPY VARCHAR2
1199         , x_error_message                 OUT NOCOPY VARCHAR2
1200         )
1201   IS
1202     l_dynamic_sql           VARCHAR2(4000);
1203   BEGIN
1204 
1205     Debug_Msg('In Propagate_Attributes, starting', 1);
1206 
1207     IF (p_attr_group_metadata_obj.HIERARCHY_PROPAGATION_API IS NOT NULL) THEN
1208 
1209       Debug_Msg('In Propagate_Attributes, executing API: '||p_attr_group_metadata_obj.HIERARCHY_PROPAGATION_API, 1);
1210 
1211       BEGIN
1212 
1213         EXECUTE IMMEDIATE 'BEGIN '||p_attr_group_metadata_obj.HIERARCHY_PROPAGATION_API||'(:1, :2, :3, :4, :5, :6, :7); END;'
1214         USING  IN  p_pk_column_name_value_pairs
1215        , IN  p_class_code_name_value_pairs
1216        , IN  p_data_level_name_value_pairs
1217              , IN  p_attr_diffs
1218              , IN  p_transaction_type
1219              , IN  p_attr_group_metadata_obj.ATTR_GROUP_ID
1220              , OUT x_error_message;
1221 
1222       EXCEPTION
1223         WHEN OTHERS THEN
1224           Debug_Msg('In Propagate_Attributes, API failed: '||SQLERRM, 1);
1225           x_return_status := G_RET_STS_UNEXP_ERROR;
1226           x_error_message := SQLERRM;
1227           RETURN;
1228       END;
1229 
1230     END IF;
1231     IF x_error_message IS NULL THEN
1232       x_return_status := G_RET_STS_SUCCESS;
1233       Debug_Msg('In Propagate_Attributes, returned successfully ', 1);
1234     ELSE
1235       x_return_status := G_RET_STS_ERROR;
1236       Debug_Msg('In Propagate_Attributes, returned with error: '||x_error_message, 1);
1237     END IF;
1238 
1239     Debug_Msg('In Propagate_Attributes, done', 1);
1240 
1241 END Propagate_Attributes;
1242 
1243 ----------------------------------------------------------------------
1244 
1245 --
1246 -- Private
1247 --
1248 PROCEDURE Convert_Attr_Diff_To_Data (
1249           p_attr_diff_tbl                 IN EGO_USER_ATTR_DIFF_TABLE
1250         , px_attr_data_tbl                IN OUT NOCOPY EGO_USER_ATTR_DATA_TABLE
1251         , p_true_if_new                   IN BOOLEAN := TRUE
1252         -- px_is_delete returns true if this diff object contains a delete operation
1253         , px_is_delete                    OUT NOCOPY BOOLEAN
1254         , x_error_message                 OUT NOCOPY VARCHAR2
1255         )
1256   IS
1257     l_dynamic_sql           VARCHAR2(4000);
1258     l_row_identifier        NUMBER;
1259     l_debug_msg             VARCHAR2(10);
1260   BEGIN
1261 
1262     Debug_Msg('In Convert_Attr_Diff_To_data, starting', 1);
1263     px_is_delete := TRUE;
1264 
1265     IF p_attr_diff_tbl IS NOT NULL THEN
1266 
1267       FOR i IN p_attr_diff_tbl.FIRST..p_attr_diff_tbl.LAST LOOP
1268 
1269         IF px_attr_data_tbl IS NULL THEN
1270           Debug_Msg('In Convert_Attr_Diff_To_Data, px_attr_data_tbl is NULL', 1);
1271           px_attr_data_tbl := EGO_USER_ATTR_DATA_TABLE();
1272         END IF;
1273 
1274         -- Set row identifier based on previous contents of diff table
1275         l_row_identifier := 1;
1276         FOR j IN p_attr_diff_tbl.FIRST..i-1 LOOP
1277 
1278           IF (p_attr_diff_tbl(i).ATTR_NAME = p_attr_diff_tbl(j).ATTR_NAME) THEN
1279 
1280             l_row_identifier := l_row_identifier + 1;
1281 
1282           END IF;
1283 
1284         END LOOP;
1285 
1286         px_attr_data_tbl.EXTEND;
1287 
1288         IF (p_true_if_new) THEN
1289           px_attr_data_tbl(i) :=
1290             EGO_USER_ATTR_DATA_OBJ
1291       ( l_row_identifier
1292       , p_attr_diff_tbl(i).ATTR_NAME
1293       , p_attr_diff_tbl(i).NEW_ATTR_VALUE_STR
1294       , p_attr_diff_tbl(i).NEW_ATTR_VALUE_NUM
1295       , p_attr_diff_tbl(i).NEW_ATTR_VALUE_DATE
1296       , NULL--p_attr_diff_tbl(i).ATTR_DISP_VALUE
1297       , p_attr_diff_tbl(i).NEW_ATTR_UOM
1298       , NULL--p_attr_diff_tbl(i).USER_ROW_IDENTIFIER
1299       );
1300         ELSE
1301           px_attr_data_tbl(i) :=
1302             EGO_USER_ATTR_DATA_OBJ
1303       ( l_row_identifier
1304       , p_attr_diff_tbl(i).ATTR_NAME
1305       , p_attr_diff_tbl(i).OLD_ATTR_VALUE_STR
1306       , p_attr_diff_tbl(i).OLD_ATTR_VALUE_NUM
1307       , p_attr_diff_tbl(i).OLD_ATTR_VALUE_DATE
1308       , NULL--p_attr_diff_tbl(i).ATTR_DISP_VALUE
1309       , p_attr_diff_tbl(i).OLD_ATTR_UOM
1310       , NULL--p_attr_diff_tbl(i).USER_ROW_IDENTIFIER
1311       );
1312         END IF;
1313 
1314         -- turn px_is_delete off/false if we find a new attribute value
1315         IF px_is_delete AND
1316            (p_attr_diff_tbl(i).NEW_ATTR_VALUE_STR IS NOT NULL OR
1317             p_attr_diff_tbl(i).NEW_ATTR_VALUE_NUM IS NOT NULL OR
1318             p_attr_diff_tbl(i).NEW_ATTR_VALUE_DATE IS NOT NULL OR
1319             p_attr_diff_tbl(i).NEW_ATTR_UOM IS NOT NULL)
1320         THEN
1321 
1322           px_is_delete := FALSE;
1323 
1324         END IF;
1325 
1326       END LOOP;
1327 
1328     END IF;
1329 
1330     if px_is_delete
1331     then
1332       l_debug_msg := 'True' ;
1333     else
1334       l_debug_msg := 'False' ;
1335     end if;
1336 
1337     Debug_Msg('In Convert_Attr_Diff_To_Data, done, px_is_delete = '||l_debug_msg);
1338 
1339 END Convert_Attr_Diff_To_Data;
1340 
1341 
1342 ----------------------------------------------------------------------
1343 --
1344 -- Private
1345 --
1346 FUNCTION Build_Sorted_Data_Table (
1347         p_attributes_data_table         IN   EGO_USER_ATTR_DATA_TABLE
1348 )
1349 RETURN LOCAL_USER_ATTR_DATA_TABLE
1350 IS
1351 
1352 
1353     l_attr_data_table_index  NUMBER;
1354     l_current_data_element   EGO_USER_ATTR_DATA_OBJ;
1355     l_current_row_id         NUMBER;
1356     l_row_id_ordinality_table LOCAL_NUMBER_TABLE;
1357     l_row_id_ordinality      NUMBER;
1358     l_sorted_data_index_table LOCAL_NUMBER_TABLE;
1359     l_s_a_d_table_index      NUMBER;
1360     l_sorted_attr_data_table LOCAL_USER_ATTR_DATA_TABLE;
1361 
1362   BEGIN
1363 
1364     Debug_Msg('In Build_Sorted_Data_Table, starting', 2);
1365 
1366     ----------------------------------------------------------------------
1367     -- This function sorts the elements of p_attributes_data_table by   --
1368     -- ROW_IDENTIFIER.  It works by putting all elements for each       --
1369     -- distinct ROW_IDENTIFIER into their own "region" of an index-by   --
1370     -- table, l_sorted_attr_data_table.  To keep track of the correct   --
1371     -- index in each region at which we will insert the next element,   --
1372     -- we use two "helper tables": l_row_id_ordinality_table, the first --
1373     -- helper table, stores the ordinal number of each ROW_IDENTIFIER,  --
1374     -- and l_sorted_data_index_table, the second helper table, stores   --
1375     -- the next available index in the ROW_IDENTIFIER region for the    --
1376     -- ordinal number we fetched from l_row_id_ordinality_table.  This  --
1377     -- solution will allow us to process 1000 rows of data in each call --
1378     -- with 1000 elements for each row of data.                         --
1379     --                                                                  --
1380     -- EXAMPLE: we have two ROW_IDENTIFIERs: 1678 and 239330, and each  --
1381     -- of these ROW_IDENTIFIERs has five elements.  So this function    --
1382     -- loops through all ten passed-in elements and sorts them by       --
1383     -- ROW_IDENTIFIER, as follows (for three of the ten elements).      --
1384     -- First element ROW_IDENTIFIER is 239330.  Since there's nothing   --
1385     -- in l_row_id_ordinality_table for 239330, we add an entry with    --
1386     -- 239330 as the key and 1 (l_row_id_ordinality_table's current     --
1387     -- count + 1) as the value.  That value, 1, is now the ordinal      --
1388     -- number of 239330 (because 239330 is the *1*st ROW_IDENTIFIER     --
1389     -- we processed).  We use this ordinality to determine that the     --
1390     -- region in l_sorted_attr_data_table for 239330 is the region      --
1391     -- starting at (1 * 1000) = 1000.  Since this is the first element  --
1392     -- for this region, the first available index will be 1000, which   --
1393     -- we store in l_sorted_data_index_table.  Then, when we fetch      --
1394     -- the index, we increment the next available index to 1001.        --
1395     -- We use 1000 to add the first element to l_sorted_data_table.     --
1396     -- Second element ROW_IDENTIFIER is 1678.  Since there's nothing    --
1397     -- in l_row_id_ordinality_table for 1678, we add an entry with      --
1398     -- 1678 as the key and 2 (l_row_id_ordinality_table's current       --
1399     -- count + 1) as the value.  That value, 2, is now the ordinal      --
1400     -- number of 1678 (because 1678 is the *2*nd ROW_IDENTIFIER         --
1401     -- we processed).  We use this ordinality to determine that the     --
1402     -- region in l_sorted_attr_data_table for 1678 is the region        --
1403     -- starting at (2 * 1000) = 2000.  Since this is the first element  --
1404     -- for this region, the first available index will be 2000, which   --
1405     -- we store in l_sorted_data_index_table.  Then, when we fetch      --
1406     -- the index, we increment the next available index to 2001.        --
1407     -- We use 2000 to add the second element to l_sorted_data_table.    --
1408     -- Third element ROW_IDENTIFIER is 239330.  We find the ordinality  --
1409     -- for 239330 from l_row_id_ordinality_table as 1, and we use that  --
1410     -- to find the next available index from l_sorted_data_index_table  --
1411     -- as 1001.  Then we increment the next available index to 1002,    --
1412     -- and we use 1001 to add the third element to l_sorted_data_table. --
1413     ----------------------------------------------------------------------
1414     l_attr_data_table_index := p_attributes_data_table.FIRST;
1415     WHILE (l_attr_data_table_index <= p_attributes_data_table.LAST)
1416     LOOP
1417 
1418       l_current_data_element := p_attributes_data_table(l_attr_data_table_index);
1419       l_current_row_id := l_current_data_element.ROW_IDENTIFIER;
1420 
1421       IF (NOT l_row_id_ordinality_table.EXISTS(l_current_row_id)) THEN
1422         l_row_id_ordinality_table(l_current_row_id) := l_row_id_ordinality_table.COUNT + 1;
1423       END IF;
1424       l_row_id_ordinality := l_row_id_ordinality_table(l_current_row_id);
1425 
1426       IF (NOT l_sorted_data_index_table.EXISTS(l_row_id_ordinality)) THEN
1427         l_sorted_data_index_table(l_row_id_ordinality) := l_row_id_ordinality * 1000;
1428       END IF;
1429       l_s_a_d_table_index := l_sorted_data_index_table(l_row_id_ordinality);
1430       l_sorted_data_index_table(l_row_id_ordinality) :=
1431         l_sorted_data_index_table(l_row_id_ordinality) + 1;
1432 
1433       l_sorted_attr_data_table(l_s_a_d_table_index) := l_current_data_element;
1434 
1435       l_attr_data_table_index := p_attributes_data_table.NEXT(l_attr_data_table_index);
1436     END LOOP;
1437 
1438     Debug_Msg('In Build_Sorted_Data_Table, p_attributes_data_table.COUNT is '||
1439               p_attributes_data_table.COUNT||' and l_sorted_attr_data_table.COUNT is '||
1440               l_sorted_attr_data_table.COUNT);
1441     Debug_Msg('In Build_Sorted_Data_Table, done', 2);
1442 
1443     RETURN l_sorted_attr_data_table;
1444 
1445 END Build_Sorted_Data_Table;
1446 
1447 ----------------------------------------------------------------------
1448 
1449 --
1450 -- Private
1451 --
1452 FUNCTION Build_Sorted_Row_Table (
1453         p_attributes_row_table          IN   EGO_USER_ATTR_ROW_TABLE
1454 ) RETURN LOCAL_USER_ATTR_ROW_TABLE IS
1455 
1456     l_sorted_attr_row_table  LOCAL_USER_ATTR_ROW_TABLE;
1457     l_attr_row_table_index   NUMBER;
1458     l_current_row_element    EGO_USER_ATTR_ROW_OBJ;
1459     l_current_row_id         NUMBER;
1460     l_row_id_index_table     LOCAL_NUMBER_TABLE;
1461 
1462   BEGIN
1463 
1464     Debug_Msg('In Build_Sorted_Row_Table, starting', 2);
1465 
1466     l_attr_row_table_index := p_attributes_row_table.FIRST;
1467     WHILE (l_attr_row_table_index <= p_attributes_row_table.LAST)
1468     LOOP
1469 
1470       l_current_row_element := p_attributes_row_table(l_attr_row_table_index);
1471       l_current_row_id := l_current_row_element.ROW_IDENTIFIER;
1472       l_sorted_attr_row_table(l_current_row_id) := l_current_row_element;
1473 
1474       l_attr_row_table_index := p_attributes_row_table.NEXT(l_attr_row_table_index);
1475     END LOOP;
1476 
1477     Debug_Msg('In Build_Sorted_Row_Table, done', 2);
1478 
1479     RETURN l_sorted_attr_row_table;
1480 
1481 END Build_Sorted_Row_Table;
1482 
1483 ----------------------------------------------------------------------
1484 
1485 --
1486 -- Private
1487 --
1488 FUNCTION Get_Object_Id_From_Name (
1489         p_object_name                   IN   VARCHAR2
1490 )
1491 RETURN NUMBER
1492 IS
1493 
1494     l_object_name_table_index NUMBER;
1495     l_object_id              NUMBER;
1496 
1497   BEGIN
1498 
1499     Debug_Msg('In Get_Object_Id_From_Name, starting for p_object_name '||p_object_name, 2);
1500 
1501     IF (G_OBJECT_NAME_TO_ID_CACHE.FIRST IS NOT NULL) THEN
1502       l_object_name_table_index := G_OBJECT_NAME_TO_ID_CACHE.FIRST;
1503       WHILE (l_object_name_table_index <= G_OBJECT_NAME_TO_ID_CACHE.LAST)
1504       LOOP
1505         EXIT WHEN (l_object_id IS NOT NULL);
1506 
1507         IF (G_OBJECT_NAME_TO_ID_CACHE(l_object_name_table_index) = p_object_name) THEN
1508           l_object_id := l_object_name_table_index;
1509         END IF;
1510 
1511         l_object_name_table_index := G_OBJECT_NAME_TO_ID_CACHE.NEXT(l_object_name_table_index);
1512       END LOOP;
1513     END IF;
1514 
1515     IF (l_object_id IS NULL) THEN
1516 
1517       SELECT OBJECT_ID
1518         INTO l_object_id
1519         FROM FND_OBJECTS
1520        WHERE OBJ_NAME = p_object_name;
1521 
1522       G_OBJECT_NAME_TO_ID_CACHE(l_object_id) := p_object_name;
1523 
1524     END IF;
1525 
1526     Debug_Msg('In Get_Object_Id_From_Name, done: returning l_object_id as '||l_object_id, 2);
1527 
1528     RETURN l_object_id;
1529 
1530   EXCEPTION
1531     WHEN NO_DATA_FOUND THEN
1532       Debug_Msg('In Get_Object_Id_From_Name, EXCEPTION NO_DATA_FOUND', 1);
1533       RETURN NULL;
1534 
1535 END Get_Object_Id_From_Name;
1536 
1537 ----------------------------------------------------------------------
1538 
1539 --
1540 -- Private
1541 --
1542 FUNCTION Build_Data_Level_Array (
1543         p_object_name       IN  VARCHAR2
1544        ,p_data_level_id     IN  NUMBER DEFAULT NULL
1545        ,p_data_level_1      IN  VARCHAR2
1546        ,p_data_level_2      IN  VARCHAR2
1547        ,p_data_level_3      IN  VARCHAR2
1548        ,p_data_level_4      IN  VARCHAR2
1549        ,p_data_level_5      IN  VARCHAR2
1550 )
1551 RETURN EGO_COL_NAME_VALUE_PAIR_ARRAY
1552 IS
1553 
1554     l_object_id                     NUMBER;
1555     l_ext_table_metadata_obj        EGO_EXT_TABLE_METADATA_OBJ;
1556     l_data_level_metadata_array     EGO_COL_METADATA_ARRAY;
1557     l_data_level_1_name_value_pair  EGO_COL_NAME_VALUE_PAIR_OBJ;
1558     l_data_level_2_name_value_pair  EGO_COL_NAME_VALUE_PAIR_OBJ;
1559     l_data_level_3_name_value_pair  EGO_COL_NAME_VALUE_PAIR_OBJ;
1560     l_data_level_4_name_value_pair  EGO_COL_NAME_VALUE_PAIR_OBJ;
1561     l_data_level_5_name_value_pair  EGO_COL_NAME_VALUE_PAIR_OBJ;
1562     l_data_level_name_value_pairs   EGO_COL_NAME_VALUE_PAIR_ARRAY;
1563     l_data_level_metadata           EGO_DATA_LEVEL_METADATA_OBJ;
1564   BEGIN
1565 
1566     Debug_Msg('In Build_Data_Level_Array, starting', 2);
1567 
1568     -----------------------------------------------------------------
1569     -- Added for R12C, in case the data_level_id is passed we need --
1570     -- to process it accordingly.                                  --
1571     -----------------------------------------------------------------
1572     IF(p_data_level_id IS NOT NULL) THEN
1573 
1574       l_data_level_metadata := EGO_USER_ATTRS_COMMON_PVT.get_data_level_metadata(p_data_level_id);
1575       IF(l_data_level_metadata.PK_COLUMN_NAME1 IS NOT NULL) THEN
1576          l_data_level_1_name_value_pair := EGO_COL_NAME_VALUE_PAIR_OBJ(l_data_level_metadata.PK_COLUMN_NAME1,p_data_level_1);
1577       END IF;
1578 
1579       IF(l_data_level_metadata.PK_COLUMN_NAME2 IS NOT NULL) THEN
1580          l_data_level_2_name_value_pair := EGO_COL_NAME_VALUE_PAIR_OBJ(l_data_level_metadata.PK_COLUMN_NAME2,p_data_level_2);
1581       END IF;
1582 
1583       IF(l_data_level_metadata.PK_COLUMN_NAME3 IS NOT NULL) THEN
1584          l_data_level_3_name_value_pair := EGO_COL_NAME_VALUE_PAIR_OBJ(l_data_level_metadata.PK_COLUMN_NAME3,p_data_level_3);
1585       END IF;
1586 
1587       IF(l_data_level_metadata.PK_COLUMN_NAME4 IS NOT NULL) THEN
1588          l_data_level_4_name_value_pair := EGO_COL_NAME_VALUE_PAIR_OBJ(l_data_level_metadata.PK_COLUMN_NAME4,p_data_level_4);
1589       END IF;
1590 
1591       IF(l_data_level_metadata.PK_COLUMN_NAME5 IS NOT NULL) THEN
1592          l_data_level_5_name_value_pair := EGO_COL_NAME_VALUE_PAIR_OBJ(l_data_level_metadata.PK_COLUMN_NAME5,p_data_level_5);
1593       END IF;
1594 
1595       IF (l_data_level_5_name_value_pair IS NOT NULL) THEN
1596         l_data_level_name_value_pairs := EGO_COL_NAME_VALUE_PAIR_ARRAY(
1597                                            l_data_level_1_name_value_pair
1598                                           ,l_data_level_2_name_value_pair
1599                                           ,l_data_level_3_name_value_pair
1600                                           ,l_data_level_4_name_value_pair
1601                                           ,l_data_level_5_name_value_pair
1602                                          );
1603       ELSIF (l_data_level_4_name_value_pair IS NOT NULL) THEN
1604         l_data_level_name_value_pairs := EGO_COL_NAME_VALUE_PAIR_ARRAY(
1605                                            l_data_level_1_name_value_pair
1606                                           ,l_data_level_2_name_value_pair
1607                                           ,l_data_level_3_name_value_pair
1608                                           ,l_data_level_4_name_value_pair
1609                                          );
1610       ELSIF (l_data_level_3_name_value_pair IS NOT NULL) THEN
1611         l_data_level_name_value_pairs := EGO_COL_NAME_VALUE_PAIR_ARRAY(
1612                                            l_data_level_1_name_value_pair
1613                                           ,l_data_level_2_name_value_pair
1614                                           ,l_data_level_3_name_value_pair
1615                                          );
1616       ELSIF (l_data_level_2_name_value_pair IS NOT NULL) THEN
1617         l_data_level_name_value_pairs := EGO_COL_NAME_VALUE_PAIR_ARRAY(
1618                                            l_data_level_1_name_value_pair
1619                                           ,l_data_level_2_name_value_pair
1620                                          );
1621       ELSIF (l_data_level_1_name_value_pair IS NOT NULL) THEN
1622         l_data_level_name_value_pairs := EGO_COL_NAME_VALUE_PAIR_ARRAY(
1623                                            l_data_level_1_name_value_pair
1624                                          );
1625       ELSE
1626         l_data_level_name_value_pairs := NULL;
1627       END IF;
1628 
1629       RETURN l_data_level_name_value_pairs;
1630 
1631     END IF;
1632     -----------------------------------------------------------------------------R12C end
1633     l_object_id := Get_Object_Id_From_Name(p_object_name);
1634     l_ext_table_metadata_obj := EGO_USER_ATTRS_COMMON_PVT.Get_Ext_Table_Metadata(l_object_id);
1635     l_data_level_metadata_array := l_ext_table_metadata_obj.data_level_metadata;
1636 
1637     IF (l_data_level_metadata_array IS NOT NULL AND l_data_level_metadata_array(1) IS NOT NULL) THEN
1638       l_data_level_1_name_value_pair := EGO_COL_NAME_VALUE_PAIR_OBJ(
1639                                           l_data_level_metadata_array(1).COL_NAME
1640                                          ,p_data_level_1
1641                                         );
1642       IF (l_data_level_metadata_array.EXISTS(2) AND l_data_level_metadata_array(2) IS NOT NULL) THEN
1643         l_data_level_2_name_value_pair := EGO_COL_NAME_VALUE_PAIR_OBJ(
1644                                             l_data_level_metadata_array(2).COL_NAME
1645                                            ,p_data_level_2
1646                                           );
1647         IF (l_data_level_metadata_array.EXISTS(3) AND l_data_level_metadata_array(3) IS NOT NULL) THEN
1648           l_data_level_3_name_value_pair := EGO_COL_NAME_VALUE_PAIR_OBJ(
1649                                             l_data_level_metadata_array(3).COL_NAME
1650                                            ,p_data_level_3
1651                                           );
1652         END IF;
1653       END IF;
1654 
1655       IF (l_data_level_3_name_value_pair IS NOT NULL) THEN
1656         l_data_level_name_value_pairs := EGO_COL_NAME_VALUE_PAIR_ARRAY(
1657                                            l_data_level_1_name_value_pair
1658                                           ,l_data_level_2_name_value_pair
1659                                           ,l_data_level_3_name_value_pair
1660                                          );
1661       ELSIF (l_data_level_2_name_value_pair IS NOT NULL) THEN
1662         l_data_level_name_value_pairs := EGO_COL_NAME_VALUE_PAIR_ARRAY(
1663                                            l_data_level_1_name_value_pair
1664                                           ,l_data_level_2_name_value_pair
1665                                          );
1666       ELSE
1667         l_data_level_name_value_pairs := EGO_COL_NAME_VALUE_PAIR_ARRAY(
1668                                            l_data_level_1_name_value_pair
1669                                          );
1670 
1671       END IF;
1672     END IF;
1673 
1674     IF (l_data_level_name_value_pairs IS NOT NULL AND l_data_level_name_value_pairs.COUNT IS NOT NULL) THEN
1675       Debug_Msg('In Build_Data_Level_Array, l_data_level_name_value_pairs.COUNT is ' ||l_data_level_name_value_pairs.COUNT);
1676     ELSE
1677       Debug_Msg('In Build_Data_Level_Array, l_data_level_name_value_pairs is NULL or empty');
1678     END IF;
1679     Debug_Msg('In Build_Data_Level_Array, done', 2);
1680 
1681     RETURN l_data_level_name_value_pairs;
1682 
1683 END Build_Data_Level_Array;
1684 
1685 ----------------------------------------------------------------------
1686 
1687 --
1688 -- Private
1689 --
1690 FUNCTION Format_Sysdate_Expression (
1691         p_sysdate_expression    IN   VARCHAR2
1692 )
1693 RETURN VARCHAR2
1694 IS
1695     l_dynamic_sql         VARCHAR2(200);
1696     l_formatted_string    VARCHAR2(150);
1697 
1698   BEGIN
1699 
1700     --------------------------------------------------------------
1701     -- We need to remove any '$' chars used to tokenize Sysdate --
1702     -- (these are used when the Value Set bounds are defined).  --
1703     --------------------------------------------------------------
1704     l_formatted_string := TRIM(REPLACE(p_sysdate_expression, '$'));
1705 
1706     ----------------------------------------------------------------
1707     -- Now we rely on dynamic SQL to treat the bound string as an --
1708     -- expression for a Date object, and we call TO_CHAR on it to --
1709     -- turn it into a string version of that Date, formatted into --
1710     -- our standard format.                                       --
1711     ----------------------------------------------------------------
1712     l_dynamic_sql := 'SELECT TO_CHAR('||l_formatted_string||', '''||
1713                      EGO_USER_ATTRS_COMMON_PVT.G_DATE_FORMAT||''') FROM DUAL';
1714     Debug_Msg('In Format_Sysdate_Expression, l_dynamic_sql is as follows:', 3);
1715     Debug_SQL(l_dynamic_sql);
1716     EXECUTE IMMEDIATE l_dynamic_sql INTO l_formatted_string;
1717 
1718     RETURN l_formatted_string;
1719 
1720 END Format_Sysdate_Expression;
1721 
1722 ----------------------------------------------------------------------
1723 
1724 --
1725 -- Private
1726 --
1727 FUNCTION Find_Name_Value_Pair_For_Attr (
1728         p_attr_name_value_pairs   IN  EGO_USER_ATTR_DATA_TABLE
1729        ,p_attr_name               IN  VARCHAR2
1730 )
1731 RETURN EGO_USER_ATTR_DATA_OBJ
1732 IS
1733 
1734     l_table_index     NUMBER;
1735     l_attr_data_obj   EGO_USER_ATTR_DATA_OBJ;
1736 
1737   BEGIN
1738 
1739     Debug_Msg('In Find_Name_Value_Pair_For_Attr, starting for p_attr_name '||p_attr_name, 2);
1740 
1741     IF (p_attr_name_value_pairs IS NOT NULL AND
1742         p_attr_name_value_pairs.COUNT > 0) THEN
1743 
1744       l_table_index := p_attr_name_value_pairs.FIRST;
1745 
1746       IF (p_attr_name IS NOT NULL) THEN
1747 
1748         WHILE (l_table_index <= p_attr_name_value_pairs.LAST)
1749         LOOP
1750           EXIT WHEN (p_attr_name_value_pairs(l_table_index).ATTR_NAME = p_attr_name);
1751 
1752           l_table_index := p_attr_name_value_pairs.NEXT(l_table_index);
1753         END LOOP;
1754 
1755         -----------------------------------------------
1756         -- Make sure we have the correct table index --
1757         -----------------------------------------------
1758         IF (l_table_index IS NOT NULL AND
1759             p_attr_name_value_pairs(l_table_index).ATTR_NAME = p_attr_name) THEN
1760           l_attr_data_obj := p_attr_name_value_pairs(l_table_index);
1761         END IF;
1762       END IF;
1763     END IF;
1764 
1765     Debug_Msg('In Find_Name_Value_Pair_For_Attr, done', 2);
1766 
1767     RETURN l_attr_data_obj;
1768 
1769 END Find_Name_Value_Pair_For_Attr;
1770 
1771 ----------------------------------------------------------------------
1772 
1773 --
1774 -- Private
1775 --
1776 FUNCTION Find_Metadata_For_Col (
1777         p_ext_table_col_metadata  IN  EGO_COL_METADATA_ARRAY
1778        ,p_col_name                IN  VARCHAR2
1779 )
1780 RETURN EGO_COL_METADATA_OBJ
1781 IS
1782 
1783     l_col_metadata_index  NUMBER;
1784     l_col_metadata_obj    EGO_COL_METADATA_OBJ;
1785 
1786   BEGIN
1787 
1788     l_col_metadata_index := p_ext_table_col_metadata.FIRST;
1789     WHILE (l_col_metadata_index <= p_ext_table_col_metadata.LAST)
1790     LOOP
1791       EXIT WHEN (l_col_metadata_obj IS NOT NULL);
1792 
1793       IF (UPPER(p_col_name) = UPPER(p_ext_table_col_metadata(l_col_metadata_index).COL_NAME)) THEN
1794         l_col_metadata_obj := p_ext_table_col_metadata(l_col_metadata_index);
1795       END IF;
1796 
1797 
1798       Debug_Msg('In Find_Metadata_For_Col, next metadata column found - ' ||
1799                 UPPER(p_ext_table_col_metadata(l_col_metadata_index).COL_NAME), 5);
1800 
1801       l_col_metadata_index := p_ext_table_col_metadata.NEXT(l_col_metadata_index);
1802     END LOOP;
1803 
1804     RETURN l_col_metadata_obj;
1805 
1806   EXCEPTION
1807     WHEN OTHERS THEN
1808       Debug_Msg('In Find_Metadata_For_Col, EXCEPTION OTHERS', 1);
1809       RETURN NULL;
1810 
1811 END Find_Metadata_For_Col;
1812 
1813 ----------------------------------------------------------------------
1814 
1815 --
1816 -- Private
1817 --
1818 -- This procedure adds text and/or bind variables, as appropriate, to a dynamic SQL
1819 -- statement being constructed using the FND_DSQL package.  We assume that we are
1820 -- in the midst of building a statement, so we do not call Init().
1821 -- The procedure appends a final p_separator value onto the FND_DSQL list
1822 --
1823 -- The procedure's allowable p_mode values are:
1824 -- 'VALUES': adds bind variables for Attr values, separated appropriately, to FND_DSQL
1825 -- 'VALUES_DEF': special case of VALUES that uses DEFAULT_VALUE for any NULL Attributes
1826 -- 'COLUMNS': adds a comma-delimited list of ext table column names and no bind variables
1827 -- 'COLUMNS_DEF': special case of COLUMNS to match with VALUES_DEF
1828 -- 'EQUALS': adds a list of elements of the form 'ColumnN = :N', where N is a number;
1829 --           the bind variables are added by calls to Add_Bind(), passing the
1830 --           relevant Attribute data values
1831 --
1832 -- The parameter p_which_attrs determines which Attributes are considered in processing
1833 -- NOTE: if p_mode is 'VALUES_DEF' or 'COLUMNS_DEF', *ALL* Attributes will be considered,
1834 -- but the rest of the constraints below will still apply for the p_which_attrs values:
1835 -- 'ALL': processes all Attributes in p_attr_metadata_table
1836 -- 'TRANS': processes passed-in Attributes of data type Translatable Text
1837 -- 'NONTRANS': processes passed-in Attributes that are *not* Translatable Text
1838 -- 'UNIQUE_KEY': processes passed-in Attributes whose UNIQUE_KEY flag is 'Y'
1839 
1840 PROCEDURE Add_Attr_Info_To_Statement (
1841         p_attr_metadata_table     IN  EGO_ATTR_METADATA_TABLE
1842        ,p_attr_name_value_pairs   IN  EGO_USER_ATTR_DATA_TABLE
1843        ,p_separator               IN  VARCHAR2
1844        ,p_mode                    IN  VARCHAR2
1845        ,p_which_attrs             IN  VARCHAR2
1846 ) IS
1847 
1848     l_metadata_driven     BOOLEAN;
1849     l_for_loop_index      NUMBER;
1850     l_for_loop_last       NUMBER;
1851     l_attr_metadata_obj   EGO_ATTR_METADATA_OBJ;
1852     l_attr_data_obj       EGO_USER_ATTR_DATA_OBJ;
1853     l_unique_key_flag     VARCHAR2(1);
1854     l_data_type           VARCHAR2(1);
1855     l_column_name         VARCHAR2(30);
1856     l_default_value       EGO_ATTRS_V.DEFAULT_VALUE%TYPE;
1857     l_candidate_value     VARCHAR2(1000);
1858     l_uom_column          VARCHAR2(30);
1859     l_uom_value           VARCHAR2(10);
1860 
1861   BEGIN
1862 
1863     Debug_Msg('In Add_Attr_Info_To_Statement, starting', 2);
1864     Debug_Msg('In Add_Attr_Info_To_Statement, mode is '||p_mode||' and p_which_attrs is '|| p_which_attrs);
1865     ----------------------------------------------------------------------------
1866     -- If l_metadata_driven is TRUE, we loop through all metadata objects,    --
1867     -- because we want to process every Attribute in the Attribute Group even --
1868     -- if the caller didn't pass in an Attr Data object for each of them.     --
1869     -- Otherwise, we loop through all name/value pairs, ignoring Attributes   --
1870     -- that are in the Attribute Group but aren't mentioned by the caller.    --
1871     ----------------------------------------------------------------------------
1872     l_metadata_driven := (p_which_attrs = 'ALL' OR
1873                           p_mode = 'VALUES_DEF' OR
1874                           p_mode = 'COLUMNS_DEF');
1875 
1876     IF (l_metadata_driven OR
1877         (p_attr_name_value_pairs IS NOT NULL AND
1878          p_attr_name_value_pairs.COUNT > 0)) THEN
1879 
1880       IF (l_metadata_driven) THEN
1881         l_for_loop_index := p_attr_metadata_table.FIRST;
1882         l_for_loop_last := p_attr_metadata_table.LAST;
1883       ELSE
1884         l_for_loop_index := p_attr_name_value_pairs.FIRST;
1885         l_for_loop_last := p_attr_name_value_pairs.LAST;
1886       END IF;
1887 
1888       WHILE (l_for_loop_index <= l_for_loop_last)
1889       LOOP
1890 
1891         ----------------------------------------------------------------
1892         -- 1). Find the metadata and data objects for this Attribute; --
1893         -- if l_metadata_driven is TRUE, then l_attr_data_obj may be  --
1894         -- null, because the caller may not have passed in an Attr    --
1895         -- Data object for that Attribute.                            --
1896         ----------------------------------------------------------------
1897         IF (l_metadata_driven) THEN
1898           l_attr_metadata_obj := p_attr_metadata_table(l_for_loop_index);
1899           l_attr_data_obj := Find_Name_Value_Pair_For_Attr(
1900                                p_attr_name_value_pairs
1901                               ,l_attr_metadata_obj.ATTR_NAME
1902                              );
1903         ELSE
1904           l_attr_data_obj := p_attr_name_value_pairs(l_for_loop_index);
1905           l_attr_metadata_obj := EGO_USER_ATTRS_COMMON_PVT.Find_Metadata_For_Attr(
1906                                    p_attr_metadata_table => p_attr_metadata_table
1907                                   ,p_attr_name           => l_attr_data_obj.ATTR_NAME
1908                                  );
1909         END IF;
1910 
1911         ------------------------------------------------------------
1912         -- 2). Find the UNIQUE_KEY_FLAG and DATA_TYPE_CODE values --
1913         ------------------------------------------------------------
1914         l_unique_key_flag := l_attr_metadata_obj.UNIQUE_KEY_FLAG;
1915         l_data_type := l_attr_metadata_obj.DATA_TYPE_CODE;
1916 
1917         -----------------------------------------------------------------
1918         -- 3). If this Attribute should be processed (according to the --
1919         -- p_which_attrs value and relevant metadata), find the value  --
1920         -- (either passed in, Default, or NULL) and also the Database  --
1921         -- Column.  We use these two pieces of information as well as  --
1922         -- things like Data Type to build our list as specified by the --
1923         -- value of p_mode (e.g., 'COLUMNS', 'VALUES_DEF', etc.).      --
1924         -- Note that if the Attribute has a Value Set, we should have  --
1925         -- replaced the passed-in Value (which may have either been    --
1926         -- the Display Value or the Internal Value) with the Internal  --
1927         -- Value in Validate_Row.                                      --
1928         -----------------------------------------------------------------
1929         IF ((UPPER(p_which_attrs) = 'ALL') OR
1930             (UPPER(p_which_attrs) = 'UNIQUE_KEY' AND l_unique_key_flag = 'Y') OR
1931             (UPPER(p_which_attrs) = 'TRANS' AND
1932              l_data_type = EGO_EXT_FWK_PUB.G_TRANS_TEXT_DATA_TYPE) OR
1933             (UPPER(p_which_attrs) = 'NONTRANS' AND
1934              l_data_type <> EGO_EXT_FWK_PUB.G_TRANS_TEXT_DATA_TYPE)) THEN
1935 
1936           ---------------------------------------------------------------------------
1937           -- Reset UOM, column name, default and value variables each time through --
1938           ---------------------------------------------------------------------------
1939           l_uom_column := NULL;
1940           l_uom_value := NULL;
1941           l_candidate_value := NULL;
1942 
1943           l_column_name := l_attr_metadata_obj.DATABASE_COLUMN;
1944 
1945           IF (UPPER(p_mode) = 'VALUES_DEF') THEN
1946             l_default_value := l_attr_metadata_obj.DEFAULT_VALUE;
1947           ELSE
1948             l_default_value := NULL;
1949           END IF;
1950 
1951           ---------------------------------------------------------------
1952           -- First, try to use the value appropriate for the data type --
1953           ---------------------------------------------------------------
1954           IF (l_data_type IS NULL OR
1955               l_data_type = EGO_EXT_FWK_PUB.G_CHAR_DATA_TYPE OR
1956               l_data_type = EGO_EXT_FWK_PUB.G_TRANS_TEXT_DATA_TYPE) THEN
1957 
1958             l_candidate_value := l_attr_data_obj.ATTR_VALUE_STR;
1959             Debug_Msg('Candidate value:'||l_candidate_value);
1960 
1961           ELSIF (l_data_type = EGO_EXT_FWK_PUB.G_NUMBER_DATA_TYPE) THEN
1962 
1963             l_candidate_value := TO_CHAR(l_attr_data_obj.ATTR_VALUE_NUM);
1964 
1965             --------------------------------------------------------------------
1966             -- For all Number Attributes with UOM info, get the data/metadata --
1967             --------------------------------------------------------------------
1968             IF (l_attr_data_obj.ATTR_UNIT_OF_MEASURE IS NOT NULL) THEN
1969 
1970               IF (INSTR(l_column_name, 'N_EXT_ATTR') = 1) THEN
1971                 l_uom_column := 'UOM_' || SUBSTR(l_column_name, 3);
1972               ELSE
1973                 l_uom_column := 'UOM_' || l_column_name;
1974               END IF;
1975               l_uom_value := '''' || l_attr_data_obj.ATTR_UNIT_OF_MEASURE || '''';
1976 
1977             END IF;
1978 
1979           ELSIF (l_data_type = EGO_EXT_FWK_PUB.G_DATE_DATA_TYPE) THEN
1980 
1981             l_candidate_value := TO_CHAR(TRUNC(l_attr_data_obj.ATTR_VALUE_DATE),
1982                                          EGO_USER_ATTRS_COMMON_PVT.G_DATE_FORMAT);
1983 
1984           ELSIF (l_data_type = EGO_EXT_FWK_PUB.G_DATE_TIME_DATA_TYPE) THEN
1985 
1986             l_candidate_value := TO_CHAR(l_attr_data_obj.ATTR_VALUE_DATE,
1987                                          EGO_USER_ATTRS_COMMON_PVT.G_DATE_FORMAT);
1988 
1989           END IF;
1990 
1991           ----------------------------------------------------------
1992           -- If what we got is null, try to use the default value --
1993           ----------------------------------------------------------
1994           IF (l_candidate_value IS NULL AND
1995               l_default_value IS NOT NULL) THEN
1996 
1997             ---------------------------------------
1998             -- Format default value if necessary --
1999             ---------------------------------------
2000             IF ((l_data_type = EGO_EXT_FWK_PUB.G_DATE_DATA_TYPE OR
2001                  l_data_type = EGO_EXT_FWK_PUB.G_DATE_TIME_DATA_TYPE) AND
2002                 INSTR(UPPER(l_default_value), 'SYSDATE') > 0) THEN
2003               l_default_value := Format_Sysdate_Expression(l_default_value);
2004             END IF;
2005 
2006 /***
2007 ASSUMPTIONS:
2008 1). the UI validates that Number default values with UOM are in the UOM base
2009 2). the UI validates that Date default values are in
2010     EGO_USER_ATTRS_COMMON_PVT.G_DATE_FORMAT and that
2011     Standard Date default values are truncated appropriately
2012 ***/
2013 
2014             l_candidate_value := l_default_value;
2015 
2016           END IF;
2017 
2018           ----------------------------------------------
2019           -- Add column info to the list if necessary --
2020           ----------------------------------------------
2021           IF (UPPER(p_mode) = 'EQUALS' OR
2022               UPPER(p_mode) = 'COLUMNS' OR
2023               UPPER(p_mode) = 'COLUMNS_DEF') THEN
2024 
2025             FND_DSQL.Add_Text(l_column_name);
2026 
2027             IF (UPPER(p_mode) = 'EQUALS') THEN
2028 
2029               IF (l_candidate_value IS NULL AND p_separator = ' AND ') THEN
2030 
2031                 FND_DSQL.Add_Text(' IS ');
2032 
2033               ELSE
2034 
2035                 FND_DSQL.Add_Text(' = ');
2036 
2037               END IF;
2038 
2039             ELSE
2040 
2041               FND_DSQL.Add_Text(p_separator);
2042 
2043             END IF;
2044           END IF;
2045 
2046           ---------------------------------------------
2047           -- Add value info to the list if necessary --
2048           ---------------------------------------------
2049           IF (UPPER(p_mode) = 'EQUALS' OR
2050               UPPER(p_mode) = 'VALUES' OR
2051               UPPER(p_mode) = 'VALUES_DEF') THEN
2052 
2053             IF (l_candidate_value IS NULL) THEN
2054 
2055               FND_DSQL.Add_Text(' NULL ');
2056 
2057             ELSIF (l_data_type IS NULL OR
2058                    l_data_type = EGO_EXT_FWK_PUB.G_CHAR_DATA_TYPE OR
2059                    l_data_type = EGO_EXT_FWK_PUB.G_TRANS_TEXT_DATA_TYPE) THEN
2060 
2061               Add_Bind(p_bind_identifier => l_attr_metadata_obj.ATTR_GROUP_NAME||'$$'||l_attr_metadata_obj.ATTR_NAME
2062                       ,p_value           =>  l_candidate_value);
2063 
2064             ELSIF (l_data_type = EGO_EXT_FWK_PUB.G_NUMBER_DATA_TYPE) THEN
2065 
2066               Add_Bind(p_bind_identifier => l_attr_metadata_obj.ATTR_GROUP_NAME||'$$'||l_attr_metadata_obj.ATTR_NAME
2067                       ,p_value           => TO_NUMBER(l_candidate_value));
2068 
2069             ELSIF (l_data_type = EGO_EXT_FWK_PUB.G_DATE_DATA_TYPE OR
2070                    l_data_type = EGO_EXT_FWK_PUB.G_DATE_TIME_DATA_TYPE) THEN
2071 
2072               Add_Bind(p_bind_identifier => l_attr_metadata_obj.ATTR_GROUP_NAME||'$$'||l_attr_metadata_obj.ATTR_NAME
2073                       ,p_value           => TO_DATE(l_candidate_value, EGO_USER_ATTRS_COMMON_PVT.G_DATE_FORMAT));
2074 
2075             END IF;
2076 
2077             FND_DSQL.Add_Text(p_separator);
2078 
2079           END IF;
2080 
2081           -------------------------------------------
2082           -- Add UOM info to the list if necessary --
2083           -------------------------------------------
2084           IF (l_uom_column IS NOT NULL) THEN
2085 
2086             IF (UPPER(p_mode) = 'EQUALS' OR
2087                 UPPER(p_mode) = 'COLUMNS' OR
2088                 UPPER(p_mode) = 'COLUMNS_DEF') THEN
2089 
2090               FND_DSQL.Add_Text(l_uom_column);
2091 
2092               IF (UPPER(p_mode) = 'EQUALS') THEN
2093 
2094                 IF (l_uom_value IS NULL AND p_separator = ' AND ') THEN
2095 
2096                   FND_DSQL.Add_Text(' IS ');
2097 
2098                 ELSE
2099 
2100                   FND_DSQL.Add_Text(' = ');
2101 
2102                 END IF;
2103 
2104               ELSE
2105 
2106                 FND_DSQL.Add_Text(p_separator);
2107 
2108               END IF;
2109             END IF;
2110 
2111             IF (UPPER(p_mode) = 'EQUALS' OR
2112                 UPPER(p_mode) = 'VALUES' OR
2113                 UPPER(p_mode) = 'VALUES_DEF') THEN
2114 
2115               IF (l_uom_value IS NULL) THEN
2116 
2117                 FND_DSQL.Add_Text(' NULL ');
2118 
2119               ELSE
2120 
2121                 FND_DSQL.Add_Text(l_uom_value);
2122 
2123               END IF;
2124 
2125               FND_DSQL.Add_Text(p_separator);
2126 
2127             END IF;
2128           END IF;
2129         END IF;
2130 
2131         IF (l_metadata_driven) THEN
2132           l_for_loop_index := p_attr_metadata_table.NEXT(l_for_loop_index);
2133         ELSE
2134           l_for_loop_index := p_attr_name_value_pairs.NEXT(l_for_loop_index);
2135         END IF;
2136       END LOOP;
2137     END IF;
2138 
2139     Debug_Msg('In Add_Attr_Info_To_Statement, done', 2);
2140 
2141 END Add_Attr_Info_To_Statement;
2142 
2143 ----------------------------------------------------------------------
2144 
2145 -- This procedure builds a WHERE clause, which it adds to a SQL statement being
2146 -- built using the FND_DSQL package.  This procedure neither initializes nor
2147 -- executes that statement; it just adds text and bind variables through calls
2148 -- to FND_DSQL procedures.
2149 
2150 PROCEDURE Build_Where_Clause (
2151         p_attr_group_metadata_obj       IN  EGO_ATTR_GROUP_METADATA_OBJ
2152        ,p_ext_table_metadata_obj        IN  EGO_EXT_TABLE_METADATA_OBJ
2153        ,p_pk_column_name_value_pairs    IN  EGO_COL_NAME_VALUE_PAIR_ARRAY
2154        ,p_data_level                    IN  VARCHAR2   DEFAULT NULL --R12C
2155        ,p_data_level_name_value_pairs   IN  EGO_COL_NAME_VALUE_PAIR_ARRAY
2156        ,p_attr_name_value_pairs         IN  EGO_USER_ATTR_DATA_TABLE DEFAULT NULL
2157 ) IS
2158 
2159     l_api_name               VARCHAR2(30) := 'Build_Where_Clause';
2160     l_pk_col_string          VARCHAR2(1000) := '';
2161     l_data_level_string      VARCHAR2(1000) := '';
2162     l_data_level_id          NUMBER;
2163     l_dl_col_mdata_array     EGO_COL_METADATA_ARRAY;
2164   BEGIN
2165 
2166     Debug_Msg(l_api_name || ' starting, p_data_level='||p_data_level, 2);
2167     ---------------------------------------------------------------
2168     -- We add the Unique Key portion of the clause first because --
2169     -- Add_Attr_Info_To_Statement appends a trailing separator   --
2170     -- to the list if it adds anything to it; this also means we --
2171     -- don't need to add an ' AND ' after we add the Unique Key  --
2172     -- info, because Add_Attr_Info_To_Statement does that for us --
2173     ---------------------------------------------------------------
2174     IF (p_attr_name_value_pairs IS NOT NULL AND
2175         p_attr_name_value_pairs.COUNT > 0 AND
2176         p_attr_group_metadata_obj.MULTI_ROW_CODE = 'Y') THEN
2177 
2178       Add_Attr_Info_To_Statement(p_attr_group_metadata_obj.attr_metadata_table
2179                                 ,p_attr_name_value_pairs
2180                                 ,' AND '
2181                                 ,'EQUALS'
2182                                 ,'UNIQUE_KEY');
2183 
2184     END IF;
2185 
2186     IF (p_attr_group_metadata_obj.ATTR_GROUP_ID_FLAG ='Y') THEN
2187       FND_DSQL.Add_Text(' ATTR_GROUP_ID = ');
2188       Add_Bind(p_value => p_attr_group_metadata_obj.ATTR_GROUP_ID);
2189     ELSE
2190       FND_DSQL.Add_Text(' 1 = 1 ');
2191     END IF;
2192 
2193     --------------------------------------------------------------
2194     -- Added in R12C, for implementations uptaking the enhanced --
2195     -- support for data level p_data_level would be passed in.  --
2196     --------------------------------------------------------------
2197       IF(p_data_level IS NOT NULL
2198          AND
2199          FND_API.TO_BOOLEAN(
2200               EGO_USER_ATTRS_COMMON_PVT.has_column_in_table(p_table_name  => p_attr_group_metadata_obj.ext_table_vl_name
2201                                                            ,p_column_name => 'DATA_LEVEL_ID'
2202                                                            )
2203                            )
2204          ) THEN
2205       -- CONVERTING THE DATA_LEVEL_NAME TO ID --
2206       l_data_level_id := Get_Data_Level_Id( p_attr_group_metadata_obj.APPLICATION_ID
2207                                            ,p_attr_group_metadata_obj.ATTR_GROUP_TYPE
2208                                            ,p_data_level);
2209 
2210       FND_DSQL.Add_Text(' AND DATA_LEVEL_ID = ');
2211       Add_Bind(p_value => l_data_level_id);
2212     END IF;
2213 
2214 Debug_Msg(l_api_name ||' calling EGO_USER_ATTRS_COMMON_PVT.Get_List_For_Table_Cols for pk ');
2215     l_pk_col_string := EGO_USER_ATTRS_COMMON_PVT.Get_List_For_Table_Cols(
2216                          p_ext_table_metadata_obj.pk_column_metadata
2217                         ,p_pk_column_name_value_pairs
2218                         ,'EQUALS'
2219                         ,TRUE
2220                         ,' AND '
2221                        );
2222 
2223 Debug_Msg(l_api_name ||' calling EGO_USER_ATTRS_COMMON_PVT.Get_Data_Level_Col_Array ');
2224     l_dl_col_mdata_array:= EGO_USER_ATTRS_COMMON_PVT.Get_Data_Level_Col_Array(p_attr_group_metadata_obj.APPLICATION_ID,
2225                                                                              p_attr_group_metadata_obj.ATTR_GROUP_TYPE);
2226 
2227 Debug_Msg(l_api_name ||' calling EGO_USER_ATTRS_COMMON_PVT.Get_List_For_Table_Cols for data level ');
2228     l_data_level_string := EGO_USER_ATTRS_COMMON_PVT.Get_List_For_Table_Cols(
2229                              l_dl_col_mdata_array
2230                             ,p_data_level_name_value_pairs
2231                             ,'EQUALS'
2232                             ,TRUE
2233                             ,' AND '
2234                            );
2235 Debug_Msg(l_api_name ||' after the l_data_level_string :=  ... l_data_level_string='||l_data_level_string);
2236     -------------------------------------------------------------------------
2237     -- Since we will be querying on the extension table's VL, we no longer --
2238     -- need to constrain our queries by language (the VL does that for us) --
2239     -------------------------------------------------------------------------
2240 
2241     Debug_Msg(l_api_name || ' done', 2);
2242 
2243 END Build_Where_Clause;
2244 
2245 ----------------------------------------------------------------------
2246 
2247 PROCEDURE Sort_Attr_Values_Table (
2248         p_attr_group_metadata_obj   IN EGO_ATTR_GROUP_METADATA_OBJ
2249        ,px_attr_name_value_pairs    IN OUT NOCOPY EGO_USER_ATTR_DATA_TABLE
2250 ) IS
2251 
2252     l_sorted_attr_data_table   LOCAL_USER_ATTR_DATA_TABLE;
2253     l_sorted_data_table_index  NUMBER;
2254     l_attr_data_index          NUMBER;
2255     l_attr_metadata_obj        EGO_ATTR_METADATA_OBJ;
2256 
2257   BEGIN
2258 
2259     Debug_Msg('In Sort_Attr_Values_Table, starting', 2);
2260 
2261     -----------------------------------------------------------------------
2262     -- First, put the Attributes into a temp table according to SEQUENCE --
2263     -----------------------------------------------------------------------
2264     IF (px_attr_name_value_pairs IS NOT NULL AND
2265         px_attr_name_value_pairs.COUNT > 0) THEN
2266       l_attr_data_index := px_attr_name_value_pairs.FIRST;
2267       WHILE (l_attr_data_index <= px_attr_name_value_pairs.LAST)
2268       LOOP
2269 
2270         l_attr_metadata_obj := EGO_USER_ATTRS_COMMON_PVT.Find_Metadata_For_Attr(
2271                                  p_attr_metadata_table => p_attr_group_metadata_obj.attr_metadata_table
2272                                 ,p_attr_name           => px_attr_name_value_pairs(l_attr_data_index).ATTR_NAME
2273                                );
2274 
2275         l_sorted_attr_data_table(l_attr_metadata_obj.SEQUENCE) := px_attr_name_value_pairs(l_attr_data_index);
2276 
2277         l_attr_data_index := px_attr_name_value_pairs.NEXT(l_attr_data_index);
2278       END LOOP;
2279 
2280       ------------------------------------------------
2281       -- Next, clear out the name/value pairs table --
2282       -- to make room for the sorted Attributes     --
2283       ------------------------------------------------
2284       px_attr_name_value_pairs.DELETE();
2285 
2286       ---------------------------------------------------------------------------
2287       -- Finally, return the Attributes to the name/value pairs table in order --
2288       ---------------------------------------------------------------------------
2289       l_sorted_data_table_index := l_sorted_attr_data_table.FIRST;
2290       WHILE (l_sorted_data_table_index <= l_sorted_attr_data_table.LAST)
2291       LOOP
2292         px_attr_name_value_pairs.EXTEND();
2293         px_attr_name_value_pairs(px_attr_name_value_pairs.LAST) := l_sorted_attr_data_table(l_sorted_data_table_index);
2294         l_sorted_data_table_index := l_sorted_attr_data_table.NEXT(l_sorted_data_table_index);
2295       END LOOP;
2296     END IF;
2297 
2298     Debug_Msg('In Sort_Attr_Values_Table, done', 2);
2299 
2300 END Sort_Attr_Values_Table;
2301 
2302 ----------------------------------------------------------------------
2303 
2304 -- This function has two basic modes: if p_return_bound_sql is FALSE, then we
2305 -- initialize FND_DSQL to constuct/bind/execute the query and return the result.
2306 -- If TRUE, we build and return the query itself.  In this case, we don't pass
2307 -- p_final_bind_value or p_attr_name_value_pairs, and when replacing Attr Group
2308 -- tokens we construct a nested query to get the value required by the token.
2309 FUNCTION Tokenized_Val_Set_Query (
2310         p_attr_metadata_obj             IN  EGO_ATTR_METADATA_OBJ
2311        ,p_attr_group_metadata_obj       IN  EGO_ATTR_GROUP_METADATA_OBJ
2312        ,p_ext_table_metadata_obj        IN  EGO_EXT_TABLE_METADATA_OBJ
2313        ,p_pk_column_name_value_pairs    IN  EGO_COL_NAME_VALUE_PAIR_ARRAY
2314        ,p_data_level_name_value_pairs   IN  EGO_COL_NAME_VALUE_PAIR_ARRAY
2315        ,p_entity_id                     IN  VARCHAR2
2316        ,p_entity_index                  IN  NUMBER
2317        ,p_entity_code                   IN  VARCHAR2
2318        ,p_add_errors_to_fnd_stack       IN  VARCHAR2   DEFAULT FND_API.G_FALSE
2319        ,p_attr_name_value_pairs         IN  EGO_USER_ATTR_DATA_TABLE
2320        ,p_is_disp_to_int_query          IN  BOOLEAN
2321        ,p_final_bind_value              IN  VARCHAR2
2322        ,p_return_bound_sql              IN  BOOLEAN DEFAULT FALSE
2323 )
2324 RETURN VARCHAR2
2325 IS
2326 
2327     l_head_of_query              VARCHAR2(32767);
2328     l_tail_of_query              VARCHAR2(32767);
2329     l_has_tokens_left            BOOLEAN;
2330     l_token_start_index          NUMBER;
2331     l_token_end_index            NUMBER;
2332     l_token                      VARCHAR2(50);
2333     l_source_of_replacement      VARCHAR2(30);
2334     l_token_replacement          VARCHAR2(1000);
2335     l_token_data_type            VARCHAR2(1);
2336     l_pk_array_index             NUMBER;
2337     l_replacement_attr_metadata  EGO_ATTR_METADATA_OBJ;
2338     l_replacement_attr_data      EGO_USER_ATTR_DATA_OBJ;
2339     l_retrieved_value            VARCHAR2(1000);
2340     l_error_message_name         VARCHAR2(30);
2341     l_token_table                ERROR_HANDLER.Token_Tbl_Type;
2342     l_cursor_id                  NUMBER;
2343     l_dynamic_sql                VARCHAR2(32767);
2344     l_number_of_rows             NUMBER;
2345 
2346   BEGIN
2347 
2348     Debug_Msg('In Tokenized_Val_Set_Query, starting', 2);
2349 
2350     --------------------------------------------------------------------------
2351     -- If this function is being called from another package, then we won't --
2352     -- have initialized G_USER_ROW_IDENTIFIER yet; we try to use the row    --
2353     -- identifier from p_attr_name_value_pairs, but if it is NULL or empty  --
2354     -- we use the value 1 instead                                           --
2355     --------------------------------------------------------------------------
2356     IF (G_USER_ROW_IDENTIFIER = 0) THEN
2357       IF (p_attr_name_value_pairs IS NOT NULL AND
2358           p_attr_name_value_pairs.COUNT > 0) THEN
2359         G_USER_ROW_IDENTIFIER := p_attr_name_value_pairs(p_attr_name_value_pairs.FIRST).USER_ROW_IDENTIFIER;
2360       ELSE
2361         G_USER_ROW_IDENTIFIER := 1;
2362       END IF;
2363     END IF;
2364 
2365     IF (p_is_disp_to_int_query) THEN
2366       l_tail_of_query := p_attr_metadata_obj.DISP_TO_INT_VAL_QUERY;
2367     ELSE
2368       l_tail_of_query := p_attr_metadata_obj.INT_TO_DISP_VAL_QUERY;
2369     END IF;
2370 
2371     Debug_Msg('In Tokenized_Val_Set_Query, query starts as follows:');
2372     Debug_Sql(l_tail_of_query);
2373 
2374     --------------------------------------------------------------------------------
2375     -- We only process the query if the Attribute has a Value Set of type "Table" --
2376     -- (because that's the only case in which there may be tokens to replace)     --
2377     --------------------------------------------------------------------------------
2378     IF (p_attr_metadata_obj.VALIDATION_CODE = EGO_EXT_FWK_PUB.G_TABLE_VALIDATION_CODE) THEN
2379 
2380       l_has_tokens_left := (INSTR(UPPER(l_tail_of_query), ':$OBJECT$.') > 0 OR
2381                             INSTR(UPPER(l_tail_of_query), ':$ATTRIBUTEGROUP$.') > 0);
2382 
2383       IF (l_has_tokens_left) THEN
2384         Debug_Msg('In Tokenized_Val_Set_Query, query has tokens to process');
2385 
2386         IF (NOT p_return_bound_sql) THEN
2387           Init();
2388         END IF;
2389 
2390       ELSE
2391         Debug_Msg('In Tokenized_Val_Set_Query, query has no tokens');
2392       END IF;
2393 
2394       WHILE (l_has_tokens_left)
2395       LOOP
2396 
2397         -------------------------------------------------------------------------
2398         -- Get the token (even in the case where it's at the end of the query) --
2399         -------------------------------------------------------------------------
2400         l_token_start_index := INSTR(l_tail_of_query, ':$');
2401         l_token_end_index := INSTR(l_tail_of_query, ' ', l_token_start_index);
2402 /***
2403 Assumption: here we assume a space after the bind variable; perhaps we shouldn't
2404 ***/
2405         IF (l_token_end_index = 0) THEN
2406           l_token_end_index := LENGTH(l_tail_of_query) + 1;
2407         END IF;
2408         l_token := SUBSTR(l_tail_of_query, l_token_start_index, (l_token_end_index - l_token_start_index));
2409 
2410         ----------------------------------------------------------------
2411         -- Ensure we have a legitimate token and not a false positive --
2412         ----------------------------------------------------------------
2413         IF ((INSTR(UPPER(l_token), ':$OBJECT$.') = 1) OR
2414             (INSTR(UPPER(l_token), ':$ATTRIBUTEGROUP$.') = 1)) THEN
2415 
2416           l_source_of_replacement := SUBSTR(l_token, INSTR(l_token, '.') + 1);
2417 
2418           ------------------------------
2419           -- If we have a PK token... --
2420           ------------------------------
2421           IF (INSTR(UPPER(l_token), ':$OBJECT$.') = 1) THEN
2422 
2423             -----------------------------------------------------------
2424             -- ...find the appropriate PK value to replace the token --
2425             -----------------------------------------------------------
2426             l_pk_array_index := p_pk_column_name_value_pairs.FIRST;
2427             WHILE (l_pk_array_index <= p_pk_column_name_value_pairs.LAST)
2428             LOOP
2429               EXIT WHEN (l_token_replacement IS NOT NULL);
2430 
2431               --------------------------------------------------------------
2432               -- Case insensitive comparison for Primary Key column names --
2433               --------------------------------------------------------------
2434               IF (UPPER(l_source_of_replacement) =
2435                   UPPER(p_pk_column_name_value_pairs(l_pk_array_index).NAME)) THEN
2436                 l_token_replacement := p_pk_column_name_value_pairs(l_pk_array_index).VALUE;
2437               END IF;
2438 
2439               l_pk_array_index := p_pk_column_name_value_pairs.NEXT(l_pk_array_index);
2440             END LOOP;
2441 
2442             --------------------------------------------------------------------
2443             -- If we couldn't find a token replacement, the token must be bad --
2444             --------------------------------------------------------------------
2445             IF (l_token_replacement IS NULL) THEN
2446 
2447               l_error_message_name := 'EGO_EF_TOKEN_ERR_PK';
2448 
2449               l_token_table(1).TOKEN_NAME := 'ATTR_NAME';
2450               l_token_table(1).TOKEN_VALUE := p_attr_metadata_obj.ATTR_DISP_NAME;
2451               l_token_table(2).TOKEN_NAME := 'AG_NAME';
2452               l_token_table(2).TOKEN_VALUE := p_attr_group_metadata_obj.ATTR_GROUP_DISP_NAME;
2453               l_token_table(3).TOKEN_NAME := 'BAD_PK_NAME';
2454               l_token_table(3).TOKEN_VALUE := l_source_of_replacement;
2455               l_token_table(4).TOKEN_NAME := 'OBJ_NAME';
2456               l_token_table(4).TOKEN_VALUE := p_ext_table_metadata_obj.OBJ_NAME;
2457 
2458               ERROR_HANDLER.Add_Error_Message(
2459                 p_message_name      => l_error_message_name
2460                ,p_application_id    => 'EGO'
2461                ,p_token_tbl         => l_token_table
2462                ,p_message_type      => FND_API.G_RET_STS_ERROR
2463                ,p_row_identifier    => G_USER_ROW_IDENTIFIER
2464                ,p_entity_id         => p_entity_id
2465                ,p_entity_index      => p_entity_index
2466                ,p_entity_code       => p_entity_code
2467                ,p_addto_fnd_stack   => p_add_errors_to_fnd_stack
2468               );
2469 
2470               RAISE FND_API.G_EXC_ERROR;
2471             END IF;
2472 
2473           ------------------------------------
2474           -- Otherwise, we have an AG token --
2475           ------------------------------------
2476           ELSIF (INSTR(UPPER(l_token), ':$ATTRIBUTEGROUP$.') = 1) THEN
2477 
2478             -----------------------------------------
2479             -- Find the metadata for the Attribute --
2480             -- whose value will replace the token  --
2481             -----------------------------------------
2482             l_replacement_attr_metadata := EGO_USER_ATTRS_COMMON_PVT.Find_Metadata_For_Attr(
2483                                              p_attr_metadata_table => p_attr_group_metadata_obj.attr_metadata_table
2484                                             ,p_attr_name           => l_source_of_replacement
2485                                            );
2486 
2487             IF (l_replacement_attr_metadata IS NULL OR
2488                 l_replacement_attr_metadata.ATTR_NAME IS NULL) THEN
2489 
2490               ----------------------------------------------------------------------
2491               -- If the Attribute Group token yielded no metadata, it must be bad --
2492               ----------------------------------------------------------------------
2493               l_error_message_name := 'EGO_EF_TOKEN_ERR_AG';
2494 
2495               l_token_table(1).TOKEN_NAME := 'ATTR_NAME';
2496               l_token_table(1).TOKEN_VALUE := p_attr_metadata_obj.ATTR_DISP_NAME;
2497               l_token_table(2).TOKEN_NAME := 'AG_NAME';
2498               l_token_table(2).TOKEN_VALUE := p_attr_group_metadata_obj.ATTR_GROUP_DISP_NAME;
2499               l_token_table(3).TOKEN_NAME := 'BAD_ATTR_NAME';
2500               l_token_table(3).TOKEN_VALUE := l_source_of_replacement;
2501 
2502               ERROR_HANDLER.Add_Error_Message(
2503                 p_message_name      => l_error_message_name
2504                ,p_application_id    => 'EGO'
2505                ,p_token_tbl         => l_token_table
2506                ,p_message_type      => FND_API.G_RET_STS_ERROR
2507                ,p_row_identifier    => G_USER_ROW_IDENTIFIER
2508                ,p_entity_id         => p_entity_id
2509                ,p_entity_index      => p_entity_index
2510                ,p_entity_code       => p_entity_code
2511                ,p_addto_fnd_stack   => p_add_errors_to_fnd_stack
2512               );
2513 
2514               RAISE FND_API.G_EXC_ERROR;
2515 
2516             ELSE
2517 
2518               IF (p_return_bound_sql) THEN
2519 
2520                 ----------------------------------------------------------
2521                 -- If we are constructing and returning the query, then --
2522                 -- we don't have p_attr_name_value_pairs, so we'll have --
2523                 -- to use the replacement's database column name        --
2524                 ----------------------------------------------------------
2525                 l_token_replacement := l_replacement_attr_metadata.DATABASE_COLUMN;
2526 
2527               ELSIF (p_attr_name_value_pairs IS NOT NULL) THEN
2528 
2529                 --------------------------------------------------------------------------------
2530                 -- If we have Attr values, try replacing the token with the appropriate value --
2531                 --------------------------------------------------------------------------------
2532                 l_replacement_attr_data := Find_Name_Value_Pair_For_Attr(p_attr_name_value_pairs
2533                                                                         ,l_replacement_attr_metadata.ATTR_NAME);
2534 
2535                 IF (l_replacement_attr_data IS NOT NULL) THEN
2536 
2537                   IF (l_replacement_attr_metadata.DATA_TYPE_CODE IS NULL OR
2538                       l_replacement_attr_metadata.DATA_TYPE_CODE = EGO_EXT_FWK_PUB.G_CHAR_DATA_TYPE OR
2539                       l_replacement_attr_metadata.DATA_TYPE_CODE = EGO_EXT_FWK_PUB.G_TRANS_TEXT_DATA_TYPE) THEN
2540 
2541                     --l_token_replacement := l_replacement_attr_data.ATTR_VALUE_STR;
2542                       l_token_replacement := l_replacement_attr_data.ATTR_DISP_VALUE; -- Bug 6456697
2543 
2544                   ELSIF (l_replacement_attr_metadata.DATA_TYPE_CODE = EGO_EXT_FWK_PUB.G_NUMBER_DATA_TYPE) THEN
2545 
2546                     l_token_replacement := TO_CHAR(l_replacement_attr_data.ATTR_VALUE_NUM);
2547 
2548                   ELSIF (l_replacement_attr_metadata.DATA_TYPE_CODE = EGO_EXT_FWK_PUB.G_DATE_DATA_TYPE OR
2549                          l_replacement_attr_metadata.DATA_TYPE_CODE = EGO_EXT_FWK_PUB.G_DATE_TIME_DATA_TYPE) THEN
2550 
2551                     l_token_replacement := TO_CHAR(l_replacement_attr_data.ATTR_VALUE_DATE, EGO_USER_ATTRS_COMMON_PVT.G_DATE_FORMAT);
2552 
2553                   END IF;
2554 
2555                   -----------------------------------------------------------------------
2556                   -- If we don't have an internal value for this Attr but we do have a --
2557                   -- display value AND if the Attr does not have a bind value VS query --
2558                   -- (i.e., if we can guarantee it won't need Tokenized_Val_Set_Query) --
2559                   -- then we can try to get its internal value for our query           --
2560                   -- NOTE: we have to be careful here, because we're flirting with a   --
2561                   -- possibly tricky pseudo-recursion                                  --
2562                   -----------------------------------------------------------------------
2563                   IF (l_token_replacement IS NULL AND
2564                       l_replacement_attr_data.ATTR_DISP_VALUE IS NOT NULL AND
2565                       (l_replacement_attr_metadata.VS_BIND_VALUES_CODE IS NULL OR
2566                        l_replacement_attr_metadata.VS_BIND_VALUES_CODE = 'N')) THEN
2567 
2568                     Debug_Msg('In Tokenized_Val_Set_Query, trying to get int value for bind value Attr '||l_replacement_attr_data.ATTR_NAME);
2569 
2570 /***
2571 ASSUMPTION:
2572 We assume that all UK Attrs for the query have their int values already
2573 We sort by sequence, which should ensure that bind value Attrs are processed, but
2574 it won't guarantee that UK Attrs are processed...
2575 ***/
2576 
2577                     l_token_replacement := Get_Int_Val_For_Disp_Val(
2578                                              p_attr_metadata_obj             => l_replacement_attr_metadata
2579                                             ,p_attr_value_obj                => l_replacement_attr_data
2580                                             ,p_attr_group_metadata_obj       => p_attr_group_metadata_obj
2581                                             ,p_ext_table_metadata_obj        => p_ext_table_metadata_obj
2582                                             ,p_pk_column_name_value_pairs    => p_pk_column_name_value_pairs
2583                                             ,p_data_level_name_value_pairs   => p_data_level_name_value_pairs
2584                                             ,p_entity_id                     => p_entity_id
2585                                             ,p_entity_index                  => p_entity_index
2586                                             ,p_entity_code                   => p_entity_code
2587                                             ,p_attr_name_value_pairs         => p_attr_name_value_pairs
2588                                            );
2589 
2590                     Debug_Msg('In Tokenized_Val_Set_Query, got int value for bind value Attr '||l_replacement_attr_data.ATTR_NAME||' as '||l_token_replacement);
2591                   END IF;
2592                 END IF;
2593               END IF;
2594             END IF;
2595           END IF;
2596 
2597           -----------------------------------------------------------------------------
2598           -- By this point we have either a replacement value or NULL (which we just --
2599           -- pass and let things break); now we paste what we have into the query    --
2600           -----------------------------------------------------------------------------
2601           IF (p_return_bound_sql) THEN
2602             l_head_of_query := l_head_of_query ||
2603                                SUBSTR(l_tail_of_query, 1, (l_token_start_index - 1)) ||
2604                                l_token_replacement;
2605           ELSE
2606             FND_DSQL.Add_Text(SUBSTR(l_tail_of_query, 1, (l_token_start_index - 1)));
2607             Add_Bind(p_value => l_token_replacement);
2608           END IF;
2609 
2610         ELSE
2611 
2612           ---------------------------------------------------------------------
2613           -- In case of a false positive, we put what we thought was a token --
2614           -- back into the query, and we move forward past the end of it     --
2615           ---------------------------------------------------------------------
2616           IF (p_return_bound_sql) THEN
2617             l_head_of_query := l_head_of_query ||
2618                                SUBSTR(l_tail_of_query, 1, (l_token_end_index - 1));
2619           ELSE
2620             FND_DSQL.Add_Text(SUBSTR(l_tail_of_query, 1, (l_token_end_index - 1)));
2621           END IF;
2622 
2623         END IF;
2624 
2625         ------------------------------------------------------------------------------
2626         -- Clip the part of the query we just processed (even if it wasn't a token) --
2627         ------------------------------------------------------------------------------
2628         l_tail_of_query := SUBSTR(l_tail_of_query, l_token_end_index);
2629 
2630         l_has_tokens_left := (INSTR(UPPER(l_tail_of_query), ':$OBJECT$') > 0 OR
2631                               INSTR(UPPER(l_tail_of_query), ':$ATTRIBUTEGROUP$') > 0);
2632         l_token_replacement := NULL;
2633         l_replacement_attr_metadata := NULL;
2634 
2635       END LOOP;
2636     END IF;
2637 
2638     -------------------------------------------------------------------
2639     -- After processing all tokens (or if we didn't process at all), --
2640     -- we get the remainder of the query, bind the passed-in value,  --
2641     -- execute the query, and return our results                     --
2642     -------------------------------------------------------------------
2643     IF (p_return_bound_sql) THEN
2644       l_dynamic_sql := l_head_of_query || l_tail_of_query;
2645 
2646       Debug_Msg('In Tokenized_Val_Set_Query, l_dynamic_sql to be returned is as follows:', 3);
2647       Debug_SQL(l_dynamic_sql);
2648       Debug_Msg('In Tokenized_Val_Set_Query, done', 2);
2649       RETURN l_dynamic_sql;
2650 
2651     ELSE
2652       FND_DSQL.Add_Text(l_tail_of_query);
2653       Add_Bind(p_value => p_final_bind_value);
2654 
2655       l_dynamic_sql := FND_DSQL.Get_Text(FALSE);
2656 
2657       Debug_Msg('In Tokenized_Val_Set_Query, l_dynamic_sql to be executed is as follows:', 3);
2658       Debug_SQL(FND_DSQL.Get_Text(TRUE));
2659 
2660       l_cursor_id := DBMS_SQL.Open_Cursor;
2661 
2662       DBMS_SQL.Parse(l_cursor_id, l_dynamic_sql, DBMS_SQL.Native);
2663       FND_DSQL.Set_Cursor(l_cursor_id);
2664       FND_DSQL.Do_Binds();
2665       DBMS_SQL.Define_Column(l_cursor_id, 1, l_retrieved_value, 1000);
2666 
2667       l_number_of_rows := DBMS_SQL.Execute_And_Fetch(l_cursor_id);
2668 
2669       IF (l_number_of_rows > 0) THEN
2670 
2671         DBMS_SQL.Column_Value(l_cursor_id, 1, l_retrieved_value);
2672 
2673       END IF;
2674 
2675       DBMS_SQL.Close_Cursor(l_cursor_id);
2676 
2677       Debug_Msg('In Tokenized_Val_Set_Query, l_retrieved_value is as follows: '||
2678                 l_retrieved_value);
2679       Debug_Msg('In Tokenized_Val_Set_Query, done', 2);
2680       RETURN l_retrieved_value;
2681 
2682     END IF;
2683 
2684 END Tokenized_Val_Set_Query;
2685 
2686 ----------------------------------------------------------------------
2687 
2688 FUNCTION Get_Int_Val_For_Disp_Val (
2689         p_attr_metadata_obj             IN   EGO_ATTR_METADATA_OBJ
2690        ,p_attr_value_obj                IN   EGO_USER_ATTR_DATA_OBJ
2691        ,p_attr_group_metadata_obj       IN   EGO_ATTR_GROUP_METADATA_OBJ
2692        ,p_ext_table_metadata_obj        IN   EGO_EXT_TABLE_METADATA_OBJ
2693        ,p_pk_column_name_value_pairs    IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
2694        ,p_data_level_name_value_pairs   IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
2695        ,p_entity_id                     IN   VARCHAR2
2696        ,p_entity_index                  IN   NUMBER
2697        ,p_entity_code                   IN   VARCHAR2
2698        ,p_attr_name_value_pairs         IN   EGO_USER_ATTR_DATA_TABLE
2699 )
2700 RETURN VARCHAR2
2701 IS
2702 
2703     l_dynamic_sql            VARCHAR2(32767);
2704     l_disp_value             VARCHAR2(1000);
2705     l_int_value              VARCHAR2(1000);
2706 
2707   BEGIN
2708 
2709     ----------------------------------------------------------------------
2710     -- For Attributes with either "Independent" or "Table" Value Sets,  --
2711     -- there are Display Values and Internal Values that are different; --
2712     -- we store the Internal Values, but since the caller may only know --
2713     -- the Display Value we have this procedure to convert a given Disp --
2714     -- Value to its corresponding Int Value.  We treat Int Value and    --
2715     -- Disp Value as strings, but either may represent a Number or Date --
2716     ----------------------------------------------------------------------
2717     l_disp_value := p_attr_value_obj.ATTR_DISP_VALUE;
2718 
2719     Debug_Msg('In Get_Int_Val_For_Disp_Val, starting for l_disp_value '||l_disp_value, 2);
2720 
2721     IF (p_attr_metadata_obj.VALIDATION_CODE = EGO_EXT_FWK_PUB.G_INDEPENDENT_VALIDATION_CODE  OR
2722         p_attr_metadata_obj.VALIDATION_CODE = EGO_EXT_FWK_PUB.G_TRANS_IND_VALIDATION_CODE ) THEN
2723 --PERF TUNING 4957648
2724       l_dynamic_sql := 'SELECT DISTINCT FLEX_VALUE '||
2725                          ' FROM FND_FLEX_VALUES_VL '||
2726                         ' WHERE FLEX_VALUE_SET_ID = :1 '||
2727                           ' AND ENABLED_FLAG = ''Y'' '||
2728                           ' AND (NVL(START_DATE_ACTIVE, SYSDATE - 1) < SYSDATE) '||
2729                           ' AND (NVL(END_DATE_ACTIVE, SYSDATE + 1) > SYSDATE) '||
2730                           ' AND FLEX_VALUE_MEANING = :2 ';
2731 
2732       EXECUTE IMMEDIATE l_dynamic_sql
2733          INTO l_int_value
2734         USING p_attr_metadata_obj.VALUE_SET_ID, l_disp_value;
2735 
2736     ELSIF (p_attr_metadata_obj.VALIDATION_CODE = EGO_EXT_FWK_PUB.G_TABLE_VALIDATION_CODE) THEN
2737 
2738       ---------------------------------------------------------------------
2739       -- If the Table Value Set doesn't have an Additional Where Clause  --
2740       -- with bind values, we can go ahead and execute the query without --
2741       -- tokenizing at all                                               --
2742       ---------------------------------------------------------------------
2743       IF (p_attr_metadata_obj.VS_BIND_VALUES_CODE IS NULL OR
2744           p_attr_metadata_obj.VS_BIND_VALUES_CODE = 'N') THEN
2745 
2746         EXECUTE IMMEDIATE p_attr_metadata_obj.DISP_TO_INT_VAL_QUERY||' :1 AND ROWNUM < 2'
2747            INTO l_int_value
2748           USING l_disp_value;
2749 
2750       ELSE
2751 
2752         --------------------------------------------------------------------
2753         -- This is the hard case; it's a Table Value Set whose Additional --
2754         -- Where Clause has bind values, which means we'll have to call   --
2755         -- Tokenized_Val_Set_Query to execute the query on our behalf     --
2756         --------------------------------------------------------------------
2757         l_int_value := Tokenized_Val_Set_Query(
2758                          p_attr_metadata_obj           => p_attr_metadata_obj
2759                         ,p_attr_group_metadata_obj     => p_attr_group_metadata_obj
2760                         ,p_ext_table_metadata_obj      => p_ext_table_metadata_obj
2761                         ,p_pk_column_name_value_pairs  => p_pk_column_name_value_pairs
2762                         ,p_data_level_name_value_pairs => p_data_level_name_value_pairs
2763                         ,p_entity_id                   => p_entity_id
2764                         ,p_entity_index                => p_entity_index
2765                         ,p_entity_code                 => p_entity_code
2766                         ,p_attr_name_value_pairs       => p_attr_name_value_pairs
2767                         ,p_is_disp_to_int_query        => TRUE
2768                         ,p_final_bind_value            => l_disp_value
2769                        );
2770 
2771         Debug_Msg('In Get_Int_Val_For_Disp_Val, Tokenized_Val_Set_Query returned '||l_int_value, 3);
2772 
2773       END IF;
2774     END IF;
2775 
2776     Debug_Msg('In Get_Int_Val_For_Disp_Val, disp val of '||l_disp_value||' got int val as '||l_int_value);
2777     Debug_Msg('In Get_Int_Val_For_Disp_Val, done', 2);
2778 
2779     RETURN l_int_value;
2780 
2781   ------------------------------------------------------------------
2782   -- In cases where the Attribute value is not in the Value Set,  --
2783   -- we may get the ORA-01403 "NO_DATA_FOUND" error, and in cases --
2784   -- where we failed to substitute the bind values, we raise an   --
2785   -- error; so our EXCEPTION block catches those and returns NULL --
2786   ------------------------------------------------------------------
2787   EXCEPTION
2788     WHEN OTHERS THEN
2789       Debug_Msg('In Get_Int_Val_For_Disp_Val, EXCEPTION OTHERS', 1);
2790       RETURN NULL;
2791 
2792 END Get_Int_Val_For_Disp_Val;
2793 
2794 ----------------------------------------------------------------------
2795 
2796 FUNCTION Get_Disp_Val_For_Int_Val (
2797         p_attr_int_value                IN   VARCHAR2   DEFAULT NULL
2798        ,p_attr_value_obj                IN   EGO_USER_ATTR_DATA_OBJ DEFAULT NULL
2799        ,p_attr_metadata_obj             IN   EGO_ATTR_METADATA_OBJ
2800        ,p_attr_group_metadata_obj       IN   EGO_ATTR_GROUP_METADATA_OBJ
2801        ,p_pk_column_name_value_pairs    IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
2802        ,p_data_level_name_value_pairs   IN   EGO_COL_NAME_VALUE_PAIR_ARRAY DEFAULT NULL
2803        ,p_entity_id                     IN   VARCHAR2   DEFAULT NULL
2804        ,p_entity_index                  IN   NUMBER     DEFAULT NULL
2805        ,p_entity_code                   IN   VARCHAR2   DEFAULT NULL
2806        ,p_attr_name_value_pairs         IN   EGO_USER_ATTR_DATA_TABLE DEFAULT NULL
2807        ,p_ext_table_metadata_obj        IN   EGO_EXT_TABLE_METADATA_OBJ DEFAULT NULL
2808        ,p_object_name                   IN   VARCHAR2   DEFAULT NULL
2809 )
2810 RETURN VARCHAR2
2811 IS
2812 
2813     l_ext_table_metadata_obj EGO_EXT_TABLE_METADATA_OBJ;
2814     l_val_set_query          VARCHAR2(32767);
2815     l_attr_int_value         VARCHAR2(1000);
2816     l_attr_disp_value        VARCHAR2(1000);
2817 
2818   BEGIN
2819 
2820     Debug_Msg('In Get_Disp_Val_For_Int_Val, starting', 2);
2821 
2822     -------------------------------------------------------------------------------
2823     -- We get the Internal Value for the Attribute, either passed in directly or --
2824     -- passed in as a field in a data object; in the latter case, we assume that --
2825     -- the data type is correct because this was checked in Validate_Row already --
2826     -------------------------------------------------------------------------------
2827     IF (p_attr_int_value IS NOT NULL) THEN
2828 
2829       l_attr_int_value := p_attr_int_value;
2830 
2831     ELSIF (p_attr_metadata_obj.DATA_TYPE_CODE IS NULL OR
2832            p_attr_metadata_obj.DATA_TYPE_CODE = EGO_EXT_FWK_PUB.G_CHAR_DATA_TYPE OR
2833            p_attr_metadata_obj.DATA_TYPE_CODE = EGO_EXT_FWK_PUB.G_TRANS_TEXT_DATA_TYPE) THEN
2834 
2835       l_attr_int_value := p_attr_value_obj.ATTR_VALUE_STR;
2836 
2837     ELSIF (p_attr_metadata_obj.DATA_TYPE_CODE = EGO_EXT_FWK_PUB.G_NUMBER_DATA_TYPE) THEN
2838 
2839       l_attr_int_value := TO_CHAR(p_attr_value_obj.ATTR_VALUE_NUM);
2840 
2841     ELSIF (p_attr_metadata_obj.DATA_TYPE_CODE = EGO_EXT_FWK_PUB.G_DATE_DATA_TYPE OR
2842            p_attr_metadata_obj.DATA_TYPE_CODE = EGO_EXT_FWK_PUB.G_DATE_TIME_DATA_TYPE) THEN
2843 
2844       l_attr_int_value := TO_CHAR(p_attr_value_obj.ATTR_VALUE_DATE, EGO_USER_ATTRS_COMMON_PVT.G_DATE_FORMAT);
2845 
2846     END IF;
2847 
2848     l_attr_int_value := TRIM(l_attr_int_value);
2849 
2850     -------------------------------------------------------------------
2851     -- Next we handle the simple cases (i.e., all queries without an --
2852     -- Additional Where Clause containing user-defined bind values)  --
2853     -------------------------------------------------------------------
2854     -- fix for bug 4543638 included translatable independent validation code to get disp value
2855     IF (p_attr_metadata_obj.VALIDATION_CODE = EGO_EXT_FWK_PUB.G_INDEPENDENT_VALIDATION_CODE OR
2856         p_attr_metadata_obj.VALIDATION_CODE = EGO_EXT_FWK_PUB.G_TRANS_IND_VALIDATION_CODE
2857         ) THEN
2858 
2859       ---------------------------------------------------------------
2860       -- Even though our Attribute metadata object has this query  --
2861       -- stored, we use this version because our stored version    --
2862       -- has the Value Set ID hard-coded, whereas this version has --
2863       -- it as a bind value (which is more efficient); the stored  --
2864       -- version is only for use in Get_User_Attrs_Data            --
2865       ---------------------------------------------------------------
2866 --PERF TUNING 4957648
2867       l_val_set_query := 'SELECT DISTINCT FLEX_VALUE_MEANING '||
2868                            ' FROM FND_FLEX_VALUES_VL '||
2869                           ' WHERE FLEX_VALUE_SET_ID = :1 '||
2870                             ' AND ENABLED_FLAG = ''Y'' '||
2871                             ' AND (NVL(START_DATE_ACTIVE, SYSDATE - 1) < SYSDATE) '||
2872                             ' AND (NVL(END_DATE_ACTIVE, SYSDATE + 1) > SYSDATE) '||
2873                             ' AND FLEX_VALUE = :2 ';
2874 
2875       EXECUTE IMMEDIATE l_val_set_query
2876          INTO l_attr_disp_value
2877         USING p_attr_metadata_obj.VALUE_SET_ID, l_attr_int_value;
2878 
2879     ELSIF (p_attr_metadata_obj.VALIDATION_CODE = EGO_EXT_FWK_PUB.G_TABLE_VALIDATION_CODE AND
2880            (p_attr_metadata_obj.VS_BIND_VALUES_CODE IS NULL OR
2881             p_attr_metadata_obj.VS_BIND_VALUES_CODE = 'N')) THEN
2882 
2883       EXECUTE IMMEDIATE p_attr_metadata_obj.INT_TO_DISP_VAL_QUERY||' :1 AND ROWNUM < 2'
2884          INTO l_attr_disp_value
2885         USING l_attr_int_value;
2886 
2887     ELSE
2888 
2889       --------------------------------------------------------------------
2890       -- This is the hard case; it's a Table Value Set whose Additional --
2891       -- Where Clause has bind values, which means we'll have to call   --
2892       -- Tokenized_Val_Set_Query to execute the query on our behalf     --
2893       --------------------------------------------------------------------
2894       IF (p_ext_table_metadata_obj IS NOT NULL) THEN
2895         l_ext_table_metadata_obj := p_ext_table_metadata_obj;
2896       ELSE
2897         l_ext_table_metadata_obj := EGO_USER_ATTRS_COMMON_PVT.Get_Ext_Table_Metadata(Get_Object_Id_From_Name(p_object_name));
2898       END IF;
2899 
2900       l_attr_disp_value := Tokenized_Val_Set_Query(
2901                              p_attr_metadata_obj           => p_attr_metadata_obj
2902                             ,p_attr_group_metadata_obj     => p_attr_group_metadata_obj
2903                             ,p_ext_table_metadata_obj      => l_ext_table_metadata_obj
2904                             ,p_pk_column_name_value_pairs  => p_pk_column_name_value_pairs
2905                             ,p_data_level_name_value_pairs => p_data_level_name_value_pairs
2906                             ,p_entity_id                   => p_entity_id
2907                             ,p_entity_index                => p_entity_index
2908                             ,p_entity_code                 => p_entity_code
2909                             ,p_attr_name_value_pairs       => p_attr_name_value_pairs
2910                             ,p_is_disp_to_int_query        => FALSE
2911                             ,p_final_bind_value            => l_attr_int_value
2912                            );
2913 
2914     END IF;
2915 
2916     Debug_Msg('In Get_Disp_Val_For_Int_Val, done; returning '||l_attr_disp_value, 2);
2917 
2918     RETURN l_attr_disp_value;
2919 
2920   EXCEPTION
2921     WHEN OTHERS THEN
2922       Debug_Msg('In Get_Disp_Val_For_Int_Val, got exception '||SQLERRM, 3);
2923       RETURN NULL;
2924 
2925 END Get_Disp_Val_For_Int_Val;
2926 
2927 ----------------------------------------------------------------------
2928 
2929 FUNCTION Get_Extension_Id_For_Row (
2930         p_attr_group_metadata_obj       IN   EGO_ATTR_GROUP_METADATA_OBJ
2931        ,p_ext_table_metadata_obj        IN   EGO_EXT_TABLE_METADATA_OBJ
2932        ,p_pk_column_name_value_pairs    IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
2933        ,p_data_level                    IN   VARCHAR2   DEFAULT NULL --R12C
2934        ,p_data_level_name_value_pairs   IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
2935        ,p_attr_name_value_pairs         IN   EGO_USER_ATTR_DATA_TABLE
2936        ,p_change_obj                    IN   EGO_USER_ATTR_CHANGE_OBJ DEFAULT NULL
2937        ,p_extra_pk_col_name_val_pairs   IN   EGO_COL_NAME_VALUE_PAIR_ARRAY DEFAULT NULL
2938        ,p_pending_b_table_name          IN   VARCHAR2   DEFAULT NULL
2939        ,p_pending_vl_name               IN   VARCHAR2   DEFAULT NULL
2940 )
2941 RETURN NUMBER
2942 IS
2943 
2944     l_api_name               VARCHAR2(30)  := 'Get_Extension_Id_For_Row';
2945     l_vl_name                VARCHAR2(30);
2946     l_change_where_clause    VARCHAR2(1000);
2947     l_extra_where_clause     VARCHAR2(5000);
2948     l_cursor_id              NUMBER;
2949     l_dynamic_sql            VARCHAR2(15000);
2950     l_data_level_name_value_pairs EGO_COL_NAME_VALUE_PAIR_ARRAY;
2951     l_number_of_rows         NUMBER;
2952     l_extension_id           NUMBER;
2953     l_index                  NUMBER;
2954 
2955   BEGIN
2956 
2957     Debug_Msg(l_api_name || ' starting with p_data_level='||p_data_level, 2);
2958 
2959     --------------------------------------------------------------------------
2960     -- Determine whether we're in Change mode and set variables accordingly --
2961     --------------------------------------------------------------------------
2962     IF (p_change_obj IS NOT NULL
2963         AND
2964        (p_pending_vl_name IS NOT NULL OR p_pending_b_table_name IS NOT NULL)) THEN
2965 
2966       IF (p_pending_vl_name IS NOT NULL) THEN
2967         l_vl_name := p_pending_vl_name;
2968       ELSE
2969         l_vl_name := p_pending_b_table_name;
2970       END IF;
2971 
2972       IF (p_change_obj.CHANGE_ID IS NOT NULL) THEN
2973         l_change_where_clause := ' CHANGE_ID = '||p_change_obj.CHANGE_ID||' AND ';
2974       ELSE
2975         l_change_where_clause := ' AND CHANGE_ID IS NULL AND ';
2976       END IF;
2977 
2978       IF (p_change_obj.CHANGE_LINE_ID IS NOT NULL) THEN
2979         l_change_where_clause := l_change_where_clause||'CHANGE_LINE_ID = '||p_change_obj.CHANGE_LINE_ID||' AND ';
2980       ELSE
2981         l_change_where_clause := l_change_where_clause||'CHANGE_LINE_ID IS NULL AND ';
2982       END IF;
2983 
2984       --------------------------------------------------------------
2985       -- If querying from the pending table, we ignore Data Level --
2986       --------------------------------------------------------------
2987       l_data_level_name_value_pairs := NULL;
2988 
2989     ELSE
2990 
2991       IF (p_attr_group_metadata_obj.EXT_TABLE_VL_NAME IS NOT NULL) THEN
2992         l_vl_name := p_attr_group_metadata_obj.EXT_TABLE_VL_NAME;
2993       ELSE
2994         l_vl_name := p_attr_group_metadata_obj.EXT_TABLE_B_NAME;
2995       END IF;
2996 
2997       l_change_where_clause := '';
2998 
2999       l_data_level_name_value_pairs := p_data_level_name_value_pairs;
3000 
3001     END IF;
3002 
3003 
3004 
3005     --------------------------------------------------------------------------
3006     -- Include the extra pk's in the query if provided --
3007     --------------------------------------------------------------------------
3008     l_extra_where_clause := ' 1=1 ';
3009 
3010     IF (p_extra_pk_col_name_val_pairs IS NOT NULL AND
3011         (p_pending_vl_name IS NOT NULL OR p_pending_b_table_name IS NOT NULL)) THEN
3012 
3013       IF (p_pending_vl_name IS NOT NULL) THEN
3014         l_vl_name := p_pending_vl_name;
3015       ELSE
3016         l_vl_name := p_pending_b_table_name;
3017       END IF;
3018 
3019       IF (p_extra_pk_col_name_val_pairs IS NOT NULL AND p_extra_pk_col_name_val_pairs.COUNT > 0) THEN
3020         l_index := p_extra_pk_col_name_val_pairs.FIRST;
3021         WHILE (l_index IS NOT NULL)
3022         LOOP
3023           IF (p_extra_pk_col_name_val_pairs(l_index).NAME IS NOT NULL) THEN
3024 
3025                 l_extra_where_clause := l_extra_where_clause || ' AND ';
3026 
3027             IF (p_extra_pk_col_name_val_pairs(l_index).VALUE IS NOT NULL) THEN
3028                 l_extra_where_clause := l_extra_where_clause || p_extra_pk_col_name_val_pairs(l_index).NAME || ' = '
3029                                                              || p_extra_pk_col_name_val_pairs(l_index).VALUE || '  '  ;
3030             ELSE
3031                 l_extra_where_clause := l_extra_where_clause || p_extra_pk_col_name_val_pairs(l_index).NAME || ' IS NULL  ';
3032             END IF;
3033           END IF;
3034           l_index := p_extra_pk_col_name_val_pairs.NEXT(l_index);
3035         END LOOP;
3036       END IF;
3037     END IF;
3038 
3039     -----------------------------------------------
3040     -- We clear FND_DSQL and start our new query --
3041     -----------------------------------------------
3042     Init();
3043     FND_DSQL.Add_Text('SELECT EXTENSION_ID FROM ' || l_vl_name ||
3044                       ' WHERE 1=1 AND ' || l_change_where_clause||l_extra_where_clause||' AND ');
3045 
3046     Debug_Msg(l_api_name ||' calling  Build_Where_Clause', 3);
3047     Build_Where_Clause(p_attr_group_metadata_obj
3048                       ,p_ext_table_metadata_obj
3049                       ,p_pk_column_name_value_pairs
3050                       ,p_data_level
3051                       ,l_data_level_name_value_pairs -- NULL if we're in Change mode
3052                       ,p_attr_name_value_pairs);
3053     Debug_Msg(l_api_name ||' returning  Build_Where_Clause', 3);
3054 
3055     l_dynamic_sql := FND_DSQL.Get_Text(FALSE);
3056 
3057     Debug_Msg(l_api_name ||' l_dynamic_sql is as follows: '||l_dynamic_sql, 3);
3058     Debug_SQL(FND_DSQL.Get_Text(TRUE));
3059     ----------------------------------------
3060     -- Now we open a cursor for our query --
3061     ----------------------------------------
3062     l_cursor_id := DBMS_SQL.Open_Cursor;
3063 
3064     --------------------------------------------------
3065     -- Next we parse the query, bind our variables, --
3066     -- and tell DBMS_SQL what we want it to return  --
3067     --------------------------------------------------
3068     DBMS_SQL.Parse(l_cursor_id, l_dynamic_sql, DBMS_SQL.Native);
3069     FND_DSQL.Set_Cursor(l_cursor_id);
3070     FND_DSQL.Do_Binds();
3071     DBMS_SQL.Define_Column(l_cursor_id, 1, l_extension_id);
3072     ---------------------------------------------------------------------
3073     -- We execute the query and see how many rows we get; if we get no --
3074     -- rows, we return NULL, and if we get too many rows, we return -1 --
3075     ---------------------------------------------------------------------
3076     l_number_of_rows := DBMS_SQL.Execute_And_Fetch(l_cursor_id);
3077     IF (l_number_of_rows = 1) THEN
3078       DBMS_SQL.Column_Value(l_cursor_id, 1, l_extension_id);
3079     ELSIF (l_number_of_rows > 1) THEN
3080       l_extension_id := -1;
3081     END IF;
3082 
3083     ---------------------------------------------------------
3084     -- Finally, we close the cursor and return our results --
3085     ---------------------------------------------------------
3086     DBMS_SQL.Close_Cursor(l_cursor_id);
3087     Debug_Msg('In Get_Extension_Id_For_Row, done; l_extension_id is '||l_extension_id, 2);
3088 
3089     RETURN l_extension_id;
3090 EXCEPTION
3091   WHEN OTHERS THEN
3092      Debug_Msg(' Get_Extension_Id_For_Row EXCEPTION - '||SQLERRM);
3093 
3094 END Get_Extension_Id_For_Row;
3095 
3096 ----------------------------------------------------------------------
3097 
3098 FUNCTION Fetch_UK_Attr_Names_Table (
3099         p_attr_group_metadata_obj       IN   EGO_ATTR_GROUP_METADATA_OBJ
3100 )
3101 RETURN LOCAL_MEDIUM_VARCHAR_TABLE
3102 IS
3103 
3104     l_uk_attr_names_table    LOCAL_MEDIUM_VARCHAR_TABLE;
3105     l_uk_attr_names_table_index NUMBER := 1;
3106     l_uk_attrs_count         NUMBER;
3107     l_table_index            NUMBER;
3108     l_attr_metadata_obj      EGO_ATTR_METADATA_OBJ;
3109 
3110   BEGIN
3111 
3112     ----------------------------------------------------------------
3113     -- We find out how many UK Attrs there are in the Attr Group, --
3114     -- so we don't waste time looping after we've found them all  --
3115     ----------------------------------------------------------------
3116     l_uk_attrs_count := p_attr_group_metadata_obj.UNIQUE_KEY_ATTRS_COUNT;
3117 
3118     l_table_index := p_attr_group_metadata_obj.attr_metadata_table.FIRST;
3119     WHILE (l_table_index <= p_attr_group_metadata_obj.attr_metadata_table.LAST)
3120     LOOP
3121       EXIT WHEN (l_uk_attr_names_table.COUNT = l_uk_attrs_count);
3122 
3123       -----------------------------------------------------
3124       -- If we find a UK Attr, add its name to our table --
3125       -----------------------------------------------------
3126       IF (p_attr_group_metadata_obj.attr_metadata_table(l_table_index).UNIQUE_KEY_FLAG = 'Y') THEN
3127 
3128         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;
3129         l_uk_attr_names_table_index := l_uk_attr_names_table_index + 1;
3130 
3131       END IF;
3132 
3133       l_table_index := p_attr_group_metadata_obj.attr_metadata_table.NEXT(l_table_index);
3134     END LOOP;
3135 
3136     RETURN l_uk_attr_names_table;
3137 
3138 END Fetch_UK_Attr_Names_Table;
3139 
3140 ----------------------------------------------------------------------
3141 
3142 FUNCTION Fetch_UK_Attr_Values_Table (
3143         p_attr_group_metadata_obj       IN   EGO_ATTR_GROUP_METADATA_OBJ
3144        ,p_attr_name_value_pairs         IN   EGO_USER_ATTR_DATA_TABLE
3145 )
3146 RETURN LOCAL_BIG_VARCHAR_TABLE
3147 IS
3148 
3149     l_uk_attr_values_table   LOCAL_BIG_VARCHAR_TABLE;
3150     l_uk_attr_values_table_index NUMBER := 1;
3151     l_uk_attrs_count         NUMBER;
3152     l_table_index            NUMBER;
3153     l_attr_metadata_obj      EGO_ATTR_METADATA_OBJ;
3154 
3155   BEGIN
3156 
3157     ----------------------------------------------------------------
3158     -- We find out how many UK Attrs there are in the Attr Group, --
3159     -- so we don't waste time looping after we've found them all  --
3160     ----------------------------------------------------------------
3161     l_uk_attrs_count := p_attr_group_metadata_obj.UNIQUE_KEY_ATTRS_COUNT;
3162 
3163     IF (p_attr_name_value_pairs IS NULL OR
3164         p_attr_name_value_pairs.COUNT = 0) THEN
3165 
3166       --------------------------------------------------------
3167       -- If there were no values passed in, we need to show --
3168       -- 'NULL' in our error message for each UK value      --
3169       --------------------------------------------------------
3170       FOR i IN 1 .. l_uk_attrs_count
3171       LOOP
3172         l_uk_attr_values_table(i) := 'NULL';
3173       END LOOP;
3174 
3175     ELSE
3176 
3177       l_table_index := p_attr_name_value_pairs.FIRST;
3178       WHILE (l_table_index <= p_attr_name_value_pairs.LAST)
3179       LOOP
3180         EXIT WHEN (l_uk_attr_values_table.COUNT = l_uk_attrs_count);
3181 
3182         l_attr_metadata_obj := EGO_USER_ATTRS_COMMON_PVT.Find_Metadata_For_Attr(
3183                                  p_attr_metadata_table => p_attr_group_metadata_obj.attr_metadata_table
3184                                 ,p_attr_name           => p_attr_name_value_pairs(l_table_index).ATTR_NAME
3185                                );
3186 
3187         -----------------------------------------------------
3188         -- If we find a UK Attr value, add it to our table --
3189         -----------------------------------------------------
3190         IF (l_attr_metadata_obj.UNIQUE_KEY_FLAG = 'Y') THEN
3191 
3192           IF (l_attr_metadata_obj.DATA_TYPE_CODE IS NULL OR
3193               l_attr_metadata_obj.DATA_TYPE_CODE = EGO_EXT_FWK_PUB.G_CHAR_DATA_TYPE OR
3194               l_attr_metadata_obj.DATA_TYPE_CODE = EGO_EXT_FWK_PUB.G_TRANS_TEXT_DATA_TYPE) THEN
3195 
3196             l_uk_attr_values_table(l_uk_attr_values_table_index) := p_attr_name_value_pairs(l_table_index).ATTR_VALUE_STR;
3197 
3198           ELSIF (l_attr_metadata_obj.DATA_TYPE_CODE = EGO_EXT_FWK_PUB.G_NUMBER_DATA_TYPE) THEN
3199 
3200             l_uk_attr_values_table(l_uk_attr_values_table_index) := TO_CHAR(p_attr_name_value_pairs(l_table_index).ATTR_VALUE_NUM);
3201 
3202           ELSIF (l_attr_metadata_obj.DATA_TYPE_CODE = EGO_EXT_FWK_PUB.G_DATE_DATA_TYPE OR
3203                  l_attr_metadata_obj.DATA_TYPE_CODE = EGO_EXT_FWK_PUB.G_DATE_TIME_DATA_TYPE) THEN
3204 
3205             l_uk_attr_values_table(l_uk_attr_values_table_index) := TO_CHAR(p_attr_name_value_pairs(l_table_index).ATTR_VALUE_DATE
3206                                                                            ,EGO_USER_ATTRS_COMMON_PVT.G_DATE_FORMAT);
3207 
3208           END IF;
3209 
3210           l_uk_attr_values_table_index := l_uk_attr_values_table_index + 1;
3211         END IF;
3212 
3213         l_table_index := p_attr_name_value_pairs.NEXT(l_table_index);
3214       END LOOP;
3215     END IF;
3216 
3217     RETURN l_uk_attr_values_table;
3218 
3219 END Fetch_UK_Attr_Values_Table;
3220 
3221 ----------------------------------------------------------------------
3222 
3223 FUNCTION Fetch_UK_Attr_Names_List (
3224         p_uk_attr_names_table           IN   LOCAL_MEDIUM_VARCHAR_TABLE
3225 )
3226 RETURN VARCHAR2
3227 IS
3228 
3229     l_uk_attr_names_table_index NUMBER;
3230     l_uk_attr_names_list       VARCHAR2(100) := ''; -- tokens can only be 100 bytes long
3231 
3232   BEGIN
3233 
3234     --------------------------------------------------------------
3235     -- If there are more than 5 Unique Key Attributes, we try   --
3236     -- to make a list of them all; however, since ERROR_HANDLER --
3237     -- tokens can only be 100 bytes, we may well not be able    --
3238     -- to provide a complete list.  In that case, we tokenize   --
3239     -- the message with another message that basically says,    --
3240     -- "(the list is too long to display here)"                 --
3241     --------------------------------------------------------------
3242     l_uk_attr_names_table_index := p_uk_attr_names_table.FIRST;
3243     WHILE (l_uk_attr_names_table_index <= p_uk_attr_names_table.LAST)
3244     LOOP
3245       l_uk_attr_names_list := l_uk_attr_names_list ||
3246                               p_uk_attr_names_table(l_uk_attr_names_table_index) ||
3247                               ', ';
3248       l_uk_attr_names_table_index := p_uk_attr_names_table.NEXT(l_uk_attr_names_table_index);
3249     END LOOP;
3250 
3251     RETURN l_uk_attr_names_list;
3252 
3253   EXCEPTION
3254     WHEN OTHERS THEN
3255       Debug_Msg(' Fetch_UK_Attr_Names_List EXCEPTION OTHERS - '||SQLERRM);
3256       RETURN ERROR_HANDLER.Translate_Message('EGO', 'EGO_UK_TOO_LONG_TO_LIST');
3257 
3258 END Fetch_UK_Attr_Names_List;
3259 
3260 ----------------------------------------------------------------------
3261 
3262 PROCEDURE Get_Err_Info_For_UK_Not_Resp (
3263         p_attr_group_metadata_obj       IN   EGO_ATTR_GROUP_METADATA_OBJ
3264        ,p_is_err_in_production_table    IN   BOOLEAN
3265        ,x_unique_key_err_msg            OUT NOCOPY VARCHAR2
3266        ,x_token_table                   OUT NOCOPY ERROR_HANDLER.Token_Tbl_Type
3267 ) IS
3268 
3269     l_uk_attr_names_table   LOCAL_MEDIUM_VARCHAR_TABLE;
3270 
3271   BEGIN
3272 
3273     l_uk_attr_names_table := Fetch_UK_Attr_Names_Table(p_attr_group_metadata_obj);
3274 
3275     IF (p_attr_group_metadata_obj.UNIQUE_KEY_ATTRS_COUNT = 1) THEN
3276 
3277       x_unique_key_err_msg := 'EGO_EF_UK1_NOT_RESP';
3278 
3279       x_token_table(1).TOKEN_NAME := 'AG_NAME';
3280       x_token_table(1).TOKEN_VALUE := p_attr_group_metadata_obj.ATTR_GROUP_DISP_NAME;
3281       x_token_table(2).TOKEN_NAME := 'UK1_NAME';
3282       x_token_table(2).TOKEN_VALUE := l_uk_attr_names_table(1);
3283 
3284     ELSIF (p_attr_group_metadata_obj.UNIQUE_KEY_ATTRS_COUNT = 2) THEN
3285 
3286       x_unique_key_err_msg := 'EGO_EF_UK2_NOT_RESP';
3287 
3288       x_token_table(1).TOKEN_NAME := 'AG_NAME';
3289       x_token_table(1).TOKEN_VALUE := p_attr_group_metadata_obj.ATTR_GROUP_DISP_NAME;
3290       x_token_table(2).TOKEN_NAME := 'UK1_NAME';
3291       x_token_table(2).TOKEN_VALUE := l_uk_attr_names_table(1);
3292       x_token_table(3).TOKEN_NAME := 'UK2_NAME';
3293       x_token_table(3).TOKEN_VALUE := l_uk_attr_names_table(2);
3294 
3295     ELSIF (p_attr_group_metadata_obj.UNIQUE_KEY_ATTRS_COUNT = 3) THEN
3296 
3297       x_unique_key_err_msg := 'EGO_EF_UK3_NOT_RESP';
3298 
3299       x_token_table(1).TOKEN_NAME := 'AG_NAME';
3300       x_token_table(1).TOKEN_VALUE := p_attr_group_metadata_obj.ATTR_GROUP_DISP_NAME;
3301       x_token_table(2).TOKEN_NAME := 'UK1_NAME';
3302       x_token_table(2).TOKEN_VALUE := l_uk_attr_names_table(1);
3303       x_token_table(3).TOKEN_NAME := 'UK2_NAME';
3304       x_token_table(3).TOKEN_VALUE := l_uk_attr_names_table(2);
3305       x_token_table(4).TOKEN_NAME := 'UK3_NAME';
3306       x_token_table(4).TOKEN_VALUE := l_uk_attr_names_table(3);
3307 
3308     ELSIF (p_attr_group_metadata_obj.UNIQUE_KEY_ATTRS_COUNT = 4) THEN
3309 
3310       x_unique_key_err_msg := 'EGO_EF_UK4_NOT_RESP';
3311 
3312       x_token_table(1).TOKEN_NAME := 'AG_NAME';
3313       x_token_table(1).TOKEN_VALUE := p_attr_group_metadata_obj.ATTR_GROUP_DISP_NAME;
3314       x_token_table(2).TOKEN_NAME := 'UK1_NAME';
3315       x_token_table(2).TOKEN_VALUE := l_uk_attr_names_table(1);
3316       x_token_table(3).TOKEN_NAME := 'UK2_NAME';
3317       x_token_table(3).TOKEN_VALUE := l_uk_attr_names_table(2);
3318       x_token_table(4).TOKEN_NAME := 'UK3_NAME';
3319       x_token_table(4).TOKEN_VALUE := l_uk_attr_names_table(3);
3320       x_token_table(5).TOKEN_NAME := 'UK4_NAME';
3321       x_token_table(5).TOKEN_VALUE := l_uk_attr_names_table(4);
3322 
3323     ELSIF (p_attr_group_metadata_obj.UNIQUE_KEY_ATTRS_COUNT = 5) THEN
3324 
3325       x_unique_key_err_msg := 'EGO_EF_UK5_NOT_RESP';
3326 
3327       x_token_table(1).TOKEN_NAME := 'AG_NAME';
3328       x_token_table(1).TOKEN_VALUE := p_attr_group_metadata_obj.ATTR_GROUP_DISP_NAME;
3329       x_token_table(2).TOKEN_NAME := 'UK1_NAME';
3330       x_token_table(2).TOKEN_VALUE := l_uk_attr_names_table(1);
3331       x_token_table(3).TOKEN_NAME := 'UK2_NAME';
3332       x_token_table(3).TOKEN_VALUE := l_uk_attr_names_table(2);
3333       x_token_table(4).TOKEN_NAME := 'UK3_NAME';
3334       x_token_table(4).TOKEN_VALUE := l_uk_attr_names_table(3);
3335       x_token_table(5).TOKEN_NAME := 'UK4_NAME';
3336       x_token_table(5).TOKEN_VALUE := l_uk_attr_names_table(4);
3337       x_token_table(6).TOKEN_NAME := 'UK5_NAME';
3338       x_token_table(6).TOKEN_VALUE := l_uk_attr_names_table(5);
3339 
3340     ELSE
3341 
3342       x_unique_key_err_msg := 'EGO_EF_LONG_UK_NOT_RESP';
3343 
3344       x_token_table(1).TOKEN_NAME := 'AG_NAME';
3345       x_token_table(1).TOKEN_VALUE := p_attr_group_metadata_obj.ATTR_GROUP_DISP_NAME;
3346       x_token_table(2).TOKEN_NAME := 'UK_NAME_LIST';
3347       x_token_table(2).TOKEN_VALUE := Fetch_UK_Attr_Names_List(l_uk_attr_names_table);
3348 
3349     END IF;
3350 
3351 END Get_Err_Info_For_UK_Not_Resp;
3352 
3353 ----------------------------------------------------------------------
3354 
3355 PROCEDURE Get_Err_Info_For_UK_Violation (
3356         p_attr_group_metadata_obj       IN   EGO_ATTR_GROUP_METADATA_OBJ
3357        ,p_attr_name_value_pairs         IN   EGO_USER_ATTR_DATA_TABLE
3358        ,p_is_err_in_production_table    IN   BOOLEAN
3359        ,x_unique_key_err_msg            OUT NOCOPY VARCHAR2
3360        ,x_token_table                   OUT NOCOPY ERROR_HANDLER.Token_Tbl_Type
3361 ) IS
3362 
3363     l_uk_attr_names_table   LOCAL_MEDIUM_VARCHAR_TABLE;
3364     l_uk_attr_values_table   LOCAL_BIG_VARCHAR_TABLE;
3365 
3366   BEGIN
3367 
3368     l_uk_attr_names_table := Fetch_UK_Attr_Names_Table(p_attr_group_metadata_obj);
3369     l_uk_attr_values_table := Fetch_UK_Attr_Values_Table(p_attr_group_metadata_obj
3370                                                         ,p_attr_name_value_pairs);
3371 
3372     IF (p_attr_group_metadata_obj.UNIQUE_KEY_ATTRS_COUNT = 1) THEN
3373 
3374       x_unique_key_err_msg := 'EGO_EF_UK1_VIOLATION';
3375 
3376       x_token_table(1).TOKEN_NAME := 'AG_NAME';
3377       x_token_table(1).TOKEN_VALUE := p_attr_group_metadata_obj.ATTR_GROUP_DISP_NAME;
3378       x_token_table(2).TOKEN_NAME := 'UK1_NAME';
3379       x_token_table(2).TOKEN_VALUE := l_uk_attr_names_table(1);
3380       x_token_table(3).TOKEN_NAME := 'ATTR1_VALUE';
3381       x_token_table(3).TOKEN_VALUE := l_uk_attr_values_table(1);
3382 
3383     ELSIF (p_attr_group_metadata_obj.UNIQUE_KEY_ATTRS_COUNT = 2) THEN
3384 
3385       x_unique_key_err_msg := 'EGO_EF_UK2_VIOLATION';
3386 
3387       x_token_table(1).TOKEN_NAME := 'AG_NAME';
3388       x_token_table(1).TOKEN_VALUE := p_attr_group_metadata_obj.ATTR_GROUP_DISP_NAME;
3389       x_token_table(2).TOKEN_NAME := 'UK1_NAME';
3390       x_token_table(2).TOKEN_VALUE := l_uk_attr_names_table(1);
3391       x_token_table(3).TOKEN_NAME := 'ATTR1_VALUE';
3392       x_token_table(3).TOKEN_VALUE := l_uk_attr_values_table(1);
3393       x_token_table(4).TOKEN_NAME := 'UK2_NAME';
3394       x_token_table(4).TOKEN_VALUE := l_uk_attr_names_table(2);
3395       x_token_table(5).TOKEN_NAME := 'ATTR2_VALUE';
3396       x_token_table(5).TOKEN_VALUE := l_uk_attr_values_table(2);
3397 
3398     ELSIF (p_attr_group_metadata_obj.UNIQUE_KEY_ATTRS_COUNT = 3) THEN
3399 
3400       x_unique_key_err_msg := 'EGO_EF_UK3_VIOLATION';
3401 
3402       x_token_table(1).TOKEN_NAME := 'AG_NAME';
3403       x_token_table(1).TOKEN_VALUE := p_attr_group_metadata_obj.ATTR_GROUP_DISP_NAME;
3404       x_token_table(2).TOKEN_NAME := 'UK1_NAME';
3405       x_token_table(2).TOKEN_VALUE := l_uk_attr_names_table(1);
3406       x_token_table(3).TOKEN_NAME := 'ATTR1_VALUE';
3407       x_token_table(3).TOKEN_VALUE := l_uk_attr_values_table(1);
3408       x_token_table(4).TOKEN_NAME := 'UK2_NAME';
3409       x_token_table(4).TOKEN_VALUE := l_uk_attr_names_table(2);
3410       x_token_table(5).TOKEN_NAME := 'ATTR2_VALUE';
3411       x_token_table(5).TOKEN_VALUE := l_uk_attr_values_table(2);
3412       x_token_table(6).TOKEN_NAME := 'UK3_NAME';
3413       x_token_table(6).TOKEN_VALUE := l_uk_attr_names_table(3);
3414       x_token_table(7).TOKEN_NAME := 'ATTR3_VALUE';
3415       x_token_table(7).TOKEN_VALUE := l_uk_attr_values_table(3);
3416 
3417     ELSIF (p_attr_group_metadata_obj.UNIQUE_KEY_ATTRS_COUNT = 4) THEN
3418 
3419       x_unique_key_err_msg := 'EGO_EF_UK4_VIOLATION';
3420 
3421       x_token_table(1).TOKEN_NAME := 'AG_NAME';
3422       x_token_table(1).TOKEN_VALUE := p_attr_group_metadata_obj.ATTR_GROUP_DISP_NAME;
3423       x_token_table(2).TOKEN_NAME := 'UK1_NAME';
3424       x_token_table(2).TOKEN_VALUE := l_uk_attr_names_table(1);
3425       x_token_table(3).TOKEN_NAME := 'ATTR1_VALUE';
3426       x_token_table(3).TOKEN_VALUE := l_uk_attr_values_table(1);
3427       x_token_table(4).TOKEN_NAME := 'UK2_NAME';
3428       x_token_table(4).TOKEN_VALUE := l_uk_attr_names_table(2);
3429       x_token_table(5).TOKEN_NAME := 'ATTR2_VALUE';
3430       x_token_table(5).TOKEN_VALUE := l_uk_attr_values_table(2);
3431       x_token_table(6).TOKEN_NAME := 'UK3_NAME';
3432       x_token_table(6).TOKEN_VALUE := l_uk_attr_names_table(3);
3433       x_token_table(7).TOKEN_NAME := 'ATTR3_VALUE';
3434       x_token_table(7).TOKEN_VALUE := l_uk_attr_values_table(3);
3435       x_token_table(8).TOKEN_NAME := 'UK4_NAME';
3436       x_token_table(8).TOKEN_VALUE := l_uk_attr_names_table(4);
3437       x_token_table(9).TOKEN_NAME := 'ATTR4_VALUE';
3438       x_token_table(9).TOKEN_VALUE := l_uk_attr_values_table(4);
3439 
3440     ELSIF (p_attr_group_metadata_obj.UNIQUE_KEY_ATTRS_COUNT = 5) THEN
3441 
3442       x_unique_key_err_msg := 'EGO_EF_UK4_VIOLATION';
3443 
3444       x_token_table(1).TOKEN_NAME := 'AG_NAME';
3445       x_token_table(1).TOKEN_VALUE := p_attr_group_metadata_obj.ATTR_GROUP_DISP_NAME;
3446       x_token_table(2).TOKEN_NAME := 'UK1_NAME';
3447       x_token_table(2).TOKEN_VALUE := l_uk_attr_names_table(1);
3448       x_token_table(3).TOKEN_NAME := 'ATTR1_VALUE';
3449       x_token_table(3).TOKEN_VALUE := l_uk_attr_values_table(1);
3450       x_token_table(4).TOKEN_NAME := 'UK2_NAME';
3451       x_token_table(4).TOKEN_VALUE := l_uk_attr_names_table(2);
3452       x_token_table(5).TOKEN_NAME := 'ATTR2_VALUE';
3453       x_token_table(5).TOKEN_VALUE := l_uk_attr_values_table(2);
3454       x_token_table(6).TOKEN_NAME := 'UK3_NAME';
3455       x_token_table(6).TOKEN_VALUE := l_uk_attr_names_table(3);
3456       x_token_table(7).TOKEN_NAME := 'ATTR3_VALUE';
3457       x_token_table(7).TOKEN_VALUE := l_uk_attr_values_table(3);
3458       x_token_table(8).TOKEN_NAME := 'UK4_NAME';
3459       x_token_table(8).TOKEN_VALUE := l_uk_attr_names_table(4);
3460       x_token_table(9).TOKEN_NAME := 'ATTR4_VALUE';
3461       x_token_table(9).TOKEN_VALUE := l_uk_attr_values_table(4);
3462       x_token_table(10).TOKEN_NAME := 'UK5_NAME';
3463       x_token_table(10).TOKEN_VALUE := l_uk_attr_names_table(5);
3464       x_token_table(11).TOKEN_NAME := 'ATTR5_VALUE';
3465       x_token_table(11).TOKEN_VALUE := l_uk_attr_values_table(5);
3466 
3467     ELSE
3468 
3469       x_unique_key_err_msg := 'EGO_EF_LONG_UK_VIOLATION';
3470 
3471       x_token_table(1).TOKEN_NAME := 'AG_NAME';
3472       x_token_table(1).TOKEN_VALUE := p_attr_group_metadata_obj.ATTR_GROUP_DISP_NAME;
3473       x_token_table(2).TOKEN_NAME := 'UK_NAME_LIST';
3474       x_token_table(2).TOKEN_VALUE := Fetch_UK_Attr_Names_List(l_uk_attr_names_table);
3475 
3476     END IF;
3477 
3478 END Get_Err_Info_For_UK_Violation;
3479 
3480 ----------------------------------------------------------------------
3481 
3482 PROCEDURE Get_Extension_Id_And_Mode (
3483         p_attr_group_metadata_obj       IN   EGO_ATTR_GROUP_METADATA_OBJ
3484        ,p_ext_table_metadata_obj        IN   EGO_EXT_TABLE_METADATA_OBJ
3485        ,p_pk_column_name_value_pairs    IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
3486        ,p_data_level                    IN   VARCHAR2   DEFAULT NULL --R12C
3487        ,p_data_level_name_value_pairs   IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
3488        ,p_attr_name_value_pairs         IN   EGO_USER_ATTR_DATA_TABLE
3489        ,p_extension_id                  IN   NUMBER     DEFAULT NULL
3490        ,p_mode                          IN   VARCHAR2   DEFAULT NULL
3491        ,p_change_obj                    IN   EGO_USER_ATTR_CHANGE_OBJ DEFAULT NULL
3492        ,p_extra_pk_col_name_val_pairs IN   EGO_COL_NAME_VALUE_PAIR_ARRAY DEFAULT NULL
3493        ,p_pending_b_table_name          IN   VARCHAR2   DEFAULT NULL
3494        ,p_pending_vl_name               IN   VARCHAR2   DEFAULT NULL
3495        ,p_entity_id                     IN   VARCHAR2   DEFAULT NULL
3496        ,p_entity_index                  IN   NUMBER     DEFAULT NULL
3497        ,p_entity_code                   IN   VARCHAR2   DEFAULT NULL
3498        ,x_extension_id                  OUT NOCOPY NUMBER
3499        ,x_mode                          OUT NOCOPY VARCHAR2
3500        ,x_return_status                 OUT NOCOPY VARCHAR2
3501 ) IS
3502 
3503     l_api_name               CONSTANT VARCHAR2(30) := 'Get_Extension_Id_And_Mode';
3504 
3505     l_is_change_case         BOOLEAN;
3506     l_extra_pk_present       BOOLEAN;
3507     l_production_ext_id      NUMBER;
3508     l_pending_ext_id         NUMBER;
3509     l_error_message_name     VARCHAR2(30);
3510     l_token_table            ERROR_HANDLER.Token_Tbl_Type;
3511 
3512   BEGIN
3513 
3514     Debug_Msg('In Get_Extension_Id_And_Mode, starting with p_mode as '||p_mode||' and p_extension_id as '||p_extension_id, 2);
3515 
3516 Debug_Msg('In Get_Extension_Id_And_Mode,  p_data_level='||p_data_level);
3517 
3518     --------------------------------------------------------------
3519     -- In this section we try to find extension IDs for the row --
3520     -- whose data we have in both the production table and, if  --
3521     -- appropriate, in the pending table; this effort serves as --
3522     -- the Unique Key check for multi-row Attribute Groups and  --
3523     -- will also allow us to determine (or validate) the mode.  --
3524     --------------------------------------------------------------
3525     l_is_change_case := (p_change_obj IS NOT NULL);
3526 
3527     l_production_ext_id := Get_Extension_Id_For_Row(
3528                              p_attr_group_metadata_obj     => p_attr_group_metadata_obj
3529                             ,p_ext_table_metadata_obj      => p_ext_table_metadata_obj
3530                             ,p_pk_column_name_value_pairs  => p_pk_column_name_value_pairs
3531                             ,p_data_level                  => p_data_level
3532                             ,p_data_level_name_value_pairs => p_data_level_name_value_pairs
3533                             ,p_attr_name_value_pairs       => p_attr_name_value_pairs
3534                            );
3535 
3536     IF (l_is_change_case) THEN
3537 
3538       l_pending_ext_id := Get_Extension_Id_For_Row(
3539                             p_attr_group_metadata_obj     => p_attr_group_metadata_obj
3540                            ,p_ext_table_metadata_obj      => p_ext_table_metadata_obj
3541                            ,p_pk_column_name_value_pairs  => p_pk_column_name_value_pairs
3542                            ,p_data_level                  => p_data_level
3543                            ,p_data_level_name_value_pairs => p_data_level_name_value_pairs
3544                            ,p_attr_name_value_pairs       => p_attr_name_value_pairs
3545                            ,p_change_obj                  => p_change_obj
3546                            ,p_pending_b_table_name        => p_pending_b_table_name
3547                            ,p_pending_vl_name             => p_pending_vl_name
3548                           );
3549 
3550     END IF;
3551 
3552     l_extra_pk_present := (p_extra_pk_col_name_val_pairs IS NOT NULL);
3553 
3554 
3555     IF (l_extra_pk_present) THEN
3556 
3557       l_pending_ext_id := Get_Extension_Id_For_Row(
3558                             p_attr_group_metadata_obj     => p_attr_group_metadata_obj
3559                            ,p_ext_table_metadata_obj      => p_ext_table_metadata_obj
3560                            ,p_pk_column_name_value_pairs  => p_pk_column_name_value_pairs
3561                            ,p_data_level                  => p_data_level
3562                            ,p_data_level_name_value_pairs => p_data_level_name_value_pairs
3563                            ,p_attr_name_value_pairs       => p_attr_name_value_pairs
3564                            ,p_change_obj                  => p_change_obj
3565                            ,p_extra_pk_col_name_val_pairs => p_extra_pk_col_name_val_pairs
3566                            ,p_pending_b_table_name        => p_pending_b_table_name
3567                            ,p_pending_vl_name             => p_pending_vl_name
3568                           );
3569 
3570       -- Here we are assuming that the extension_id passed is the correct one even though
3571       -- we cannot find it in the pending table. This was a specific requirement raised by
3572       -- CM where they do not save the UK's which are not changed in the pending table and
3573       -- hence they want this check to be overlooked.
3574       -- GNANDA
3575       IF (p_attr_group_metadata_obj.MULTI_ROW_CODE = 'Y' AND
3576           l_pending_ext_id IS NULL AND
3577           p_extension_id IS NOT NULL) THEN
3578           l_pending_ext_id := p_extension_id;
3579       END IF;
3580 
3581 
3582 
3583     END IF;
3584 
3585     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);
3586 
3587     IF (p_attr_group_metadata_obj.MULTI_ROW_CODE = 'N') THEN
3588       IF (p_extension_id IS NOT NULL) THEN
3589 
3590         x_extension_id := p_extension_id;
3591 
3592       ELSE
3593 
3594         -----------------------------------------------------
3595         -- If we're inserting into the pending table a row --
3596         -- that comes from a production row, we'll want to --
3597         -- preserve the production row's extension ID      --
3598         -----------------------------------------------------
3599         IF (l_is_change_case AND
3600             p_mode = G_CREATE_MODE AND
3601             p_change_obj.ACD_TYPE <> 'ADD') THEN
3602 
3603           x_extension_id := l_production_ext_id;
3604 
3605         END IF;
3606       END IF;
3607     ELSIF (p_attr_group_metadata_obj.MULTI_ROW_CODE = 'Y') THEN
3608       IF (p_extension_id IS NOT NULL) THEN
3609 
3610         IF (p_mode = G_DELETE_MODE OR
3611             (l_is_change_case AND p_change_obj.ACD_TYPE = 'DELETE')) THEN
3612 
3613           ------------------------------------------------------------
3614           -- If user is trying to delete from the UI, we don't want --
3615           -- to worry about Unique Key violations; we just want to  --
3616           -- delete whatever row the user tells us to delete        --
3617           ------------------------------------------------------------
3618           x_extension_id := p_extension_id;
3619 
3620         ELSE
3621 
3622           ----------------------------------------------------------------------------
3623           -- If the extension ID is passed in and the Attribute Group is multi-row, --
3624           -- then we have to ensure that the values we'll be updating won't result  --
3625           -- in a Unique Key violation.  So we check to ensure that a row like the  --
3626           -- passed-in row doesn't exist in the production table (and, if we're in  --
3627           -- change case, we check the pending table as well).  If we get an ext ID --
3628           -- for either table that's not the same as the passed-in ext ID, we raise --
3629           -- an error.  If, on the other hand, whatever ext IDs we find match the   --
3630           -- passed-in ext ID, that just means we found the row that the user wants --
3631           -- to update, so we have no problem.  Likewise, if we don't find any ext  --
3632           -- IDs, that means the user is changing Unique Key values to some new and --
3633           -- still-unique combination, in which case we accept the passed-in ext ID --
3634           ----------------------------------------------------------------------------
3635           IF ((l_production_ext_id IS NOT NULL AND
3636                l_production_ext_id <> p_extension_id) OR
3637               (l_pending_ext_id IS NOT NULL AND
3638                l_pending_ext_id <> p_extension_id)) THEN
3639 
3640             IF (p_attr_group_metadata_obj.UNIQUE_KEY_ATTRS_COUNT > 0) THEN
3641 
3642               -----------------------------------------------
3643               -- If we found more than one row, the Unique --
3644               -- Key is not respected in the current data  --
3645               -----------------------------------------------
3646               IF (l_production_ext_id = -1 OR
3647                   l_pending_ext_id = -1) THEN
3648 
3649                 Get_Err_Info_For_UK_Not_Resp(p_attr_group_metadata_obj
3650                                             ,(l_production_ext_id = -1)
3651                                             ,l_error_message_name
3652                                             ,l_token_table);
3653 
3654               -----------------------------------------------------------------
3655               -- If, on the other hand, we found exactly one row, the Unique --
3656               -- Key is respected but the current row would violate it       --
3657               -----------------------------------------------------------------
3658               ELSE
3659 
3660                 Get_Err_Info_For_UK_Violation(p_attr_group_metadata_obj
3661                                              ,p_attr_name_value_pairs
3662                                              ,(l_production_ext_id IS NOT NULL)
3663                                              ,l_error_message_name
3664                                              ,l_token_table);
3665 
3666               END IF;
3667 
3668             ELSE
3669 
3670               l_error_message_name := 'EGO_EF_NO_UNIQUE_KEY';
3671 
3672               l_token_table(1).TOKEN_NAME := 'AG_NAME';
3673               l_token_table(1).TOKEN_VALUE := p_attr_group_metadata_obj.ATTR_GROUP_DISP_NAME;
3674 
3675             END IF;
3676 
3677           ----------------------------------------------------------
3678           -- As mentioned above, if both are null then we assume  --
3679           -- that we're changing UK values and that the passed-in --
3680           -- ext ID must be the correct ext ID to do so           --
3681           ----------------------------------------------------------
3682           ELSIF (l_production_ext_id IS NULL AND
3683                  l_pending_ext_id IS NULL) THEN
3684 
3685             x_extension_id := p_extension_id;
3686 
3687           END IF;
3688         END IF;
3689       ELSE
3690 
3691         -------------------------------------------------------------------------
3692         -- In this case the extension IDs we fetched will determine whether we --
3693         -- are inserting or updating--and, if the latter, which row we update. --
3694         -------------------------------------------------------------------------
3695         IF (l_production_ext_id IS NOT NULL OR
3696             l_pending_ext_id IS NOT NULL) THEN
3697 
3698           -------------------------------------------------------------------------
3699           -- If we found more than one row in either table (signaled by the -1)  --
3700           -- then we either have no Unique Key or one that's not respected       --
3701           -------------------------------------------------------------------------
3702           IF (l_production_ext_id = -1 OR
3703               l_pending_ext_id = -1) THEN
3704 
3705             IF (p_attr_group_metadata_obj.UNIQUE_KEY_ATTRS_COUNT > 0) THEN
3706 
3707               ----------------------------------------------------------
3708               -- If we found more than one row, the Unique Key is not --
3709               -- respected in the current data in at least one table  --
3710               ----------------------------------------------------------
3711               Get_Err_Info_For_UK_Not_Resp(p_attr_group_metadata_obj
3712                                           ,(l_production_ext_id = -1)
3713                                           ,l_error_message_name
3714                                           ,l_token_table);
3715 
3716 
3717             ELSE
3718 
3719               l_error_message_name := 'EGO_EF_NO_UNIQUE_KEY';
3720 
3721               l_token_table(1).TOKEN_NAME := 'AG_NAME';
3722               l_token_table(1).TOKEN_VALUE := p_attr_group_metadata_obj.ATTR_GROUP_DISP_NAME;
3723 
3724             END IF;
3725 
3726           ---------------------------------------------------------
3727           -- If the mode is 'CREATE', then the current row would --
3728           -- violate the UK if any of the following applies:     --
3729           -- * user is inserting into the pending table and      --
3730           --   + there's already a row in the pending table, or  --
3731           --   + the ACD type is also 'CREATE', and there's      --
3732           --     already a row in the production table           --
3733           -- * user is inserting into the production table and   --
3734           --   there's already a row in the production table     --
3735           ---------------------------------------------------------
3736           ELSIF (p_mode = G_CREATE_MODE AND
3737                  ((l_is_change_case AND
3738                    (l_pending_ext_id IS NOT NULL OR
3739                     (p_change_obj.ACD_TYPE = 'ADD' AND
3740                      l_production_ext_id IS NOT NULL))) OR
3741                   ((NOT l_is_change_case AND NOT l_extra_pk_present) AND
3742                    l_production_ext_id IS NOT NULL))) THEN
3743 
3744             IF (p_attr_group_metadata_obj.UNIQUE_KEY_ATTRS_COUNT > 0) THEN
3745 
3746               -------------------------------------------------------
3747               -- If we found an ext ID for at least one table, the --
3748               -- Unique Key would be violated by adding this row   --
3749               -------------------------------------------------------
3750               Get_Err_Info_For_UK_Violation(p_attr_group_metadata_obj
3751                                            ,p_attr_name_value_pairs
3752                                            ,(l_pending_ext_id IS NULL)
3753                                            ,l_error_message_name
3754                                            ,l_token_table);
3755 
3756             ELSE
3757 
3758               l_error_message_name := 'EGO_EF_NO_UK_FOR_CREATE';
3759 
3760               l_token_table(1).TOKEN_NAME := 'AG_NAME';
3761               l_token_table(1).TOKEN_VALUE := p_attr_group_metadata_obj.ATTR_GROUP_DISP_NAME;
3762 
3763             END IF;
3764           END IF;
3765         END IF;
3766       END IF;
3767     END IF;
3768 
3769     ------------------------------------------------------------------------
3770     -- Whatever error message we built in the preceding lines, we now log --
3771     ------------------------------------------------------------------------
3772     IF (l_error_message_name IS NOT NULL) THEN
3773 
3774       ERROR_HANDLER.Add_Error_Message(
3775         p_message_name      => l_error_message_name
3776        ,p_application_id    => 'EGO'
3777        ,p_token_tbl         => l_token_table
3778        ,p_message_type      => FND_API.G_RET_STS_ERROR
3779        ,p_row_identifier    => G_USER_ROW_IDENTIFIER
3780        ,p_entity_id         => p_entity_id
3781        ,p_entity_index      => p_entity_index
3782        ,p_entity_code       => p_entity_code
3783        ,p_addto_fnd_stack   => G_ADD_ERRORS_TO_FND_STACK
3784       );
3785 
3786       RAISE FND_API.G_EXC_ERROR;
3787     ELSIF (x_extension_id IS NULL) THEN
3788       --------------------------------------------------------------------
3789       -- If there was no error and we don't yet have the ext ID, set it --
3790       -- based on the table on which the user is trying to perform DML  --
3791       --------------------------------------------------------------------
3792       IF (l_is_change_case OR l_extra_pk_present) THEN
3793         x_extension_id := l_pending_ext_id;
3794       ELSE
3795         x_extension_id := l_production_ext_id;
3796       END IF;
3797     END IF;
3798 
3799     --------------------------------------------------------------------------
3800     -- If the caller didn't pass a mode, we behave as if we're in SYNC mode --
3801     --------------------------------------------------------------------------
3802     IF (p_mode IS NOT NULL AND
3803         UPPER(p_mode) <> G_SYNC_MODE) THEN
3804       x_mode := UPPER(p_mode);
3805     ELSE
3806       IF (x_extension_id IS NULL) THEN
3807         x_mode := G_CREATE_MODE;
3808       ELSE
3809         x_mode := G_UPDATE_MODE;
3810       END IF;
3811     END IF;
3812 
3813     ------------------------------------------------------------------
3814     -- If we don't have an extension ID at this point, then either  --
3815     -- we are in CREATE mode or there's an error somewhere.  If, on --
3816     -- the other hand, we *do* have an extension ID and the mode is --
3817     -- CREATE, that's also an error (unless we're in Change mode,   --
3818     -- in which case we sometimes take in an extension ID)          --
3819     ------------------------------------------------------------------
3820     IF (x_extension_id IS NULL AND x_mode <> G_CREATE_MODE) THEN
3821 
3822       l_error_message_name := 'EGO_EF_ROW_NOT_FOUND';
3823 
3824       l_token_table(1).TOKEN_NAME := 'AG_NAME';
3825       l_token_table(1).TOKEN_VALUE := p_attr_group_metadata_obj.ATTR_GROUP_DISP_NAME;
3826 
3827       ERROR_HANDLER.Add_Error_Message(
3828         p_message_name      => l_error_message_name
3829        ,p_application_id    => 'EGO'
3830        ,p_token_tbl         => l_token_table
3831        ,p_message_type      => FND_API.G_RET_STS_ERROR
3832        ,p_row_identifier    => G_USER_ROW_IDENTIFIER
3833        ,p_entity_id         => p_entity_id
3834        ,p_entity_index      => p_entity_index
3835        ,p_entity_code       => p_entity_code
3836        ,p_addto_fnd_stack   => G_ADD_ERRORS_TO_FND_STACK
3837       );
3838 
3839       RAISE FND_API.G_EXC_ERROR;
3840 
3841     ELSIF (x_extension_id IS NOT NULL AND
3842            x_mode = G_CREATE_MODE AND
3843            (NOT l_is_change_case OR p_change_obj.ACD_TYPE = 'ADD')) THEN
3844 
3845       l_error_message_name := 'EGO_EF_ROW_ALREADY_EXISTS';
3846 
3847       l_token_table(1).TOKEN_NAME := 'AG_NAME';
3848       l_token_table(1).TOKEN_VALUE := p_attr_group_metadata_obj.ATTR_GROUP_DISP_NAME;
3849 
3850       ERROR_HANDLER.Add_Error_Message(
3851         p_message_name      => l_error_message_name
3852        ,p_application_id    => 'EGO'
3853        ,p_token_tbl         => l_token_table
3854        ,p_message_type      => FND_API.G_RET_STS_ERROR
3855        ,p_row_identifier    => G_USER_ROW_IDENTIFIER
3856        ,p_entity_id         => p_entity_id
3857        ,p_entity_index      => p_entity_index
3858        ,p_entity_code       => p_entity_code
3859        ,p_addto_fnd_stack   => G_ADD_ERRORS_TO_FND_STACK
3860       );
3861 
3862       RAISE FND_API.G_EXC_ERROR;
3863 
3864     END IF;
3865 
3866     ----------------------------------------------------------------------
3867     -- There is one circumstance (coming from Implement_Change_Line) in --
3868     -- which we take in an extension ID but want to operate in CREATE   --
3869     -- mode; to pass our error checks, we use G_IMPLEMENT_CREATE_MODE   --
3870     ----------------------------------------------------------------------
3871     IF (x_mode = G_IMPLEMENT_CREATE_MODE) THEN
3872       x_mode := G_CREATE_MODE;
3873     END IF;
3874 
3875     ----------------------------------------------------------------------
3876     -- If we're bulkloading, we don't accept empty rows in CREATE mode; --
3877     -- from the UI we do, because there are cases (e.g., seeded AGs) in --
3878     -- which other teams' code always assumes that a join to our tables --
3879     -- will succeed (even if there's no data in our tables)             --
3880     ----------------------------------------------------------------------
3881     IF (x_mode = G_CREATE_MODE AND
3882         All_Attr_Values_Are_Null(p_attr_name_value_pairs) AND
3883         G_BULK_PROCESSING_FLAG) THEN
3884 
3885       l_error_message_name := 'EGO_EF_NO_ATTR_VALS_TO_INSERT';
3886 
3887       l_token_table(1).TOKEN_NAME := 'AG_NAME';
3888       l_token_table(1).TOKEN_VALUE := p_attr_group_metadata_obj.ATTR_GROUP_DISP_NAME;
3889 
3890       ERROR_HANDLER.Add_Error_Message(
3891         p_message_name      => l_error_message_name
3892        ,p_application_id    => 'EGO'
3893        ,p_token_tbl         => l_token_table
3894        ,p_message_type      => FND_API.G_RET_STS_ERROR
3895        ,p_row_identifier    => G_USER_ROW_IDENTIFIER
3896        ,p_entity_id         => p_entity_id
3897        ,p_entity_index      => p_entity_index
3898        ,p_entity_code       => p_entity_code
3899        ,p_addto_fnd_stack   => G_ADD_ERRORS_TO_FND_STACK
3900       );
3901 
3902       RAISE FND_API.G_EXC_ERROR;
3903 
3904     END IF;
3905     Debug_Msg('In Get_Extension_Id_And_Mode, done', 2);
3906 
3907   EXCEPTION
3908     WHEN FND_API.G_EXC_ERROR THEN
3909       Debug_Msg(' Get_Extension_Id_And_Mode EXCEPTION FND_API.G_EXC_ERROR ');
3910       x_return_status := FND_API.G_RET_STS_ERROR;
3911 
3912     WHEN OTHERS THEN
3913 
3914       Debug_Msg(' Get_Extension_Id_And_Mode EXCEPTION OTHERS '||SQLERRM);
3915       x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
3916 
3917       l_token_table.DELETE();
3918       l_token_table(1).TOKEN_NAME := 'PKG_NAME';
3919       l_token_table(1).TOKEN_VALUE := G_PKG_NAME;
3920       l_token_table(2).TOKEN_NAME := 'API_NAME';
3921       l_token_table(2).TOKEN_VALUE := l_api_name;
3922       l_token_table(3).TOKEN_NAME := 'SQL_ERR_MSG';
3923       l_token_table(3).TOKEN_VALUE := SQLERRM;
3924 
3925       ERROR_HANDLER.Add_Error_Message(
3926         p_message_name      => 'EGO_PLSQL_ERR'
3927        ,p_application_id    => 'EGO'
3928        ,p_token_tbl         => l_token_table
3929        ,p_message_type      => FND_API.G_RET_STS_ERROR
3930        ,p_row_identifier    => G_USER_ROW_IDENTIFIER
3931        ,p_entity_id         => p_entity_id
3932        ,p_entity_index      => p_entity_index
3933        ,p_entity_code       => p_entity_code
3934        ,p_addto_fnd_stack   => G_ADD_ERRORS_TO_FND_STACK
3935       );
3936 
3937 END Get_Extension_Id_And_Mode;
3938 
3939 ----------------------------------------------------------------------
3940 
3941 FUNCTION Do_All_Attrs_Exist (
3942         p_attr_group_metadata_obj       IN   EGO_ATTR_GROUP_METADATA_OBJ
3943        ,p_attr_name_value_pairs         IN   EGO_USER_ATTR_DATA_TABLE
3944        ,p_entity_id                     IN   VARCHAR2
3945        ,p_entity_index                  IN   NUMBER
3946        ,p_entity_code                   IN   VARCHAR2
3947 )
3948 RETURN BOOLEAN
3949 IS
3950 
3951     l_token_table            ERROR_HANDLER.Token_Tbl_Type;
3952     l_attr_count             NUMBER;
3953     l_attr_metadata_obj      EGO_ATTR_METADATA_OBJ;
3954     l_all_exist              BOOLEAN := TRUE;
3955 
3956   BEGIN
3957 
3958     Debug_Msg('In Do_All_Attrs_Exist, starting', 2);
3959 
3960     l_token_table(1).TOKEN_NAME := 'BAD_ATTR_NAME';
3961     -- the token value will be set every time we find a missing Attr
3962     l_token_table(2).TOKEN_NAME := 'AG_NAME';
3963     l_token_table(2).TOKEN_VALUE := p_attr_group_metadata_obj.ATTR_GROUP_NAME;
3964 
3965     IF (p_attr_name_value_pairs IS NOT NULL AND
3966         p_attr_name_value_pairs.COUNT > 0) THEN
3967       l_attr_count := p_attr_name_value_pairs.FIRST;
3968       WHILE (l_attr_count <= p_attr_name_value_pairs.LAST)
3969       LOOP
3970 
3971         l_attr_metadata_obj := EGO_USER_ATTRS_COMMON_PVT.Find_Metadata_For_Attr(
3972                                  p_attr_metadata_table => p_attr_group_metadata_obj.attr_metadata_table
3973                                 ,p_attr_name           => p_attr_name_value_pairs(l_attr_count).ATTR_NAME
3974                                );
3975         IF (l_attr_metadata_obj IS NULL OR
3976             l_attr_metadata_obj.ATTR_NAME IS NULL) THEN
3977 
3978           --------------------------------------------------------------------
3979           -- If we can't find metadata for this Attribute, report the error --
3980           --------------------------------------------------------------------
3981           l_all_exist := FALSE;
3982 
3983           l_token_table(1).TOKEN_VALUE := p_attr_name_value_pairs(l_attr_count).ATTR_NAME;
3984 
3985           ERROR_HANDLER.Add_Error_Message(
3986             p_message_name      => 'EGO_EF_ATTR_DOES_NOT_EXIST'
3987            ,p_application_id    => 'EGO'
3988            ,p_token_tbl         => l_token_table
3989            ,p_message_type      => FND_API.G_RET_STS_ERROR
3990            ,p_row_identifier    => G_USER_ROW_IDENTIFIER
3991            ,p_entity_id         => p_entity_id
3992            ,p_entity_index      => p_entity_index
3993            ,p_entity_code       => p_entity_code
3994            ,p_addto_fnd_stack   => G_ADD_ERRORS_TO_FND_STACK
3995           );
3996 
3997         END IF;
3998 
3999         l_attr_count := p_attr_name_value_pairs.NEXT(l_attr_count);
4000       END LOOP;
4001     END IF;
4002 
4003     Debug_Msg('In Do_All_Attrs_Exist, done', 2);
4004 
4005     RETURN l_all_exist;
4006 
4007 END Do_All_Attrs_Exist;
4008 
4009 ----------------------------------------------------------------------
4010 
4011 
4012 FUNCTION Are_These_Col_Names_Right (
4013         p_ext_table_col_metadata        IN   EGO_COL_METADATA_ARRAY
4014        ,p_col_name_value_pairs          IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
4015 )
4016 RETURN BOOLEAN
4017 IS
4018 
4019     l_name_value_pair_index  NUMBER;
4020     l_col_metadata_obj       EGO_COL_METADATA_OBJ;
4021     l_col_name_candidate     VARCHAR2(30);
4022     l_are_names_right        BOOLEAN := TRUE;
4023     l_found_this_col_name    BOOLEAN := FALSE;
4024 
4025   BEGIN
4026 
4027     Debug_Msg('In Are_These_Col_Names_Right, starting');
4028 
4029     --------------------------------------------------------------
4030     -- Loop through the name/value pair array: for every column --
4031     -- name, look in the extension table metadata column list   --
4032     -- to find a match.  If we don't find a match, we return    --
4033     -- FALSE; if we find matches for all the columns in the     --
4034     -- name/value pair list, we return TRUE.  If the name/value --
4035     -- pair array is null or empty, it passes.                  --
4036     --------------------------------------------------------------
4037     IF (p_col_name_value_pairs IS NOT NULL AND
4038         p_col_name_value_pairs.COUNT > 0) THEN
4039 
4040       l_name_value_pair_index := p_col_name_value_pairs.FIRST;
4041       WHILE (l_name_value_pair_index <= p_col_name_value_pairs.LAST)
4042       LOOP
4043         EXIT WHEN (NOT l_are_names_right);
4044 
4045         l_col_name_candidate := p_col_name_value_pairs(l_name_value_pair_index).NAME;
4046         l_found_this_col_name := FALSE;
4047 
4048         -----------------------------------------------------
4049         -- If we can find this candidate or if it's a list --
4050         -- of related classification codes, we pass it     --
4051         -----------------------------------------------------
4052         IF (INSTR(UPPER(l_col_name_candidate), 'RELATED_CLASS_CODE_LIST') <> 0) THEN
4053 
4054           l_found_this_col_name := TRUE;
4055 
4056         ELSE
4057 
4058           l_col_metadata_obj := Find_Metadata_For_Col(p_ext_table_col_metadata
4059                                                      ,l_col_name_candidate);
4060           l_found_this_col_name := (l_col_metadata_obj IS NOT NULL);
4061 
4062         END IF;
4063 
4064         l_are_names_right := l_found_this_col_name;
4065 
4066         IF (NOT l_are_names_right) THEN
4067           Debug_Msg('In Are_These_Col_Names_Right, unidentified column name is: '||l_col_name_candidate);
4068         END IF;
4069 
4070         l_name_value_pair_index := p_col_name_value_pairs.NEXT(l_name_value_pair_index);
4071       END LOOP;
4072     END IF;
4073 
4074     IF (l_are_names_right) THEN
4075       Debug_Msg('In Are_These_Col_Names_Right, returning TRUE');
4076     ELSE
4077       Debug_Msg('In Are_These_Col_Names_Right, returning FALSE');
4078     END IF;
4079 
4080     RETURN l_are_names_right;
4081 
4082 END Are_These_Col_Names_Right;
4083 
4084 ----------------------------------------------------------------------
4085 
4086 FUNCTION Are_Ext_Table_Col_Names_Right (
4087         p_ext_table_metadata_obj        IN   EGO_EXT_TABLE_METADATA_OBJ
4088        ,p_pk_column_name_value_pairs    IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
4089        ,p_class_code_name_value_pairs   IN   EGO_COL_NAME_VALUE_PAIR_ARRAY DEFAULT NULL
4090 )
4091 RETURN BOOLEAN
4092 IS
4093 
4094     l_are_names_right        BOOLEAN := TRUE;
4095 
4096   BEGIN
4097 
4098     Debug_Msg('In Are_Ext_Table_Col_Names_Right, starting', 2);
4099 
4100     l_are_names_right := Are_These_Col_Names_Right(p_ext_table_metadata_obj.pk_column_metadata
4101                                                   ,p_pk_column_name_value_pairs);
4102 
4103     IF (l_are_names_right AND
4104         p_class_code_name_value_pairs IS NOT NULL) THEN
4105       l_are_names_right := Are_These_Col_Names_Right(p_ext_table_metadata_obj.class_code_metadata
4106                                                     ,p_class_code_name_value_pairs);
4107     END IF;
4108 
4109     IF (l_are_names_right) THEN
4110       Debug_Msg('In Are_Ext_Table_Col_Names_Right, done; returning TRUE', 2);
4111     ELSE
4112       Debug_Msg('In Are_Ext_Table_Col_Names_Right, done; returning FALSE', 2);
4113     END IF;
4114 
4115     RETURN l_are_names_right;
4116 
4117   EXCEPTION
4118     WHEN OTHERS THEN
4119       Debug_Msg(' Are_Ext_Table_Col_Names_Right EXCEPTION OTHERS '||SQLERRM);
4120       RETURN FALSE;
4121 
4122 END Are_Ext_Table_Col_Names_Right;
4123 
4124 ----------------------------------------------------------------------
4125 
4126 FUNCTION Is_Data_Level_Correct (
4127         p_object_id                     IN   NUMBER
4128        ,p_attr_group_id                 IN   NUMBER
4129        ,p_ext_table_metadata_obj        IN   EGO_EXT_TABLE_METADATA_OBJ
4130        ,p_class_code_name_value_pairs   IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
4131        ,p_data_level                    IN   VARCHAR2   DEFAULT NULL --R12C
4132        ,p_data_level_name_value_pairs   IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
4133        ,p_attr_group_disp_name          IN   VARCHAR2
4134        ,x_err_msg_name                  OUT NOCOPY VARCHAR2
4135        ,x_token_table                   OUT NOCOPY ERROR_HANDLER.Token_Tbl_Type
4136 )
4137 RETURN BOOLEAN IS
4138 
4139     l_api_name                VARCHAR2(50) := 'Is_Data_Level_Correct';
4140     l_cursor_id               NUMBER;
4141     l_dummy                   NUMBER;
4142     l_obj_and_class           VARCHAR2(1100);
4143     l_data_level              EGO_OBJ_AG_ASSOCS_B.DATA_LEVEL%TYPE;
4144     l_data_level_id           NUMBER;
4145     l_is_data_level_correct   BOOLEAN := TRUE;
4146     l_cc_value_list           VARCHAR2(1000);
4147     l_dynamic_sql             VARCHAR2(5500);
4148     l_data_level_index        NUMBER;
4149     l_data_level_progress_point VARCHAR2(10);
4150     l_wrong_data_level        VARCHAR2(80);
4151     l_attr_group_metadata_obj EGO_ATTR_GROUP_METADATA_OBJ;
4152     l_enabled_data_level_table EGO_DATA_LEVEL_TABLE;
4153     l_data_level_metadata      EGO_DATA_LEVEL_METADATA_OBJ;
4154     l_column_matched           BOOLEAN;
4155     l_data_level_matched       BOOLEAN;
4156     l_dl_pk_col_list           VARCHAR2(200);
4157 
4158     l_data_level_list    VARCHAR2(5000);
4159     l_start_index        NUMBER;
4160     l_end_index          NUMBER;
4161 
4162   BEGIN
4163 
4164     Debug_Msg(l_api_name || ' starting with p_data_level '||p_data_level, 2);
4165 
4166     -----------------------------------------------------------------
4167     -- If data level has been provided we need to verify it from   --
4168     -- the metadata.                                               --
4169     -----------------------------------------------------------------
4170     IF (p_data_level IS NOT NULL) THEN
4171 
4172       l_data_level_matched := FALSE;
4173       l_attr_group_metadata_obj := EGO_USER_ATTRS_COMMON_PVT.Get_Attr_Group_Metadata
4174                                           (p_attr_group_id  =>  p_attr_group_id);
4175       l_enabled_data_level_table := l_attr_group_metadata_obj.ENABLED_DATA_LEVELS;
4176 
4177       FOR i IN l_enabled_data_level_table.FIRST .. l_enabled_data_level_table.LAST
4178       LOOP
4179         IF(l_enabled_data_level_table(i).DATA_LEVEL_NAME = p_data_level) THEN
4180           l_data_level_metadata := EGO_USER_ATTRS_COMMON_PVT.get_data_level_metadata(
4181                                        p_data_level_id => l_enabled_data_level_table(i).DATA_LEVEL_ID
4182                                                                                     );
4183           l_data_level_matched := TRUE;
4184           l_column_matched := TRUE;
4185           l_dl_pk_col_list := '';
4186           IF p_data_level_name_value_pairs IS NOT NULL AND p_data_level_name_value_pairs.COUNT > 0 THEN
4187             FOR j IN p_data_level_name_value_pairs.FIRST .. p_data_level_name_value_pairs.LAST
4188             LOOP
4189                --Each col in the provided dl pk col list should be valid
4190                IF(    p_data_level_name_value_pairs(j).NAME <> l_data_level_metadata.PK_COLUMN_NAME1
4191                   AND p_data_level_name_value_pairs(j).NAME <> l_data_level_metadata.PK_COLUMN_NAME2
4192                   AND p_data_level_name_value_pairs(j).NAME <> l_data_level_metadata.PK_COLUMN_NAME3
4193                   AND p_data_level_name_value_pairs(j).NAME <> l_data_level_metadata.PK_COLUMN_NAME4
4194                   AND p_data_level_name_value_pairs(j).NAME <> l_data_level_metadata.PK_COLUMN_NAME5) THEN
4195                  l_column_matched:= FALSE;
4196                END IF;
4197                l_dl_pk_col_list := l_dl_pk_col_list||' '||p_data_level_name_value_pairs(j).NAME;
4198             END LOOP;
4199 
4200             -- All the pk columns should be present in the provided DL columns list.
4201             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)
4202                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)
4203                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)
4204                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)
4205                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)
4206               ) THEN
4207                  l_column_matched:= FALSE;
4208             END IF;
4209           END IF;
4210 
4211           IF(NOT l_column_matched) THEN
4212             RETURN FALSE;
4213           END IF;
4214         END IF;   --l_enabled_data_level_table(i).DATA_LEVEL_NAME = p_data_level
4215       END LOOP;
4216 
4217       IF(l_data_level_matched AND l_column_matched) THEN
4218       --If the passed in data level is fine we check the association of the data level with the classification
4219         Init();
4220         FND_DSQL.Add_Text(' SELECT DATA_LEVEL FROM EGO_OBJ_AG_ASSOCS_B'||
4221                           '  WHERE OBJECT_ID =  ');
4222         Add_Bind(p_value => p_object_id);
4223         FND_DSQL.Add_Text('    AND ATTR_GROUP_ID = ');
4224         Add_Bind(p_value => p_attr_group_id);
4225         FND_DSQL.Add_Text('    AND ROWNUM = 1');
4226         FND_DSQL.Add_Text('    AND CLASSIFICATION_CODE IN (');
4227         l_cc_value_list := EGO_USER_ATTRS_COMMON_PVT.Get_List_For_Table_Cols(
4228                              p_ext_table_metadata_obj.class_code_metadata
4229                             ,p_class_code_name_value_pairs
4230                             ,'VALUES_ALL_CC'
4231                             ,TRUE
4232                            );
4233         FND_DSQL.Add_Text(')');
4234         l_cursor_id := DBMS_SQL.Open_Cursor;
4235         DBMS_SQL.Parse(l_cursor_id, FND_DSQL.Get_Text(), DBMS_SQL.Native);
4236         FND_DSQL.Set_Cursor(l_cursor_id);
4237         FND_DSQL.Do_Binds();
4238         DBMS_SQL.Define_Column(l_cursor_id, 1, l_data_level, 30);
4239         l_dummy := DBMS_SQL.Execute(l_cursor_id);
4240         l_dummy := DBMS_SQL.Fetch_Rows(l_cursor_id);
4241 
4242         IF (l_dummy = 0) THEN
4243            RAISE NO_DATA_FOUND;
4244         END IF;
4245 
4246         l_is_data_level_correct := TRUE;
4247       ELSE
4248         l_is_data_level_correct := FALSE;
4249       END IF;
4250 
4251     ELSE  -- p_data_level IS NULL
4252       --
4253       -- R12 code
4254       --
4255       l_cc_value_list := EGO_USER_ATTRS_COMMON_PVT.Get_List_For_Table_Cols(
4256                            p_ext_table_metadata_obj.class_code_metadata
4257                           ,p_class_code_name_value_pairs
4258                           ,'VALUES_ALL_CC'
4259                           ,FALSE
4260                          );
4261 
4262       Debug_Msg('In Is_Data_Level_Correct, got l_cc_value_list as '||l_cc_value_list);
4263 
4264       l_obj_and_class := '$'||TO_CHAR(p_object_id)||':'||l_cc_value_list||':';
4265 
4266       Debug_Msg('In Is_Data_Level_Correct, got l_obj_and_class as '||l_obj_and_class);
4267 
4268       IF (G_ASSOCIATION_DATA_LEVEL_CACHE.EXISTS(p_attr_group_id) AND
4269           INSTR(G_ASSOCIATION_DATA_LEVEL_CACHE(p_attr_group_id), l_obj_and_class) > 0) THEN
4270 
4271         Debug_Msg('In Is_Data_Level_Correct, found association '||l_obj_and_class||' in the cache');
4272          l_data_level_list := G_ASSOCIATION_DATA_LEVEL_CACHE(p_attr_group_id);
4273          l_start_index := INSTR(l_data_level_list, l_obj_and_class) + LENGTH(l_obj_and_class);
4274          l_end_index := INSTR(l_data_level_list, '$', l_start_index);
4275          l_data_level := SUBSTR(l_data_level_list, l_start_index, (l_end_index - l_start_index));
4276       ELSE
4277 
4278         Init();
4279         FND_DSQL.Add_Text(' SELECT DECODE(ATTRIBUTE2, 1, ATTRIBUTE3,'||
4280                                                     ' 2, ATTRIBUTE5,'||
4281                                                     ' 3, ATTRIBUTE7,'||
4282                                                        ' ''NONE'')'||
4283                             ' FROM FND_LOOKUP_VALUES'||
4284                            ' WHERE LOOKUP_TYPE = ''EGO_EF_DATA_LEVEL'''||
4285                  ' AND LANGUAGE = USERENV(''LANG'')'||
4286                              ' AND LOOKUP_CODE = (SELECT DATA_LEVEL'||
4287                                                   ' FROM EGO_OBJ_AG_ASSOCS_B'||
4288                                                  ' WHERE OBJECT_ID = ');
4289         Add_Bind(p_value => p_object_id);
4290         FND_DSQL.Add_Text(' AND ATTR_GROUP_ID = ');
4291         Add_Bind(p_value => p_attr_group_id);
4292         FND_DSQL.Add_Text(' AND ROWNUM = 1');
4293 
4294         IF (LENGTH(l_cc_value_list) > 0) THEN
4295           FND_DSQL.Add_Text(' AND CLASSIFICATION_CODE IN (');
4296           l_cc_value_list := EGO_USER_ATTRS_COMMON_PVT.Get_List_For_Table_Cols(
4297                                p_ext_table_metadata_obj.class_code_metadata
4298                               ,p_class_code_name_value_pairs
4299                               ,'VALUES_ALL_CC'
4300                               ,TRUE
4301                              );
4302           FND_DSQL.Add_Text(')');
4303         END IF;
4304 
4305         FND_DSQL.Add_Text(') ');
4306 
4307         Debug_Msg('Bind params for the preceding SQL: '||p_object_id||' and '||p_attr_group_id, 3);
4308 
4309         l_cursor_id := DBMS_SQL.Open_Cursor;
4310         DBMS_SQL.Parse(l_cursor_id, FND_DSQL.Get_Text(), DBMS_SQL.Native);
4311         FND_DSQL.Set_Cursor(l_cursor_id);
4312         FND_DSQL.Do_Binds();
4313         DBMS_SQL.Define_Column(l_cursor_id, 1, l_data_level, 30);
4314         l_dummy := DBMS_SQL.Execute(l_cursor_id);
4315         l_dummy := DBMS_SQL.Fetch_Rows(l_cursor_id);
4316 
4317         IF (l_dummy = 0) THEN
4318           RAISE NO_DATA_FOUND;
4319         END IF;
4320 
4321         DBMS_SQL.Column_Value(l_cursor_id, 1, l_data_level);
4322         DBMS_SQL.Close_Cursor(l_cursor_id);
4323 
4324         IF (G_ASSOCIATION_DATA_LEVEL_CACHE.EXISTS(p_attr_group_id)) THEN
4325 
4326           G_ASSOCIATION_DATA_LEVEL_CACHE(p_attr_group_id) := l_obj_and_class||
4327                                                              l_data_level||'$ '||
4328                                                              G_ASSOCIATION_DATA_LEVEL_CACHE(p_attr_group_id);
4329           Debug_Msg('In Is_Data_Level_Correct, added association '||l_obj_and_class||' to the cached list');
4330 
4331         ELSE
4332 
4333           G_ASSOCIATION_DATA_LEVEL_CACHE(p_attr_group_id) := l_obj_and_class||
4334                                                              l_data_level||'$ ';
4335 
4336           Debug_Msg('In Is_Data_Level_Correct, started cached list with association '||l_obj_and_class);
4337 
4338         END IF;
4339       END IF;
4340 
4341       Debug_Msg('In Is_Data_Level_Correct, the data level for this association is '||l_data_level);
4342 
4343       ------------------------------------------------------------------------
4344       -- At this point we have the Data Level at which this Attribute Group --
4345       -- is associated to this Object; now we need to make sure that we     --
4346       -- have values for all Data Levels up to and including this one and   --
4347       -- that we don't have values for any Data Levels past this one.       --
4348       ------------------------------------------------------------------------
4349       IF (l_data_level = 'NONE') THEN
4350         l_data_level_progress_point := 'AFTER';
4351       ELSE
4352         l_data_level_progress_point := 'BEFORE';
4353       END IF;
4354 
4355       ------------------------------------------------------------------
4356       -- If user hasn't passed in a data level array or has passed in --
4357       -- an array with a NULL first value, then NONE is the only      --
4358       -- correct value for the data level of this association         --
4359       ------------------------------------------------------------------
4360       IF (p_data_level_name_value_pairs IS NULL OR
4361           p_data_level_name_value_pairs.COUNT = 0 OR
4362           p_data_level_name_value_pairs(p_data_level_name_value_pairs.FIRST).VALUE IS NULL) THEN
4363 
4364         l_is_data_level_correct := (l_data_level = 'NONE');
4365 
4366       ELSE
4367 
4368         l_data_level_index := p_data_level_name_value_pairs.FIRST;
4369 
4370         WHILE (l_data_level_index <= p_data_level_name_value_pairs.LAST)
4371         LOOP
4372           EXIT WHEN (NOT l_is_data_level_correct);
4373 
4374           IF (p_data_level_name_value_pairs(l_data_level_index).NAME = l_data_level) THEN
4375             l_data_level_progress_point := 'AT';
4376             Debug_Msg('In Is_Data_Level_Correct, found the data level for this association at index '||
4377                       l_data_level_index||' in the passed-in DL array');
4378           END IF;
4379 
4380           IF ((l_data_level_progress_point = 'BEFORE' OR
4381                l_data_level_progress_point = 'AT') AND
4382               p_data_level_name_value_pairs(l_data_level_index).VALUE IS NULL) THEN
4383 
4384             --------------------------------------------------------------------
4385             -- If the user didn't pass a value for the current data level and --
4386             -- should have, then he/she must have been trying to process the  --
4387             -- Attr data for the data level above the current one (e.g., Item --
4388             -- instead of Item Revision, Structure instead of Component, or   --
4389             -- Project instead of Task), so we report that this is incorrect  --
4390             -- NOTE: The data level index will never be 1, because we checked --
4391             -- that case just before we entered the loop                      --
4392             --------------------------------------------------------------------
4393             IF (l_data_level_index = 2) THEN
4394               l_wrong_data_level := p_ext_table_metadata_obj.DATA_LEVEL_MEANING_1;
4395             ELSIF (l_data_level_index = 3) THEN
4396               l_wrong_data_level := p_ext_table_metadata_obj.DATA_LEVEL_MEANING_2;
4397             END IF;
4398 
4399             l_is_data_level_correct := FALSE;
4400 
4401           ELSIF (l_data_level_progress_point = 'AFTER' AND
4402                  p_data_level_name_value_pairs(l_data_level_index).VALUE IS NOT NULL) THEN
4403 
4404             ----------------------------------------------------------------------
4405             -- If, on the other hand, the user passed a data level value for    --
4406             -- some data level beyond the correct one (e.g., Item Revision when --
4407             -- trying to process Attr data for an Attr Group associated at the  --
4408             -- Item level), we report this mistake as well                      --
4409             ----------------------------------------------------------------------
4410             IF (l_data_level_index = 1) THEN
4411               l_wrong_data_level := p_ext_table_metadata_obj.DATA_LEVEL_MEANING_2;
4412             ELSIF (l_data_level_index = 2) THEN
4413               l_wrong_data_level := p_ext_table_metadata_obj.DATA_LEVEL_MEANING_3;
4414             END IF;
4415 
4416             l_is_data_level_correct := FALSE;
4417 
4418           END IF;
4419 
4420           ---------------------------------------------------------
4421           -- Once we've processed the correct data level we will --
4422           -- need to process all subsequent data levels as well, --
4423           -- noting that they are AFTER the correct data level   --
4424           ---------------------------------------------------------
4425           IF (l_data_level_progress_point = 'AT') THEN
4426             l_data_level_progress_point := 'AFTER';
4427           END IF;
4428 
4429           ------------------------------------------------------------
4430           -- If we're going to do another loop, increment the index --
4431           ------------------------------------------------------------
4432           IF (l_is_data_level_correct) THEN
4433             l_data_level_index := p_data_level_name_value_pairs.NEXT(l_data_level_index);
4434           END IF;
4435         END LOOP;
4436       END IF;
4437     END IF;
4438 
4439     IF (NOT l_is_data_level_correct) THEN
4440       x_err_msg_name := 'EGO_EF_DATA_LEVEL_INCORRECT';
4441       x_token_table(1).TOKEN_NAME := 'AG_NAME';
4442       x_token_table(1).TOKEN_VALUE := p_attr_group_disp_name;
4443       x_token_table(2).TOKEN_NAME := 'DATA_LEVEL';
4444       x_token_table(2).TOKEN_VALUE := NVL(l_wrong_data_level,p_data_level);
4445       Debug_Msg('In Is_Data_Level_Correct, returning FALSE because l_data_level is '||
4446                 l_data_level ||
4447                 ', l_data_level_progress_point is '||
4448                 l_data_level_progress_point||
4449                 ' and l_wrong_data_level is '||l_wrong_data_level);
4450     END IF;
4451 
4452     Debug_Msg('In Is_Data_Level_Correct, done', 2);
4453     RETURN l_is_data_level_correct;
4454 
4455   EXCEPTION
4456     WHEN NO_DATA_FOUND THEN
4457       Debug_Msg('In Is_Data_Level_Correct, got NO_DATA_FOUND exception so returning FALSE');
4458       IF (l_cursor_id IS NOT NULL) THEN
4459         DBMS_SQL.Close_Cursor(l_cursor_id);
4460       END IF;
4461       --------------------------------------------------------------------
4462       -- In this case, the Attribute Group isn't even associated to the --
4463       -- passed-in Classification Code, so we try to query up the       --
4464       -- Classification Meaning to make a user-friendly error message   --
4465       --------------------------------------------------------------------
4466       x_err_msg_name := 'EGO_EF_AG_NOT_ASSOCIATED';
4467       x_token_table(1).TOKEN_NAME := 'AG_NAME';
4468       x_token_table(1).TOKEN_VALUE := p_attr_group_disp_name;
4469       x_token_table(2).TOKEN_NAME := 'CLASS_MEANING';
4470       BEGIN
4471         SELECT EGO_EXT_FWK_PUB.Get_Class_Meaning(p_object_id, p_class_code_name_value_pairs(1).VALUE)
4472           INTO x_token_table(2).TOKEN_VALUE
4473           FROM DUAL;
4474       EXCEPTION
4475         WHEN OTHERS THEN
4476           x_token_table(2).TOKEN_VALUE := p_class_code_name_value_pairs(1).VALUE;
4477       END;
4478       RETURN FALSE;
4479 
4480 END Is_Data_Level_Correct;
4481 
4482 ----------------------------------------------------------------------
4483 
4484 FUNCTION Disp_Val_Replacement_Is_Bad (
4485         p_attr_metadata_obj             IN   EGO_ATTR_METADATA_OBJ
4486        ,px_attr_value_obj               IN OUT NOCOPY EGO_USER_ATTR_DATA_OBJ
4487 )
4488 RETURN BOOLEAN
4489 IS
4490 
4491   BEGIN
4492 
4493     Debug_Msg('In Disp_Val_Replacement_Is_Bad, starting', 2);
4494 
4495     IF (p_attr_metadata_obj.VALIDATION_CODE IS NULL OR
4496         NOT (p_attr_metadata_obj.VALIDATION_CODE = EGO_EXT_FWK_PUB.G_INDEPENDENT_VALIDATION_CODE OR
4497              p_attr_metadata_obj.VALIDATION_CODE = EGO_EXT_FWK_PUB.G_TABLE_VALIDATION_CODE)) THEN
4498 
4499       IF (px_attr_value_obj.ATTR_DISP_VALUE IS NOT NULL) THEN
4500 
4501         IF ((p_attr_metadata_obj.DATA_TYPE_CODE IS NULL OR
4502              p_attr_metadata_obj.DATA_TYPE_CODE = EGO_EXT_FWK_PUB.G_CHAR_DATA_TYPE OR
4503              p_attr_metadata_obj.DATA_TYPE_CODE = EGO_EXT_FWK_PUB.G_TRANS_TEXT_DATA_TYPE) AND
4504             px_attr_value_obj.ATTR_VALUE_STR IS NULL) THEN
4505 
4506           Debug_Msg('In Disp_Val_Replacement_Is_Bad, putting '||
4507                     px_attr_value_obj.ATTR_DISP_VALUE||
4508                     ' into ATTR_VALUE_STR column', 3);
4509           px_attr_value_obj.ATTR_VALUE_STR := px_attr_value_obj.ATTR_DISP_VALUE;
4510 
4511         ELSIF (p_attr_metadata_obj.DATA_TYPE_CODE = EGO_EXT_FWK_PUB.G_NUMBER_DATA_TYPE AND
4512                px_attr_value_obj.ATTR_VALUE_NUM IS NULL) THEN
4513 
4514           Debug_Msg('In Disp_Val_Replacement_Is_Bad, putting '||
4515                     px_attr_value_obj.ATTR_DISP_VALUE||
4516                     ' into ATTR_VALUE_NUM column', 3);
4517           px_attr_value_obj.ATTR_VALUE_NUM := TO_NUMBER(px_attr_value_obj.ATTR_DISP_VALUE);
4518 
4519         ELSIF (p_attr_metadata_obj.DATA_TYPE_CODE = EGO_EXT_FWK_PUB.G_DATE_DATA_TYPE AND
4520                px_attr_value_obj.ATTR_VALUE_DATE IS NULL) THEN
4521 
4522           Debug_Msg('In Disp_Val_Replacement_Is_Bad, putting '||
4523                     px_attr_value_obj.ATTR_DISP_VALUE||
4524                     ' into ATTR_VALUE_DATE column', 3);
4525           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));
4526 
4527         ELSIF (p_attr_metadata_obj.DATA_TYPE_CODE = EGO_EXT_FWK_PUB.G_DATE_TIME_DATA_TYPE AND
4528                px_attr_value_obj.ATTR_VALUE_DATE IS NULL) THEN
4529 
4530           Debug_Msg('In Disp_Val_Replacement_Is_Bad, putting '||
4531                     px_attr_value_obj.ATTR_DISP_VALUE||
4532                     ' into ATTR_VALUE_DATE column', 3);
4533           px_attr_value_obj.ATTR_VALUE_DATE := TO_DATE(px_attr_value_obj.ATTR_DISP_VALUE, EGO_USER_ATTRS_COMMON_PVT.G_DATE_FORMAT);
4534 
4535         END IF;
4536       END IF;
4537     END IF;
4538 
4539     ----------------------------------------------------
4540     -- If we've gotten here, either we didn't replace --
4541     -- or else the replacement was a valid one        --
4542     ----------------------------------------------------
4543     Debug_Msg('In Disp_Val_Replacement_Is_Bad, returning FALSE', 2);
4544     RETURN FALSE;
4545 
4546   EXCEPTION
4547     WHEN OTHERS THEN
4548       Debug_Msg('In Disp_Val_Replacement_Is_Bad, returning TRUE', 2);
4549       ------------------------------------------------------------------------
4550       -- We assume this means we tried to replace and got a data type clash --
4551       ------------------------------------------------------------------------
4552       RETURN TRUE;
4553 
4554 END Disp_Val_Replacement_Is_Bad;
4555 
4556 ----------------------------------------------------------------------
4557 
4558 FUNCTION Is_Required_Flag_Respected (
4559         p_attr_metadata_obj             IN   EGO_ATTR_METADATA_OBJ
4560        ,p_mode                          IN   VARCHAR2
4561        ,p_attr_value_obj                IN   EGO_USER_ATTR_DATA_OBJ
4562        ,p_attr_group_disp_name          IN   VARCHAR2
4563        ,x_err_msg_name                  OUT NOCOPY VARCHAR2
4564        ,x_token_table                   OUT NOCOPY ERROR_HANDLER.Token_Tbl_Type
4565 )
4566 RETURN BOOLEAN
4567 IS
4568 
4569     l_value                  VARCHAR2(1000);
4570     l_is_req_flag_resp       BOOLEAN := TRUE;
4571 
4572   BEGIN
4573 
4574     Debug_Msg('In Is_Required_Flag_Respected, starting', 2);
4575 
4576     IF (p_attr_metadata_obj.DATA_TYPE_CODE IS NULL OR
4577         p_attr_metadata_obj.DATA_TYPE_CODE = EGO_EXT_FWK_PUB.G_CHAR_DATA_TYPE OR
4578         p_attr_metadata_obj.DATA_TYPE_CODE = EGO_EXT_FWK_PUB.G_TRANS_TEXT_DATA_TYPE) THEN
4579       l_value := p_attr_value_obj.ATTR_VALUE_STR;
4580     ELSIF (p_attr_metadata_obj.DATA_TYPE_CODE = EGO_EXT_FWK_PUB.G_NUMBER_DATA_TYPE) THEN
4581       l_value := p_attr_value_obj.ATTR_VALUE_NUM;
4582     ELSE
4583       l_value := p_attr_value_obj.ATTR_VALUE_DATE;
4584     END IF;
4585 
4586     ------------------------------------------------------------------
4587     -- If they didn't pass a value of the correct data type AND the --
4588     -- Attribute has a Value Set of type Independent or Table, then --
4589     -- we give them one last chance by assuming that they passed a  --
4590     -- Display Value (which we will later convert to an Internal    --
4591     -- Value in Is_Value_Set_Respected)                             --
4592     ------------------------------------------------------------------
4593     IF (l_value IS NULL AND
4594         (p_attr_metadata_obj.VALIDATION_CODE = EGO_EXT_FWK_PUB.G_INDEPENDENT_VALIDATION_CODE OR
4595          p_attr_metadata_obj.VALIDATION_CODE = EGO_EXT_FWK_PUB.G_TRANS_IND_VALIDATION_CODE OR
4596          p_attr_metadata_obj.VALIDATION_CODE = EGO_EXT_FWK_PUB.G_TABLE_VALIDATION_CODE)) THEN
4597       l_value := p_attr_value_obj.ATTR_DISP_VALUE;
4598     END IF;
4599 
4600     --------------------------------------------------------------
4601     -- If the Attribute is required, we're in CREATE mode, no   --
4602     -- value was passed, and no Default Value is defined (or we --
4603     -- aren't using the Default Value), then we raise an error  --
4604     --------------------------------------------------------------
4605     IF (p_attr_metadata_obj.REQUIRED_FLAG = 'Y' AND
4606         (UPPER(p_mode) = G_CREATE_MODE OR UPPER(p_mode) = G_UPDATE_MODE) AND --gnanda:BugFix:4640128
4607         l_value IS NULL AND
4608         (p_attr_metadata_obj.DEFAULT_VALUE IS NULL OR
4609         NOT G_DEFAULT_ON_INSERT_FLAG)) THEN
4610       Debug_Msg('In Is_Required_Flag_Respected, required Attr '||p_attr_value_obj.ATTR_NAME||' has no value in '||p_mode||' mode');
4611 
4612       l_is_req_flag_resp := FALSE;
4613 
4614       x_err_msg_name := 'EGO_EF_NO_VAL_FOR_REQ_ATTR';
4615 
4616       x_token_table(1).TOKEN_NAME := 'ATTR_NAME';
4617       x_token_table(1).TOKEN_VALUE := p_attr_metadata_obj.ATTR_DISP_NAME;
4618       x_token_table(2).TOKEN_NAME := 'AG_NAME';
4619       x_token_table(2).TOKEN_VALUE := p_attr_group_disp_name;
4620 
4621     END IF;
4622 
4623     Debug_Msg('In Is_Required_Flag_Respected, done', 2);
4624 
4625   RETURN l_is_req_flag_resp;
4626 
4627 END Is_Required_Flag_Respected;
4628 
4629 ----------------------------------------------------------------------
4630 
4631 FUNCTION Is_Data_Type_Correct (
4632         p_attr_metadata_obj             IN   EGO_ATTR_METADATA_OBJ
4633        ,p_attr_value_obj                IN   EGO_USER_ATTR_DATA_OBJ
4634        ,p_attr_group_disp_name          IN   VARCHAR2
4635        ,x_err_msg_name                  OUT NOCOPY VARCHAR2
4636        ,x_token_table                   OUT NOCOPY ERROR_HANDLER.Token_Tbl_Type
4637 )
4638 RETURN BOOLEAN
4639 IS
4640 
4641     l_value                  VARCHAR2(1000);
4642     l_is_data_type_correct   BOOLEAN := TRUE;
4643 
4644   BEGIN
4645 
4646     Debug_Msg('In Is_Data_Type_Correct, starting', 2);
4647 
4648     IF
4649        (
4650          (
4651            p_attr_metadata_obj.DATA_TYPE_CODE = EGO_EXT_FWK_PUB.G_CHAR_DATA_TYPE OR
4652            p_attr_metadata_obj.DATA_TYPE_CODE = EGO_EXT_FWK_PUB.G_TRANS_TEXT_DATA_TYPE
4653          ) AND
4654          (
4655            p_attr_value_obj.ATTR_VALUE_STR IS NULL AND
4656            (
4657              p_attr_value_obj.ATTR_VALUE_NUM IS NOT NULL OR
4658              p_attr_value_obj.ATTR_VALUE_DATE IS NOT NULL
4659            )
4660          )
4661        ) THEN
4662 
4663       l_value := NVL(TO_CHAR(p_attr_value_obj.ATTR_VALUE_NUM),
4664                      TO_CHAR(p_attr_value_obj.ATTR_VALUE_DATE, EGO_USER_ATTRS_COMMON_PVT.G_DATE_FORMAT));
4665 
4666     ELSIF (
4667             (
4668               p_attr_metadata_obj.DATA_TYPE_CODE = EGO_EXT_FWK_PUB.G_NUMBER_DATA_TYPE
4669             ) AND
4670             (
4671               p_attr_value_obj.ATTR_VALUE_NUM IS NULL AND
4672               (
4673                 p_attr_value_obj.ATTR_VALUE_STR IS NOT NULL OR
4674                 p_attr_value_obj.ATTR_VALUE_DATE IS NOT NULL
4675               )
4676             )
4677           ) THEN
4678 
4679       l_value := NVL(p_attr_value_obj.ATTR_VALUE_STR,
4680                      TO_CHAR(p_attr_value_obj.ATTR_VALUE_DATE, EGO_USER_ATTRS_COMMON_PVT.G_DATE_FORMAT));
4681 
4682     ELSIF (
4683             (
4684               p_attr_metadata_obj.DATA_TYPE_CODE = EGO_EXT_FWK_PUB.G_DATE_DATA_TYPE OR
4685               p_attr_metadata_obj.DATA_TYPE_CODE = EGO_EXT_FWK_PUB.G_DATE_TIME_DATA_TYPE
4686             ) AND
4687             (
4688               p_attr_value_obj.ATTR_VALUE_DATE IS NULL AND
4689               (
4690                 p_attr_value_obj.ATTR_VALUE_STR IS NOT NULL OR
4691                 p_attr_value_obj.ATTR_VALUE_NUM IS NOT NULL
4692               )
4693             )
4694           ) THEN
4695 
4696       l_value := NVL(p_attr_value_obj.ATTR_VALUE_STR,
4697                      TO_CHAR(p_attr_value_obj.ATTR_VALUE_NUM));
4698 
4699     END IF;
4700 
4701     IF (l_value IS NOT NULL) THEN
4702 
4703       Debug_Msg('In Is_Data_Type_Correct, Attr '||p_attr_value_obj.ATTR_NAME||
4704                 ' has no value of the correct data type, '||p_attr_metadata_obj.DATA_TYPE_MEANING);
4705 
4706       l_is_data_type_correct := FALSE;
4707 
4708       x_err_msg_name := 'EGO_EF_DATA_TYPE_INCORRECT';
4709 
4710       x_token_table(1).TOKEN_NAME := 'ATTR_NAME';
4711       x_token_table(1).TOKEN_VALUE := p_attr_metadata_obj.ATTR_DISP_NAME;
4712       x_token_table(2).TOKEN_NAME := 'AG_NAME';
4713       x_token_table(2).TOKEN_VALUE := p_attr_group_disp_name;
4714       x_token_table(3).TOKEN_NAME := 'DATA_TYPE';
4715       x_token_table(3).TOKEN_VALUE := p_attr_metadata_obj.DATA_TYPE_MEANING;
4716       x_token_table(4).TOKEN_NAME := 'VALUE';
4717       x_token_table(4).TOKEN_VALUE := p_attr_value_obj.ATTR_DISP_VALUE;
4718 
4719     END IF;
4720 
4721     Debug_Msg('In Is_Data_Type_Correct, done', 2);
4722 
4723   RETURN l_is_data_type_correct;
4724 
4725 END Is_Data_Type_Correct;
4726 
4727 ----------------------------------------------------------------------
4728 
4729 FUNCTION Is_Min_Or_Max_Value_Respected (
4730         p_attr_metadata_obj             IN   EGO_ATTR_METADATA_OBJ
4731        ,p_attr_value_obj                IN   EGO_USER_ATTR_DATA_OBJ
4732        ,p_min_or_max                    IN   VARCHAR2
4733 )
4734 RETURN BOOLEAN
4735 IS
4736 
4737     l_is_range_respected     BOOLEAN := TRUE;
4738     l_value_bound_string     VARCHAR2(150);
4739 
4740   BEGIN
4741 
4742     Debug_Msg('In Is_Min_Or_Max_Value_Respected, starting', 2);
4743 
4744     IF (p_min_or_max = 'MIN') THEN
4745       l_value_bound_string := p_attr_metadata_obj.MINIMUM_VALUE;
4746     ELSIF (p_min_or_max = 'MAX') THEN
4747       l_value_bound_string := p_attr_metadata_obj.MAXIMUM_VALUE;
4748     END IF;
4749 
4750     IF (l_value_bound_string IS NOT NULL) THEN
4751 
4752       Debug_Msg('In Is_Min_Or_Max_Value_Respected, '||p_attr_value_obj.ATTR_NAME||
4753                 ' has a '||p_min_or_max||' value of '||l_value_bound_string);
4754 
4755       -----------------
4756       -- Number case --
4757       -----------------
4758       IF (p_attr_metadata_obj.DATA_TYPE_CODE = EGO_EXT_FWK_PUB.G_NUMBER_DATA_TYPE) THEN
4759 
4760         IF ((p_min_or_max = 'MIN' AND
4761              p_attr_value_obj.ATTR_VALUE_NUM < TO_NUMBER(l_value_bound_string)) OR
4762             (p_min_or_max = 'MAX' AND
4763              p_attr_value_obj.ATTR_VALUE_NUM > TO_NUMBER(l_value_bound_string))) THEN
4764           l_is_range_respected := FALSE;
4765         END IF;
4766 
4767       ---------------
4768       -- Date case --
4769       ---------------
4770       ELSIF (p_attr_metadata_obj.DATA_TYPE_CODE = EGO_EXT_FWK_PUB.G_DATE_DATA_TYPE OR
4771              p_attr_metadata_obj.DATA_TYPE_CODE = EGO_EXT_FWK_PUB.G_DATE_TIME_DATA_TYPE) THEN
4772 
4773         -----------------------------------------------------------------
4774         -- We store Min/Max Values in Timestamp format, which includes --
4775         -- a decimal millisecond component; but since the TO_DATE      --
4776         -- function doesn't allow for milliseconds, we have to trim    --
4777         -- that part of the string in order to compare the value.      --
4778         -- We also allow Min/Max Values to be expressions of the form  --
4779         -- "$SYSDATE$ [+/- {integer}]"; if this value bound string is  --
4780         -- in such a form, we turn it into a string in                 --
4781         -- EGO_USER_ATTRS_COMMON_PVT.G_DATE_FORMAT.                    --
4782         -----------------------------------------------------------------
4783         IF (INSTR(l_value_bound_string, '.', -1) > 0) THEN
4784           l_value_bound_string := SUBSTR(l_value_bound_string, 1, INSTR(l_value_bound_string, '.') - 1);
4785         ELSIF (INSTR(UPPER(l_value_bound_string), 'SYSDATE') > 0) THEN
4786 
4787           l_value_bound_string := Format_Sysdate_Expression(l_value_bound_string);
4788 
4789         END IF;
4790 
4791         IF (
4792              (
4793                (
4794                  p_attr_metadata_obj.DATA_TYPE_CODE = EGO_EXT_FWK_PUB.G_DATE_DATA_TYPE AND
4795                  (
4796                    p_min_or_max = 'MIN' AND
4797                    p_attr_value_obj.ATTR_VALUE_DATE < TRUNC(TO_DATE(l_value_bound_string, EGO_USER_ATTRS_COMMON_PVT.G_DATE_FORMAT))
4798                  )
4799                )
4800                OR
4801                (
4802                  p_min_or_max = 'MAX' AND
4803                  TRUNC(p_attr_value_obj.ATTR_VALUE_DATE) > TO_DATE(l_value_bound_string, EGO_USER_ATTRS_COMMON_PVT.G_DATE_FORMAT)
4804                )
4805              )
4806              OR
4807              (
4808                (
4809                  p_attr_metadata_obj.DATA_TYPE_CODE = EGO_EXT_FWK_PUB.G_DATE_TIME_DATA_TYPE AND
4810                  (
4811                    p_min_or_max = 'MIN' AND
4812                    p_attr_value_obj.ATTR_VALUE_DATE < TO_DATE(l_value_bound_string, EGO_USER_ATTRS_COMMON_PVT.G_DATE_FORMAT)
4813                  )
4814                )
4815                OR
4816                (
4817                  p_min_or_max = 'MAX' AND
4818                  p_attr_value_obj.ATTR_VALUE_DATE > TO_DATE(l_value_bound_string, EGO_USER_ATTRS_COMMON_PVT.G_DATE_FORMAT)
4819                )
4820              )
4821            ) THEN
4822 
4823           l_is_range_respected := FALSE;
4824 
4825         END IF;
4826       END IF;
4827     END IF;
4828 
4829     IF (l_is_range_respected) THEN
4830       Debug_Msg('In Is_Min_Or_Max_Value_Respected, returning TRUE');
4831     ELSE
4832       Debug_Msg('In Is_Min_Or_Max_Value_Respected, returning FALSE');
4833     END IF;
4834     Debug_Msg('In Is_Min_Or_Max_Value_Respected, done', 2);
4835 
4836     RETURN l_is_range_respected;
4837 
4838 EXCEPTION
4839   WHEN OTHERS THEN
4840     Debug_Msg('In Is_Min_Or_Max_Value_Respected, EXCEPTION OTHERS '||SQLERRM);
4841     RETURN FALSE;
4842 
4843 END Is_Min_Or_Max_Value_Respected;
4844 
4845 ----------------------------------------------------------------------
4846 
4847 FUNCTION Is_Max_Size_Respected (
4848         p_attr_metadata_obj             IN   EGO_ATTR_METADATA_OBJ
4849        ,p_attr_value_obj                IN   EGO_USER_ATTR_DATA_OBJ
4850        ,p_attr_group_disp_name          IN   VARCHAR2
4851        ,x_err_msg_name                  OUT NOCOPY VARCHAR2
4852        ,x_token_table                   OUT NOCOPY ERROR_HANDLER.Token_Tbl_Type
4853 )
4854 RETURN BOOLEAN
4855 IS
4856 
4857     l_is_max_size_respected  BOOLEAN := TRUE;
4858     l_value                  VARCHAR2(1000);
4859 
4860   BEGIN
4861 
4862     Debug_Msg('In Is_Max_Size_Respected, starting', 2);
4863 
4864     ---------------------------------------------------------------
4865     -- NOTE: We don't enforce maximum size with Date Attributes, --
4866     -- because the size depends on the format of the Date, which --
4867     -- we can't know at this point.                              --
4868     -- Also, we use LENGTH rather than LENGTH for these checks  --
4869     -- because we want to know the number of characters rather   --
4870     -- than the number of bytes (for multi-byte support).        --
4871     ---------------------------------------------------------------
4872 
4873     IF (p_attr_metadata_obj.DATA_TYPE_CODE IS NULL OR
4874         p_attr_metadata_obj.DATA_TYPE_CODE = EGO_EXT_FWK_PUB.G_CHAR_DATA_TYPE OR
4875         p_attr_metadata_obj.DATA_TYPE_CODE = EGO_EXT_FWK_PUB.G_TRANS_TEXT_DATA_TYPE) THEN
4876 
4877       IF (p_attr_metadata_obj.MAXIMUM_SIZE > 0 AND
4878           p_attr_metadata_obj.MAXIMUM_SIZE <
4879           LENGTH(p_attr_value_obj.ATTR_VALUE_STR)) THEN
4880         l_is_max_size_respected := FALSE;
4881         l_value := p_attr_value_obj.ATTR_VALUE_STR;
4882       END IF;
4883 
4884     ELSIF (p_attr_metadata_obj.DATA_TYPE_CODE = EGO_EXT_FWK_PUB.G_NUMBER_DATA_TYPE) THEN
4885 
4886       IF (p_attr_metadata_obj.MAXIMUM_SIZE > 0 AND
4887           p_attr_metadata_obj.MAXIMUM_SIZE <
4888           LENGTH(TO_CHAR(p_attr_value_obj.ATTR_VALUE_NUM))) THEN
4889         l_is_max_size_respected := FALSE;
4890         l_value := TO_CHAR(p_attr_value_obj.ATTR_VALUE_NUM);
4891       END IF;
4892 
4893     END IF;
4894 
4895     IF (NOT l_is_max_size_respected) THEN
4896 
4897       x_err_msg_name := 'EGO_EF_MAX_SIZE_VIOLATED';
4898 
4899       x_token_table(1).TOKEN_NAME := 'VALUE';
4900       x_token_table(1).TOKEN_VALUE := l_value;
4901       x_token_table(2).TOKEN_NAME := 'ATTR_NAME';
4902       x_token_table(2).TOKEN_VALUE := p_attr_metadata_obj.ATTR_DISP_NAME;
4903       x_token_table(3).TOKEN_NAME := 'AG_NAME';
4904       x_token_table(3).TOKEN_VALUE := p_attr_group_disp_name;
4905 
4906     END IF;
4907 
4908     Debug_Msg('In Is_Max_Size_Respected, done', 2);
4909 
4910     RETURN l_is_max_size_respected;
4911 
4912 END Is_Max_Size_Respected;
4913 
4914 ----------------------------------------------------------------------
4915 
4916 FUNCTION Is_UOM_Valid (
4917         p_attr_metadata_obj             IN   EGO_ATTR_METADATA_OBJ
4918        ,px_attr_value_obj               IN OUT NOCOPY EGO_USER_ATTR_DATA_OBJ
4919 )
4920 RETURN BOOLEAN
4921 IS
4922 
4923     l_is_uom_valid           BOOLEAN := TRUE;
4924     l_dummy                  VARCHAR2(1);
4925 
4926   BEGIN
4927 
4928     Debug_Msg('In Is_UOM_Valid, starting', 2);
4929 
4930     ------------------------------------------------------------------------------
4931     -- If there is a UOM, we see whether it's a member of the correct UOM class --
4932     -- (we query against MTL_UNITS_OF_MEASURE_TL because there is no _B table)  --
4933     ------------------------------------------------------------------------------
4934     IF (px_attr_value_obj.ATTR_UNIT_OF_MEASURE IS NOT NULL) THEN
4935 
4936       BEGIN
4937         SELECT 'X'
4938           INTO l_dummy
4939           FROM MTL_UNITS_OF_MEASURE_TL
4940          WHERE UOM_CLASS = p_attr_metadata_obj.UNIT_OF_MEASURE_CLASS
4941            AND UOM_CODE = px_attr_value_obj.ATTR_UNIT_OF_MEASURE
4942            AND ROWNUM = 1;
4943       EXCEPTION
4944         WHEN NO_DATA_FOUND THEN
4945           l_is_uom_valid := FALSE;
4946       END;
4947 
4948     END IF;
4949 
4950     IF (l_is_uom_valid) THEN
4951       Debug_Msg('In Is_UOM_Valid, returning TRUE');
4952     ELSE
4953       Debug_Msg('In Is_UOM_Valid, returning FALSE');
4954     END IF;
4955 
4956     Debug_Msg('In Is_UOM_Valid, done', 2);
4957 
4958   RETURN l_is_uom_valid;
4959 
4960 END Is_UOM_Valid;
4961 
4962 ----------------------------------------------------------------------
4963 
4964 FUNCTION Is_Value_Set_Respected (
4965         p_attr_metadata_obj             IN   EGO_ATTR_METADATA_OBJ
4966        ,p_attr_group_metadata_obj       IN   EGO_ATTR_GROUP_METADATA_OBJ
4967        ,p_ext_table_metadata_obj        IN   EGO_EXT_TABLE_METADATA_OBJ
4968        ,p_pk_column_name_value_pairs    IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
4969        ,p_data_level_name_value_pairs   IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
4970        ,p_entity_id                     IN   VARCHAR2
4971        ,p_entity_index                  IN   NUMBER
4972        ,p_entity_code                   IN   VARCHAR2
4973        ,p_attr_name_value_pairs         IN   EGO_USER_ATTR_DATA_TABLE
4974        ,px_attr_value_obj               IN OUT NOCOPY EGO_USER_ATTR_DATA_OBJ
4975 )
4976 RETURN BOOLEAN
4977 IS
4978 
4979     l_int_value              VARCHAR2(1000);
4980     l_disp_value             VARCHAR2(1000);
4981     l_is_val_set_respected   BOOLEAN := TRUE;
4982     l_err_msg_name           VARCHAR2(30);
4983     l_token_table            ERROR_HANDLER.Token_Tbl_Type;
4984 
4985   BEGIN
4986 
4987     Debug_Msg('In Is_Value_Set_Respected, starting', 2);
4988 
4989     IF (p_attr_metadata_obj.VALUE_SET_ID IS NOT NULL) THEN
4990 
4991       Debug_Msg('In Is_Value_Set_Respected, '||px_attr_value_obj.ATTR_NAME||
4992                 ' has Value Set of validation type '||p_attr_metadata_obj.VALIDATION_CODE);
4993 
4994       IF (p_attr_metadata_obj.VALIDATION_CODE = 'N') THEN
4995 
4996         l_is_val_set_respected := Is_Min_Or_Max_Value_Respected(p_attr_metadata_obj
4997                                                                ,px_attr_value_obj
4998                                                                ,'MIN');
4999 
5000         IF (NOT l_is_val_set_respected) THEN
5001 
5002           IF (p_attr_metadata_obj.DATA_TYPE_CODE = EGO_EXT_FWK_PUB.G_NUMBER_DATA_TYPE) THEN
5003 
5004             l_err_msg_name := 'EGO_EF_MIN_VAL_NUM_VIOLATED';
5005 
5006             l_token_table(1).TOKEN_NAME := 'ATTR_NAME';
5007             l_token_table(1).TOKEN_VALUE := p_attr_metadata_obj.ATTR_DISP_NAME;
5008             l_token_table(2).TOKEN_NAME := 'AG_NAME';
5009             l_token_table(2).TOKEN_VALUE := p_attr_group_metadata_obj.ATTR_GROUP_DISP_NAME;
5010             l_token_table(3).TOKEN_NAME := 'MIN_NUM_VALUE';
5011             l_token_table(3).TOKEN_VALUE := p_attr_metadata_obj.MINIMUM_VALUE;
5012 
5013           ELSE
5014 
5015             l_err_msg_name := 'EGO_EF_MIN_VAL_DATE_VIOLATED';
5016 
5017             l_token_table(1).TOKEN_NAME := 'ATTR_NAME';
5018             l_token_table(1).TOKEN_VALUE := p_attr_metadata_obj.ATTR_DISP_NAME;
5019             l_token_table(2).TOKEN_NAME := 'AG_NAME';
5020             l_token_table(2).TOKEN_VALUE := p_attr_group_metadata_obj.ATTR_GROUP_DISP_NAME;
5021             l_token_table(3).TOKEN_NAME := 'MIN_DATE_VALUE';
5022             l_token_table(3).TOKEN_VALUE := p_attr_metadata_obj.MINIMUM_VALUE;
5023 
5024           END IF;
5025 
5026         ELSE
5027 
5028           l_is_val_set_respected := Is_Min_Or_Max_Value_Respected(p_attr_metadata_obj
5029                                                                  ,px_attr_value_obj
5030                                                                  ,'MAX');
5031 
5032           IF (NOT l_is_val_set_respected) THEN
5033 
5034             IF (p_attr_metadata_obj.DATA_TYPE_CODE = EGO_EXT_FWK_PUB.G_NUMBER_DATA_TYPE) THEN
5035 
5036               l_err_msg_name := 'EGO_EF_MAX_VAL_NUM_VIOLATED';
5037 
5038               l_token_table(1).TOKEN_NAME := 'ATTR_NAME';
5039               l_token_table(1).TOKEN_VALUE := p_attr_metadata_obj.ATTR_DISP_NAME;
5040               l_token_table(2).TOKEN_NAME := 'AG_NAME';
5041               l_token_table(2).TOKEN_VALUE := p_attr_group_metadata_obj.ATTR_GROUP_DISP_NAME;
5042               l_token_table(3).TOKEN_NAME := 'MAX_NUM_VALUE';
5043               l_token_table(3).TOKEN_VALUE := p_attr_metadata_obj.MAXIMUM_VALUE;
5044 
5045             ELSE
5046 
5047               l_err_msg_name := 'EGO_EF_MAX_VAL_DATE_VIOLATED';
5048 
5049               l_token_table(1).TOKEN_NAME := 'ATTR_NAME';
5050               l_token_table(1).TOKEN_VALUE := p_attr_metadata_obj.ATTR_DISP_NAME;
5051               l_token_table(2).TOKEN_NAME := 'AG_NAME';
5052               l_token_table(2).TOKEN_VALUE := p_attr_group_metadata_obj.ATTR_GROUP_DISP_NAME;
5053               l_token_table(3).TOKEN_NAME := 'MAX_DATE_VALUE';
5054               l_token_table(3).TOKEN_VALUE := p_attr_metadata_obj.MAXIMUM_VALUE;
5055 
5056             END IF;
5057           END IF;
5058         END IF;
5059 
5060       ----------------------------------------------------------------------------
5061       -- If the Attribute has a Value Set whose Values have different Internal  --
5062       -- and Display Values, we need to validate the passed-in value (which has --
5063       -- to be either an Internal Value or a Display Value for the Value Set)   --
5064       ----------------------------------------------------------------------------
5065       ELSIF (p_attr_metadata_obj.VALIDATION_CODE = EGO_EXT_FWK_PUB.G_INDEPENDENT_VALIDATION_CODE OR
5066              p_attr_metadata_obj.VALIDATION_CODE = EGO_EXT_FWK_PUB.G_TRANS_IND_VALIDATION_CODE OR
5067              p_attr_metadata_obj.VALIDATION_CODE = EGO_EXT_FWK_PUB.G_TABLE_VALIDATION_CODE) THEN
5068 
5069         -------------------------------------------
5070         -- If the user passed the Display Value, --
5071         -- we will try to get the Internal Value --
5072         -------------------------------------------
5073         IF (px_attr_value_obj.ATTR_DISP_VALUE IS NOT NULL AND
5074             px_attr_value_obj.ATTR_VALUE_STR IS NULL AND
5075             px_attr_value_obj.ATTR_VALUE_NUM IS NULL AND
5076             px_attr_value_obj.ATTR_VALUE_DATE IS NULL) THEN
5077 
5078           l_int_value := Get_Int_Val_For_Disp_Val(
5079                            p_attr_metadata_obj             => p_attr_metadata_obj
5080                           ,p_attr_value_obj                => px_attr_value_obj
5081                           ,p_attr_group_metadata_obj       => p_attr_group_metadata_obj
5082                           ,p_ext_table_metadata_obj        => p_ext_table_metadata_obj
5083                           ,p_pk_column_name_value_pairs    => p_pk_column_name_value_pairs
5084                           ,p_data_level_name_value_pairs   => p_data_level_name_value_pairs
5085                           ,p_entity_id                     => p_entity_id
5086                           ,p_entity_index                  => p_entity_index
5087                           ,p_entity_code                   => p_entity_code
5088                           ,p_attr_name_value_pairs         => p_attr_name_value_pairs
5089                          );
5090 
5091           IF (l_int_value IS NOT NULL) THEN
5092             IF (p_attr_metadata_obj.DATA_TYPE_CODE IS NULL OR
5093                 p_attr_metadata_obj.DATA_TYPE_CODE = EGO_EXT_FWK_PUB.G_CHAR_DATA_TYPE OR
5094                 p_attr_metadata_obj.DATA_TYPE_CODE = EGO_EXT_FWK_PUB.G_TRANS_TEXT_DATA_TYPE) THEN
5095 
5096               px_attr_value_obj.ATTR_VALUE_STR := l_int_value;
5097 
5098             ELSIF (p_attr_metadata_obj.DATA_TYPE_CODE = EGO_EXT_FWK_PUB.G_NUMBER_DATA_TYPE) THEN
5099 
5100               px_attr_value_obj.ATTR_VALUE_NUM := TO_NUMBER(l_int_value);
5101 
5102             ELSIF (p_attr_metadata_obj.DATA_TYPE_CODE = EGO_EXT_FWK_PUB.G_DATE_DATA_TYPE) THEN
5103 
5104               px_attr_value_obj.ATTR_VALUE_DATE := TRUNC(TO_DATE(l_int_value, EGO_USER_ATTRS_COMMON_PVT.G_DATE_FORMAT));
5105 
5106             ELSIF (p_attr_metadata_obj.DATA_TYPE_CODE = EGO_EXT_FWK_PUB.G_DATE_TIME_DATA_TYPE) THEN
5107 
5108               px_attr_value_obj.ATTR_VALUE_DATE := TO_DATE(l_int_value, EGO_USER_ATTRS_COMMON_PVT.G_DATE_FORMAT);
5109 
5110             END IF;
5111           ELSE
5112 
5113             l_is_val_set_respected := FALSE;
5114 
5115             l_err_msg_name := 'EGO_EF_INDEPENDENT_VS_VIOLATED';
5116 
5117             l_token_table(1).TOKEN_NAME := 'VALUE';
5118             l_token_table(1).TOKEN_VALUE := px_attr_value_obj.ATTR_DISP_VALUE;
5119             l_token_table(2).TOKEN_NAME := 'ATTR_NAME';
5120             l_token_table(2).TOKEN_VALUE := p_attr_metadata_obj.ATTR_DISP_NAME;
5121             l_token_table(3).TOKEN_NAME := 'AG_NAME';
5122             l_token_table(3).TOKEN_VALUE := p_attr_group_metadata_obj.ATTR_GROUP_DISP_NAME;
5123 
5124             Debug_Msg('In Is_Value_Set_Respected, disp value passed was bad; VS is violated');
5125           END IF;
5126 
5127         ---------------------------------------------------------------
5128         -- If, on the other hand, the user passed the Interal Value, --
5129         -- we verify it by trying to get the Display Value           --
5130         ---------------------------------------------------------------
5131         ELSIF (px_attr_value_obj.ATTR_VALUE_STR IS NOT NULL OR
5132                px_attr_value_obj.ATTR_VALUE_NUM IS NOT NULL OR
5133                px_attr_value_obj.ATTR_VALUE_DATE IS NOT NULL) THEN
5134 
5135           l_disp_value := Get_Disp_Val_For_Int_Val(
5136                             p_attr_value_obj                => px_attr_value_obj
5137                            ,p_attr_metadata_obj             => p_attr_metadata_obj
5138                            ,p_attr_group_metadata_obj       => p_attr_group_metadata_obj
5139                            ,p_pk_column_name_value_pairs    => p_pk_column_name_value_pairs
5140                            ,p_data_level_name_value_pairs   => p_data_level_name_value_pairs
5141                            ,p_entity_id                     => p_entity_id
5142                            ,p_entity_index                  => p_entity_index
5143                            ,p_entity_code                   => p_entity_code
5144                            ,p_attr_name_value_pairs         => p_attr_name_value_pairs
5145                            ,p_ext_table_metadata_obj        => p_ext_table_metadata_obj
5146                           );
5147 
5148           IF (l_disp_value IS NULL) THEN
5149 
5150             l_is_val_set_respected := FALSE;
5151 
5152             l_err_msg_name := 'EGO_EF_INDEPENDENT_VS_VIOLATED';
5153 
5154             IF (px_attr_value_obj.ATTR_VALUE_STR IS NOT NULL) THEN
5155               l_int_value := px_attr_value_obj.ATTR_VALUE_STR;
5156             ELSIF (px_attr_value_obj.ATTR_VALUE_NUM IS NOT NULL) THEN
5157               l_int_value := px_attr_value_obj.ATTR_VALUE_NUM;
5158             ELSE
5159               l_int_value := px_attr_value_obj.ATTR_VALUE_DATE;
5160             END IF;
5161 
5162             l_token_table(1).TOKEN_NAME := 'VALUE';
5163             l_token_table(1).TOKEN_VALUE := l_int_value;
5164             l_token_table(2).TOKEN_NAME := 'ATTR_NAME';
5165             l_token_table(2).TOKEN_VALUE :=p_attr_metadata_obj.ATTR_DISP_NAME;
5166             l_token_table(3).TOKEN_NAME := 'AG_NAME';
5167             l_token_table(3).TOKEN_VALUE := p_attr_group_metadata_obj.ATTR_GROUP_DISP_NAME;
5168 
5169             Debug_Msg('In Is_Value_Set_Respected, int value passed was bad; VS is violated');
5170           END IF;
5171         END IF;
5172       END IF;
5173     END IF;
5174 
5175     ----------------------------------------------------------
5176     -- If we found an error and didn't log it in one of the --
5177     -- functions we called, then we need to log it now      --
5178     ----------------------------------------------------------
5179     IF (NOT l_is_val_set_respected AND l_err_msg_name IS NOT NULL) THEN
5180 
5181       ERROR_HANDLER.Add_Error_Message(
5182         p_message_name      => l_err_msg_name
5183        ,p_application_id    => 'EGO'
5184        ,p_token_tbl         => l_token_table
5185        ,p_message_type      => FND_API.G_RET_STS_ERROR
5186        ,p_row_identifier    => G_USER_ROW_IDENTIFIER
5187        ,p_entity_id         => p_entity_id
5188        ,p_entity_index      => p_entity_index
5189        ,p_entity_code       => p_entity_code
5190        ,p_addto_fnd_stack   => G_ADD_ERRORS_TO_FND_STACK
5191       );
5192 
5193     END IF;
5194 
5195     IF (l_is_val_set_respected) THEN
5196       Debug_Msg('In Is_Value_Set_Respected, returning TRUE');
5197     ELSE
5198       Debug_Msg('In Is_Value_Set_Respected, returning FALSE');
5199     END IF;
5200 
5201     Debug_Msg('In Is_Value_Set_Respected, done', 2);
5202 
5203     RETURN l_is_val_set_respected;
5204 
5205   EXCEPTION
5206     WHEN OTHERS THEN
5207       Debug_Msg('In Is_Min_Or_Max_Value_Respected, EXCEPTION OTHERS '||SQLERRM);
5208       RETURN FALSE;
5209 
5210 END Is_Value_Set_Respected;
5211 
5212 ----------------------------------------------------------------------
5213 
5214 FUNCTION Verify_All_Required_Attrs (
5215         p_passed_attr_names_table       IN   LOCAL_VARCHAR_TABLE
5216        ,p_attr_metadata_table           IN   EGO_ATTR_METADATA_TABLE
5217        ,p_entity_id                     IN   VARCHAR2
5218        ,p_entity_index                  IN   NUMBER
5219        ,p_entity_code                   IN   VARCHAR2
5220        ,p_attr_group_disp_name          IN   VARCHAR2
5221        ,px_attr_name_value_pairs        IN OUT NOCOPY EGO_USER_ATTR_DATA_TABLE
5222 )
5223 RETURN BOOLEAN
5224 IS
5225 
5226     l_has_all_required_attrs BOOLEAN := TRUE;
5227     l_metadata_table_index   NUMBER;
5228     l_attr_metadata_obj      EGO_ATTR_METADATA_OBJ;
5229     l_passed_attrs_table_index NUMBER;
5230     l_already_processed      BOOLEAN;
5231     l_token_table            ERROR_HANDLER.Token_Tbl_Type;
5232 
5233   BEGIN
5234 
5235     l_token_table(1).TOKEN_NAME := 'ATTR_NAME';
5236     -- the token value will be supplied in the loop itself
5237     l_token_table(2).TOKEN_NAME := 'AG_NAME';
5238     l_token_table(2).TOKEN_VALUE := p_attr_group_disp_name;
5239 
5240     Debug_Msg('In Verify_All_Required_Attrs, starting', 2);
5241 
5242     -----------------------------------------------------
5243     -- We loop through all Attributes in the Attribute --
5244     -- Group, looking for required Attributes          --
5245     -----------------------------------------------------
5246     l_metadata_table_index := p_attr_metadata_table.FIRST;
5247     WHILE (l_metadata_table_index <= p_attr_metadata_table.LAST)
5248     LOOP
5249 
5250       l_already_processed := FALSE;
5251       l_attr_metadata_obj := p_attr_metadata_table(l_metadata_table_index);
5252       IF (l_attr_metadata_obj.REQUIRED_FLAG = 'Y') THEN
5253 
5254         --------------------------------------------
5255         -- For every required Attribute, we check --
5256         -- whether or not we already processed it --
5257         --------------------------------------------
5258         l_passed_attrs_table_index := p_passed_attr_names_table.FIRST;
5259         WHILE (l_passed_attrs_table_index <= p_passed_attr_names_table.LAST)
5260         LOOP
5261           EXIT WHEN (l_already_processed);
5262 
5263           IF (p_passed_attr_names_table(l_passed_attrs_table_index) = l_attr_metadata_obj.ATTR_NAME) THEN
5264 
5265             l_already_processed := TRUE;
5266 
5267           END IF;
5268 
5269           l_passed_attrs_table_index := p_passed_attr_names_table.NEXT(l_passed_attrs_table_index);
5270         END LOOP;
5271 
5272         -------------------------------------------------------------------------
5273         -- If the required Attribute wasn't passed but has a default value, we --
5274         -- create a data object for it and put it into our name/value pairs    --
5275         -- table (trusting Get_List_For_Attrs to default it as necessary); if  --
5276         -- there is no default value, we add the Attribute's name to the list  --
5277         -- of missing Attributes                                               --
5278         -------------------------------------------------------------------------
5279         IF (NOT l_already_processed) THEN
5280 
5281           IF (l_attr_metadata_obj.DEFAULT_VALUE IS NOT NULL) THEN
5282 
5283             Debug_Msg('In Verify_All_Required_Attrs, non-passed required Attribute '||l_attr_metadata_obj.ATTR_DISP_NAME||' has a default value');
5284 
5285             DECLARE
5286 
5287               l_attr_data_obj           EGO_USER_ATTR_DATA_OBJ;
5288 
5289             BEGIN
5290 
5291               l_attr_data_obj := EGO_USER_ATTR_DATA_OBJ(
5292                                    px_attr_name_value_pairs(px_attr_name_value_pairs.FIRST).ROW_IDENTIFIER
5293                                   ,l_attr_metadata_obj.ATTR_NAME
5294                                   ,null -- ATTR_VALUE_STR
5295                                   ,null -- ATTR_VALUE_NUM
5296                                   ,null -- ATTR_VALUE_DATE
5297                                   ,null -- ATTR_DISP_VALUE
5298                                   ,l_attr_metadata_obj.UNIT_OF_MEASURE_BASE
5299                                   ,-1   -- USER_ROW_IDENTIFIER
5300                                  );
5301 
5302               px_attr_name_value_pairs.EXTEND();
5303 --
5304 -- ASSUMPTION: this table does not need to be re-sorted by sequence, because we've
5305 -- passed the only place where sequence matters (i.e., Tokenized_Val_Set_Query)
5306 --
5307               px_attr_name_value_pairs(px_attr_name_value_pairs.LAST) := l_attr_data_obj;
5308             END;
5309           ELSE
5310 
5311             Debug_Msg('In Verify_All_Required_Attrs, non-passed required Attribute '||l_attr_metadata_obj.ATTR_DISP_NAME||' has no default value');
5312 
5313             l_token_table(1).TOKEN_VALUE := l_attr_metadata_obj.ATTR_DISP_NAME;
5314 
5315             ERROR_HANDLER.Add_Error_Message(
5316               p_message_name      => 'EGO_EF_NO_VAL_FOR_REQ_ATTR'
5317              ,p_application_id    => 'EGO'
5318              ,p_token_tbl         => l_token_table
5319              ,p_message_type      => FND_API.G_RET_STS_ERROR
5320              ,p_row_identifier    => G_USER_ROW_IDENTIFIER
5321              ,p_entity_id         => p_entity_id
5322              ,p_entity_index      => p_entity_index
5323              ,p_entity_code       => p_entity_code
5324              ,p_addto_fnd_stack   => G_ADD_ERRORS_TO_FND_STACK
5325             );
5326 
5327             l_has_all_required_attrs := FALSE;
5328 
5329           END IF;
5330         END IF;
5331       END IF;
5332 
5333       l_metadata_table_index := p_attr_metadata_table.NEXT(l_metadata_table_index);
5334     END LOOP;
5335 
5336     Debug_Msg('In Verify_All_Required_Attrs, done', 2);
5337 
5338     RETURN l_has_all_required_attrs;
5339 
5340 END Verify_All_Required_Attrs;
5341 
5342 ----------------------------------------------------------------------
5343 
5344 FUNCTION Get_Requested_Attr_Names (
5345         p_row_identifier                IN   NUMBER
5346        ,p_attr_group_disp_name          IN   VARCHAR2
5347        ,p_attr_name_list                IN   VARCHAR2
5348        ,p_attr_metadata_table           IN   EGO_ATTR_METADATA_TABLE
5349        ,p_entity_id                     IN   VARCHAR2
5350        ,p_entity_index                  IN   NUMBER
5351        ,p_entity_code                   IN   VARCHAR2
5352 )
5353 RETURN LOCAL_VARCHAR_TABLE
5354 IS
5355 
5356     l_attr_name_list         VARCHAR2(3000) := p_attr_name_list;
5357     l_attr_name_table        LOCAL_VARCHAR_TABLE;
5358     l_next_attr_name         VARCHAR2(30);
5359     l_candidate_attr         EGO_ATTR_METADATA_OBJ;
5360     l_token_table            ERROR_HANDLER.Token_Tbl_Type;
5361     l_metadata_table_index   NUMBER;
5362     l_found_bad_names        BOOLEAN := FALSE;
5363 
5364   BEGIN
5365 
5366     Debug_Msg('In Get_Requested_Attr_Names, starting', 2);
5367 
5368     IF (LENGTH(l_attr_name_list) > 0) THEN
5369       WHILE (LENGTH(l_attr_name_list) > 0)
5370       LOOP
5371 
5372         IF (INSTR(l_attr_name_list, ',') > 0) THEN
5373 
5374           l_next_attr_name := SUBSTR(l_attr_name_list, 1, INSTR(l_attr_name_list, ',') - 1);
5375           l_attr_name_list := SUBSTR(l_attr_name_list, INSTR(l_attr_name_list, ',') + 1);
5376 
5377         ELSE
5378 
5379           l_next_attr_name := l_attr_name_list;
5380           l_attr_name_list := '';
5381 
5382         END IF;
5383 
5384         l_next_attr_name := TRIM(l_next_attr_name);
5385 
5386         Debug_Msg('In Get_Requested_Attr_Names, trying to add '||l_next_attr_name||' to table', 3);
5387 
5388         l_candidate_attr := EGO_USER_ATTRS_COMMON_PVT.Find_Metadata_For_Attr(
5389                               p_attr_metadata_table => p_attr_metadata_table
5390                              ,p_attr_name           => l_next_attr_name
5391                             );
5392 
5393         IF (l_candidate_attr IS NOT NULL AND
5394             l_candidate_attr.ATTR_NAME IS NOT NULL) THEN
5395 
5396           l_attr_name_table(l_attr_name_table.COUNT+1) := l_next_attr_name;
5397 
5398         ELSE
5399 
5400           l_found_bad_names := TRUE;
5401 
5402           l_token_table(1).TOKEN_NAME := 'BAD_ATTR_NAME';
5403           l_token_table(1).TOKEN_VALUE := l_next_attr_name;
5404           l_token_table(2).TOKEN_NAME := 'AG_NAME';
5405           l_token_table(2).TOKEN_VALUE := p_attr_group_disp_name;
5406 
5407           ERROR_HANDLER.Add_Error_Message(
5408             p_message_name      => 'EGO_EF_ATTR_DOES_NOT_EXIST'
5409            ,p_application_id    => 'EGO'
5410            ,p_token_tbl         => l_token_table
5411            ,p_message_type      => FND_API.G_RET_STS_ERROR
5412            ,p_row_identifier    => p_row_identifier
5413            ,p_entity_id         => p_entity_id
5414            ,p_entity_index      => p_entity_index
5415            ,p_entity_code       => p_entity_code
5416            ,p_addto_fnd_stack   => G_ADD_ERRORS_TO_FND_STACK
5417           );
5418 
5419         END IF;
5420 
5421       END LOOP;
5422     ELSE -- if the list is empty, we return all Attributes in the Attribute Group
5423      --bug 5494760 the p_attr_metadata_table can be null, if no attribute
5424      -- is created under the attribute group.
5425      IF p_attr_metadata_table IS NOT NULL THEN
5426       l_metadata_table_index := p_attr_metadata_table.FIRST;
5427       WHILE (l_metadata_table_index <= p_attr_metadata_table.LAST)
5428       LOOP
5429         l_attr_name_table(l_attr_name_table.COUNT+1) := p_attr_metadata_table(l_metadata_table_index).ATTR_NAME;
5430         l_metadata_table_index := p_attr_metadata_table.NEXT(l_metadata_table_index);
5431       END LOOP;
5432      END IF;--p_attr_metadata_table IS NOT NULL
5433     END IF;
5434 
5435     -- If we fail, we need to pass something back to indicate that failure
5436     IF (l_found_bad_names) THEN
5437       l_attr_name_table(-1) := 'FAILED';
5438     END IF;
5439 
5440     Debug_Msg('In Get_Requested_Attr_Names, done', 2);
5441 
5442     RETURN l_attr_name_table;
5443 
5444 END Get_Requested_Attr_Names;
5445 
5446 ----------------------------------------------------------------------
5447 
5448 PROCEDURE Generate_Attr_Int_Values (
5449         p_attr_group_metadata_obj       IN   EGO_ATTR_GROUP_METADATA_OBJ
5450        ,p_ext_table_metadata_obj        IN   EGO_EXT_TABLE_METADATA_OBJ
5451        ,p_pk_column_name_value_pairs    IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
5452        ,p_data_level_name_value_pairs   IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
5453        ,p_entity_id                     IN   VARCHAR2   DEFAULT NULL
5454        ,p_entity_index                  IN   NUMBER     DEFAULT NULL
5455        ,p_entity_code                   IN   VARCHAR2   DEFAULT NULL
5456        ,px_attr_name_value_pairs        IN OUT NOCOPY EGO_USER_ATTR_DATA_TABLE
5457        ,x_return_status                 OUT NOCOPY VARCHAR2
5458 ) IS
5459 
5460     l_token_table            ERROR_HANDLER.Token_Tbl_Type;
5461     l_attr_value_index       NUMBER;
5462     l_attr_metadata_obj      EGO_ATTR_METADATA_OBJ;
5463     l_int_value              VARCHAR2(1000);
5464     l_err_msg_name           VARCHAR2(30);
5465 
5466   BEGIN
5467 
5468     Debug_Msg('In Generate_Attr_Int_Values, starting', 2);
5469 
5470     IF (px_attr_name_value_pairs IS NOT NULL AND
5471         px_attr_name_value_pairs.COUNT > 0) THEN
5472       l_attr_value_index := px_attr_name_value_pairs.FIRST;
5473       WHILE (l_attr_value_index <= px_attr_name_value_pairs.LAST)
5474       LOOP
5475 
5476         l_attr_metadata_obj := EGO_USER_ATTRS_COMMON_PVT.Find_Metadata_For_Attr(
5477                                  p_attr_metadata_table => p_attr_group_metadata_obj.attr_metadata_table
5478                                 ,p_attr_name           => px_attr_name_value_pairs(l_attr_value_index).ATTR_NAME
5479                                );
5480 
5481         ----------------------------------------------------------------------------
5482         -- If the Attribute has a Value Set of a type that has different internal --
5483         -- and display values, we only want to try getting the internal value if  --
5484         -- the caller has passed in the display value and nothing else; otherwise --
5485         -- we want to use the passed-in internal value and thus avoid a query.    --
5486         ----------------------------------------------------------------------------
5487         IF ((l_attr_metadata_obj.VALIDATION_CODE = EGO_EXT_FWK_PUB.G_INDEPENDENT_VALIDATION_CODE OR
5488              l_attr_metadata_obj.VALIDATION_CODE = EGO_EXT_FWK_PUB.G_TRANS_IND_VALIDATION_CODE OR
5489              l_attr_metadata_obj.VALIDATION_CODE = EGO_EXT_FWK_PUB.G_TABLE_VALIDATION_CODE) AND
5490             (px_attr_name_value_pairs(l_attr_value_index).ATTR_DISP_VALUE IS NOT NULL) AND
5491             (px_attr_name_value_pairs(l_attr_value_index).ATTR_VALUE_STR IS NULL AND
5492              px_attr_name_value_pairs(l_attr_value_index).ATTR_VALUE_NUM IS NULL AND
5493              px_attr_name_value_pairs(l_attr_value_index).ATTR_VALUE_DATE IS NULL)) THEN
5494 
5495           l_int_value := Get_Int_Val_For_Disp_Val(
5496                            p_attr_metadata_obj             => l_attr_metadata_obj
5497                           ,p_attr_value_obj                => px_attr_name_value_pairs(l_attr_value_index)
5498                           ,p_attr_group_metadata_obj       => p_attr_group_metadata_obj
5499                           ,p_ext_table_metadata_obj        => p_ext_table_metadata_obj
5500                           ,p_pk_column_name_value_pairs    => p_pk_column_name_value_pairs
5501                           ,p_data_level_name_value_pairs   => p_data_level_name_value_pairs
5502                           ,p_entity_id                     => p_entity_id
5503                           ,p_entity_index                  => p_entity_index
5504                           ,p_entity_code                   => p_entity_code
5505                           ,p_attr_name_value_pairs         => px_attr_name_value_pairs
5506                          );
5507 
5508           IF (l_int_value IS NOT NULL) THEN
5509             IF (l_attr_metadata_obj.DATA_TYPE_CODE IS NULL OR
5510                 l_attr_metadata_obj.DATA_TYPE_CODE = EGO_EXT_FWK_PUB.G_CHAR_DATA_TYPE OR
5511                 l_attr_metadata_obj.DATA_TYPE_CODE = EGO_EXT_FWK_PUB.G_TRANS_TEXT_DATA_TYPE) THEN
5512               px_attr_name_value_pairs(l_attr_value_index).ATTR_VALUE_STR := l_int_value;
5513             ELSIF (l_attr_metadata_obj.DATA_TYPE_CODE = EGO_EXT_FWK_PUB.G_NUMBER_DATA_TYPE) THEN
5514               px_attr_name_value_pairs(l_attr_value_index).ATTR_VALUE_NUM := TO_NUMBER(l_int_value);
5515             ELSIF (l_attr_metadata_obj.DATA_TYPE_CODE = EGO_EXT_FWK_PUB.G_DATE_DATA_TYPE) THEN
5516               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));
5517             ELSIF (l_attr_metadata_obj.DATA_TYPE_CODE = EGO_EXT_FWK_PUB.G_DATE_TIME_DATA_TYPE) THEN
5518               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);
5519             END IF;
5520           ELSE
5521 
5522             l_err_msg_name := 'EGO_EF_INDEPENDENT_VS_VIOLATED';
5523 
5524             l_token_table(1).TOKEN_NAME := 'VALUE';
5525             l_token_table(1).TOKEN_VALUE := px_attr_name_value_pairs(l_attr_value_index).ATTR_DISP_VALUE;
5526             l_token_table(2).TOKEN_NAME := 'ATTR_NAME';
5527             l_token_table(2).TOKEN_VALUE := l_attr_metadata_obj.ATTR_DISP_NAME;
5528             l_token_table(3).TOKEN_NAME := 'AG_NAME';
5529             l_token_table(3).TOKEN_VALUE := p_attr_group_metadata_obj.ATTR_GROUP_DISP_NAME;
5530 
5531             x_return_status := FND_API.G_RET_STS_ERROR;
5532 
5533           END IF;
5534 
5535         -----------------------------------------------------------------------------------
5536         -- We also check for the (common) case where the Attribute doesn't have distinct --
5537         -- internal and display values but the user passed the value as ATTR_DISP_VALUE  --
5538         -- anyway, just for convenience; in this case, we try to interpret the passed-in --
5539         -- value as being of the appropriate data type.  If we cannot do so, we report   --
5540         -- the problem,                                                                  --
5541         -----------------------------------------------------------------------------------
5542         ELSIF (Disp_Val_Replacement_Is_Bad(l_attr_metadata_obj
5543                                           ,px_attr_name_value_pairs(l_attr_value_index))) THEN
5544 
5545           l_err_msg_name := 'EGO_EF_DATA_TYPE_INCORRECT';
5546 
5547           l_token_table(1).TOKEN_NAME := 'ATTR_NAME';
5548           l_token_table(1).TOKEN_VALUE := l_attr_metadata_obj.ATTR_DISP_NAME;
5549           l_token_table(2).TOKEN_NAME := 'AG_NAME';
5550           l_token_table(2).TOKEN_VALUE := p_attr_group_metadata_obj.ATTR_GROUP_DISP_NAME;
5551           l_token_table(3).TOKEN_NAME := 'DATA_TYPE';
5552           l_token_table(3).TOKEN_VALUE := l_attr_metadata_obj.DATA_TYPE_MEANING;
5553           l_token_table(4).TOKEN_NAME := 'VALUE';
5554           l_token_table(4).TOKEN_VALUE := px_attr_name_value_pairs(l_attr_value_index).ATTR_DISP_VALUE;
5555 
5556           x_return_status := FND_API.G_RET_STS_ERROR;
5557 
5558 
5559         ------------------------------------------------------------------------------
5560         -- Finally, we check for the much less common case where the Attribute is a --
5561         -- Date, but the value passed in is a $SYSDATE$ expression of some sort; in --
5562         -- such a case, we want to replace the expression with the appropriate Date --
5563         ------------------------------------------------------------------------------
5564         ELSIF ((l_attr_metadata_obj.DATA_TYPE_CODE = EGO_EXT_FWK_PUB.G_DATE_DATA_TYPE OR
5565                 l_attr_metadata_obj.DATA_TYPE_CODE = EGO_EXT_FWK_PUB.G_DATE_TIME_DATA_TYPE)
5566                 AND
5567                (px_attr_name_value_pairs(l_attr_value_index).ATTR_VALUE_STR IS NOT NULL AND
5568                 px_attr_name_value_pairs(l_attr_value_index).ATTR_VALUE_DATE IS NULL)) THEN
5569 
5570           DECLARE
5571             l_formatted_expression   VARCHAR2(150);
5572           BEGIN
5573             l_formatted_expression := Format_Sysdate_Expression(px_attr_name_value_pairs(l_attr_value_index).ATTR_VALUE_STR);
5574 
5575             IF (l_attr_metadata_obj.DATA_TYPE_CODE = EGO_EXT_FWK_PUB.G_DATE_DATA_TYPE) THEN
5576               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));
5577             ELSE
5578               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);
5579             END IF;
5580 
5581           EXCEPTION
5582             WHEN OTHERS THEN
5583               l_err_msg_name := 'EGO_EF_DATA_TYPE_INCORRECT';
5584               l_token_table(1).TOKEN_NAME := 'ATTR_NAME';
5585               l_token_table(1).TOKEN_VALUE := l_attr_metadata_obj.ATTR_DISP_NAME;
5586               l_token_table(2).TOKEN_NAME := 'AG_NAME';
5587               l_token_table(2).TOKEN_VALUE := p_attr_group_metadata_obj.ATTR_GROUP_DISP_NAME;
5588               l_token_table(3).TOKEN_NAME := 'DATA_TYPE';
5589               l_token_table(3).TOKEN_VALUE := l_attr_metadata_obj.DATA_TYPE_MEANING;
5590               l_token_table(4).TOKEN_NAME := 'VALUE';
5591               l_token_table(4).TOKEN_VALUE := px_attr_name_value_pairs(l_attr_value_index).ATTR_VALUE_STR;
5592               x_return_status := FND_API.G_RET_STS_ERROR;
5593           END;
5594         END IF;
5595 
5596         ----------------------------------------------------------------------------
5597         -- If processing for this Attribute failed, we log the error but continue --
5598         -- to process remaining Attributes (so we can report all errors at once)  --
5599         ----------------------------------------------------------------------------
5600         IF (l_err_msg_name IS NOT NULL) THEN
5601 
5602           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);
5603 
5604           ERROR_HANDLER.Add_Error_Message(
5605             p_message_name      => l_err_msg_name
5606            ,p_application_id    => 'EGO'
5607            ,p_token_tbl         => l_token_table
5608            ,p_message_type      => FND_API.G_RET_STS_ERROR
5609            ,p_row_identifier    => G_USER_ROW_IDENTIFIER
5610            ,p_entity_id         => p_entity_id
5611            ,p_entity_index      => p_entity_index
5612            ,p_entity_code       => p_entity_code
5613            ,p_addto_fnd_stack   => G_ADD_ERRORS_TO_FND_STACK
5614           );
5615         END IF;
5616 
5617         l_err_msg_name := NULL;
5618         l_token_table.DELETE();
5619         l_attr_value_index := px_attr_name_value_pairs.NEXT(l_attr_value_index);
5620       END LOOP;
5621     END IF;
5622 
5623     Debug_Msg('In Generate_Attr_Int_Values, done', 2);
5624 
5625 END Generate_Attr_Int_Values;
5626 
5627 ----------------------------------------------------------------------
5628 PROCEDURE Raise_WF_Event_If_Enabled (
5629         p_dml_type                      IN   VARCHAR2
5630        ,p_attr_group_metadata_obj       IN   EGO_ATTR_GROUP_METADATA_OBJ
5631        ,p_extension_id                  IN   NUMBER
5632        ,p_pk_column_name_value_pairs    IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
5633        ,p_data_level_name_value_pairs   IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
5634        ,p_entity_id                     IN   VARCHAR2
5635        ,p_entity_index                  IN   NUMBER
5636        ,p_entity_code                   IN   VARCHAR2
5637        ,p_pre_event_flag                IN   VARCHAR2 DEFAULT NULL  --4105841
5638        ,p_data_level_id                 IN   VARCHAR2 DEFAULT NULL
5639        ,px_attr_diffs                   IN   EGO_USER_ATTR_DIFF_TABLE
5640 ) IS
5641 
5642     l_api_name               CONSTANT VARCHAR2(30) := 'Raise_WF_Event_If_Enabled';
5643     l_event_name             VARCHAR2(240);
5644     l_is_event_enabled_flag  VARCHAR2(1);
5645     l_primary_key_1_col_name VARCHAR2(30);
5646     l_primary_key_1_value    VARCHAR2(150);
5647     l_primary_key_2_col_name VARCHAR2(30);
5648     l_primary_key_2_value    VARCHAR2(150);
5649     l_primary_key_3_col_name VARCHAR2(30);
5650     l_primary_key_3_value    VARCHAR2(150);
5651     l_primary_key_4_col_name VARCHAR2(30);
5652     l_primary_key_4_value    VARCHAR2(150);
5653     l_primary_key_5_col_name VARCHAR2(30);
5654     l_primary_key_5_value    VARCHAR2(150);
5655     l_data_level_1_col_name  VARCHAR2(30);
5656     l_data_level_1_value     VARCHAR2(150);
5657     l_data_level_2_col_name  VARCHAR2(30);
5658     l_data_level_2_value     VARCHAR2(150);
5659     l_data_level_3_col_name  VARCHAR2(30);
5660     l_data_level_3_value     VARCHAR2(150);
5661     l_data_level_4_col_name  VARCHAR2(30);
5662     l_data_level_4_value     VARCHAR2(150);
5663     l_data_level_5_col_name  VARCHAR2(30);
5664     l_data_level_5_value     VARCHAR2(150);
5665 
5666     l_event_key              VARCHAR2(240);
5667     l_attr_name              VARCHAR2(240);
5668     --Start 4105841 Business Event Enh
5669     l_attr_name_val_index    NUMBER;
5670     l_attrs_index            NUMBER;
5671     l_attr_rec               EGO_ATTR_REC;
5672     l_attr_name_val          EGO_ATTR_TABLE;
5673     l_dml_type               VARCHAR2(10);
5674     l_dummy                  NUMBER;
5675     --End 4105841
5676     l_curr_attr_metadata_obj        EGO_ATTR_METADATA_OBJ; -- abedajna, Bug 6134504
5677   BEGIN
5678 
5679 
5680     ----------------------------------------------------------------------
5681     -- If there is a Business Event defined for this Attr Group Type... --
5682     ----------------------------------------------------------------------
5683     Debug_Msg( l_api_name ||' started');
5684     IF p_pre_event_flag IS NULL THEN
5685       BEGIN
5686         SELECT BUSINESS_EVENT_NAME
5687           INTO l_event_name
5688           FROM EGO_FND_DESC_FLEXS_EXT
5689          WHERE APPLICATION_ID = p_attr_group_metadata_obj.APPLICATION_ID
5690            AND DESCRIPTIVE_FLEXFIELD_NAME = p_attr_group_metadata_obj.ATTR_GROUP_TYPE;
5691       EXCEPTION
5692         WHEN NO_DATA_FOUND THEN
5693           NULL;
5694       END;
5695     ELSE
5696       BEGIN --Added for 4105841
5697         SELECT PRE_BUSINESS_EVENT_NAME
5698           INTO l_event_name
5699           FROM EGO_FND_DESC_FLEXS_EXT
5700          WHERE APPLICATION_ID = p_attr_group_metadata_obj.APPLICATION_ID
5701            AND DESCRIPTIVE_FLEXFIELD_NAME = p_attr_group_metadata_obj.ATTR_GROUP_TYPE;
5702       EXCEPTION
5703         WHEN NO_DATA_FOUND THEN
5704           NULL;
5705       END;
5706     END IF;
5707 
5708     IF (l_event_name IS NOT NULL) THEN
5709       -----------------------------------------------------------
5710       -- ...and if this Attr Group is enabled for the Event... --
5711       -----------------------------------------------------------
5712 
5713 
5714       IF p_pre_event_flag IS NULL THEN
5715         /*
5716   SELECT BUSINESS_EVENT_FLAG
5717           INTO l_is_event_enabled_flag
5718           FROM EGO_FND_DSC_FLX_CTX_EXT
5719          WHERE ATTR_GROUP_ID = p_attr_group_metadata_obj.ATTR_GROUP_ID;*/
5720         SELECT COUNT(*)
5721           INTO l_dummy
5722           FROM EGO_ATTR_GROUP_DL
5723          WHERE ATTR_GROUP_ID = p_attr_group_metadata_obj.ATTR_GROUP_ID
5724            AND DATA_LEVEL_ID = NVL(p_data_level_id,DATA_LEVEL_ID)
5725            AND RAISE_POST_EVENT = 'Y'; -- abedajna 6137035
5726         IF (l_dummy > 0) THEN
5727           l_is_event_enabled_flag := 'Y';
5728         ELSE
5729           l_is_event_enabled_flag := 'N';
5730         END IF;
5731 
5732       ELSE  --Added for 4105841
5733       /*
5734         SELECT PRE_BUSINESS_EVENT_FLAG
5735           INTO l_is_event_enabled_flag
5736           FROM EGO_FND_DSC_FLX_CTX_EXT
5737          WHERE ATTR_GROUP_ID = p_attr_group_metadata_obj.ATTR_GROUP_ID;*/
5738         SELECT COUNT(*)
5739           INTO l_dummy
5740           FROM EGO_ATTR_GROUP_DL
5741          WHERE ATTR_GROUP_ID = p_attr_group_metadata_obj.ATTR_GROUP_ID
5742            AND DATA_LEVEL_ID = NVL(p_data_level_id,DATA_LEVEL_ID)
5743            AND RAISE_PRE_EVENT = 'Y';  --abedajna 6137035
5744         IF (l_dummy > 0) THEN
5745           l_is_event_enabled_flag := 'Y';
5746         ELSE
5747           l_is_event_enabled_flag := 'N';
5748         END IF;
5749       END IF;
5750 
5751     END IF;
5752 
5753     IF (l_is_event_enabled_flag = 'Y') THEN
5754 
5755         ------------------------------------------------------------
5756         -- ...then we gather PKs and data levels in order to call --
5757         -- our wrapper to the WF code to raise the Business Event --
5758         ------------------------------------------------------------
5759       l_primary_key_1_col_name := p_pk_column_name_value_pairs(1).NAME;
5760       l_primary_key_1_value := p_pk_column_name_value_pairs(1).VALUE;
5761 
5762       IF (p_pk_column_name_value_pairs.COUNT > 1 AND
5763           p_pk_column_name_value_pairs(2) IS NOT NULL) THEN
5764 
5765         l_primary_key_2_col_name := p_pk_column_name_value_pairs(2).NAME;
5766         l_primary_key_2_value := p_pk_column_name_value_pairs(2).VALUE;
5767 
5768         IF (p_pk_column_name_value_pairs.COUNT > 2 AND
5769             p_pk_column_name_value_pairs(3) IS NOT NULL) THEN
5770 
5771           l_primary_key_3_col_name := p_pk_column_name_value_pairs(3).NAME;
5772           l_primary_key_3_value := p_pk_column_name_value_pairs(3).VALUE;
5773 
5774           IF (p_pk_column_name_value_pairs.COUNT > 3 AND
5775               p_pk_column_name_value_pairs(4) IS NOT NULL) THEN
5776 
5777             l_primary_key_4_col_name := p_pk_column_name_value_pairs(4).NAME;
5778             l_primary_key_4_value := p_pk_column_name_value_pairs(4).VALUE;
5779 
5780             IF (p_pk_column_name_value_pairs.COUNT > 4 AND
5781                 p_pk_column_name_value_pairs(5) IS NOT NULL) THEN
5782 
5783               l_primary_key_5_col_name := p_pk_column_name_value_pairs(5).NAME;
5784               l_primary_key_5_value := p_pk_column_name_value_pairs(5).VALUE;
5785 
5786             END IF;
5787           END IF;
5788         END IF;
5789       END IF;
5790 
5791       IF (p_data_level_name_value_pairs IS NOT NULL AND
5792           p_data_level_name_value_pairs.COUNT > 0 AND
5793           p_data_level_name_value_pairs(1) IS NOT NULL) THEN
5794 
5795         l_data_level_1_col_name := p_data_level_name_value_pairs(1).NAME;
5796         l_data_level_1_value := p_data_level_name_value_pairs(1).VALUE;
5797 
5798         IF (p_data_level_name_value_pairs.COUNT > 1 AND
5799             p_data_level_name_value_pairs(2) IS NOT NULL) THEN
5800 
5801           l_data_level_2_col_name := p_data_level_name_value_pairs(2).NAME;
5802           l_data_level_2_value := p_data_level_name_value_pairs(2).VALUE;
5803 
5804           IF (p_data_level_name_value_pairs.COUNT > 2 AND
5805               p_data_level_name_value_pairs(3) IS NOT NULL) THEN
5806 
5807             l_data_level_3_col_name := p_data_level_name_value_pairs(3).NAME;
5808             l_data_level_3_value := p_data_level_name_value_pairs(3).VALUE;
5809 
5810               IF (p_data_level_name_value_pairs.COUNT > 3 AND
5811                   p_data_level_name_value_pairs(4) IS NOT NULL) THEN
5812 
5813                 l_data_level_4_col_name := p_data_level_name_value_pairs(4).NAME;
5814                 l_data_level_4_value := p_data_level_name_value_pairs(4).VALUE;
5815 
5816                  IF (p_data_level_name_value_pairs.COUNT > 4 AND
5817                      p_data_level_name_value_pairs(5) IS NOT NULL) THEN
5818 
5819                    l_data_level_5_col_name := p_data_level_name_value_pairs(5).NAME;
5820                    l_data_level_5_value := p_data_level_name_value_pairs(5).VALUE;
5821                  END IF;
5822               END IF;
5823           END IF;
5824         END IF;
5825       END IF;
5826 
5827       --------------------------------------------------------------------
5828       -- To generate a unique instance key, we take the first 225 chars --
5829       -- of the Event name and append a timestamp of the current time   --
5830       --------------------------------------------------------------------
5831       l_event_key := SUBSTRB(l_event_name, 1, 225) || '-' || TO_CHAR(SYSDATE, 'J.SSSSS') || TO_CHAR(dbms_random.value(1,100));
5832 
5833       Debug_Msg('In Raise_WF_Event_If_Enabled, raising event with key '||l_event_key||' and DML_TYPE '||p_dml_type, 3);
5834       -- Start 4105841
5835 
5836       l_attrs_index    := px_attr_diffs.FIRST;
5837       l_attr_name_val  := EGO_ATTR_TABLE();
5838       l_attr_rec       := EGO_ATTR_REC('','');
5839       ---  In case of update compare and add...the changed ones....
5840       l_dml_type := p_dml_type;
5841       IF l_dml_type = 'UPDATE' AND G_SYNC_TO_UPDATE = 'Y' THEN
5842         l_dml_type := 'CREATE';
5843 /*        IF p_pre_event_flag IS NULL THEN --modify it after raising post event.
5844           G_SYNC_TO_UPDATE := 'N';
5845         END IF;     */
5846       END IF;
5847 
5848       IF(l_dml_type = 'UPDATE') THEN
5849         WHILE (l_attrs_index <= px_attr_diffs.LAST) LOOP
5850           l_attr_rec.attr_name := px_attr_diffs(l_attrs_index).attr_name;
5851 -- abedajna Bug 6134504 begin
5852             l_curr_attr_metadata_obj := EGO_USER_ATTRS_COMMON_PVT.Find_Metadata_For_Attr(
5853                                       p_attr_group_metadata_obj.attr_metadata_table
5854                                      ,l_attr_rec.attr_name );
5855 -- abedajna Bug 6134504 end
5856           IF(NVL(px_attr_diffs(L_ATTRS_INDEX).OLD_ATTR_VALUE_STR,FND_API.G_MISS_CHAR)<>
5857              NVL(px_attr_diffs(L_ATTRS_INDEX).NEW_ATTR_VALUE_STR,FND_API.G_MISS_CHAR)) THEN
5858             l_attr_name_val.EXTEND();
5859             l_attr_rec.attr_value := px_attr_diffs(L_ATTRS_INDEX).NEW_ATTR_VALUE_STR;
5860             l_attr_name_val(l_attr_name_val.LAST) := l_attr_rec;
5861           ELSIF ( NVL(px_attr_diffs(L_ATTRS_INDEX).OLD_ATTR_VALUE_NUM,FND_API.G_MISS_NUM)<>
5862                   NVL(px_attr_diffs(L_ATTRS_INDEX).NEW_ATTR_VALUE_NUM,FND_API.G_MISS_NUM))THEN
5863             l_attr_name_val.EXTEND();
5864             l_attr_rec.attr_value := to_char(px_attr_diffs(L_ATTRS_INDEX).NEW_ATTR_VALUE_NUM);
5865             l_attr_name_val(l_attr_name_val.LAST) :=l_attr_rec;
5866           ELSIF (NVL(px_attr_diffs(L_ATTRS_INDEX).OLD_ATTR_VALUE_DATE,FND_API.G_MISS_DATE)<>
5867                  NVL(px_attr_diffs(L_ATTRS_INDEX).NEW_ATTR_VALUE_DATE,FND_API.G_MISS_DATE))THEN
5868             l_attr_name_val.EXTEND();
5869 --          l_attr_rec.attr_value := to_char(px_attr_diffs(L_ATTRS_INDEX).NEW_ATTR_VALUE_DATE);
5870 -- abedajna Bug 6134504 begin
5871             if ( l_curr_attr_metadata_obj.DATA_TYPE_CODE = EGO_EXT_FWK_PUB.G_DATE_TIME_DATA_TYPE ) then -- timestamp
5872                 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);
5873             elsif ( l_curr_attr_metadata_obj.DATA_TYPE_CODE = EGO_EXT_FWK_PUB.G_DATE_DATA_TYPE) then -- date
5874                 l_attr_rec.attr_value := to_char(px_attr_diffs(L_ATTRS_INDEX).NEW_ATTR_VALUE_DATE);
5875             end if;
5876 -- abedajna Bug 6134504 end
5877             l_attr_name_val(l_attr_name_val.LAST) :=  l_attr_rec;
5878           END IF;
5879           l_attrs_index := px_attr_diffs.NEXT(l_attrs_index);
5880         END LOOP;
5881 
5882       ---for create add all attributes
5883       ELSIF(l_dml_type = 'CREATE') then
5884         WHILE (l_attrs_index <= px_attr_diffs.LAST) LOOP
5885           l_attr_rec.attr_name := px_attr_diffs(l_attrs_index).attr_name;
5886 -- abedajna Bug 6134504 begin
5887             l_curr_attr_metadata_obj := EGO_USER_ATTRS_COMMON_PVT.Find_Metadata_For_Attr(
5888                                       p_attr_group_metadata_obj.attr_metadata_table
5889                                      ,l_attr_rec.attr_name );
5890 -- abedajna Bug 6134504 end
5891           IF px_attr_diffs(L_ATTRS_INDEX).NEW_ATTR_VALUE_STR IS NOT NULL  THEN
5892             l_attr_rec.attr_value := px_attr_diffs(L_ATTRS_INDEX).NEW_ATTR_VALUE_STR;
5893           ELSIF px_attr_diffs(L_ATTRS_INDEX).NEW_ATTR_VALUE_NUM IS NOT NULL THEN
5894             l_attr_rec.attr_value := TO_CHAR(px_attr_diffs(L_ATTRS_INDEX).NEW_ATTR_VALUE_num);
5895           ELSIF px_attr_diffs(L_ATTRS_INDEX).NEW_ATTR_VALUE_DATE IS NOT NULL THEN
5896 --            l_attr_rec.attr_value := TO_CHAR(px_attr_diffs(L_ATTRS_INDEX).NEW_ATTR_VALUE_DATE);
5897 -- abedajna Bug 6134504 begin
5898             if ( l_curr_attr_metadata_obj.DATA_TYPE_CODE = EGO_EXT_FWK_PUB.G_DATE_TIME_DATA_TYPE ) then -- timestamp
5899                 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);
5900             elsif ( l_curr_attr_metadata_obj.DATA_TYPE_CODE = EGO_EXT_FWK_PUB.G_DATE_DATA_TYPE) then -- date
5901                 l_attr_rec.attr_value := to_char(px_attr_diffs(L_ATTRS_INDEX).NEW_ATTR_VALUE_DATE);
5902             end if;
5903 -- abedajna Bug 6134504 end
5904           ELSE
5905             l_attr_rec.attr_value := null;
5906           END IF;
5907 
5908           l_attr_name_val.EXTEND();
5909           l_attr_name_val(l_attr_name_val.LAST) :=  l_attr_rec;
5910           l_attrs_index := px_attr_diffs.NEXT(l_attrs_index);
5911         END LOOP;
5912 
5913      ---for delete add all 'old' attributes
5914      ELSIF(l_dml_type = 'DELETE') then
5915         WHILE (l_attrs_index <= px_attr_diffs.LAST) LOOP
5916           l_attr_rec.attr_name := px_attr_diffs(l_attrs_index).attr_name;
5917 -- abedajna Bug 6134504 begin
5918             l_curr_attr_metadata_obj := EGO_USER_ATTRS_COMMON_PVT.Find_Metadata_For_Attr(
5919                                       p_attr_group_metadata_obj.attr_metadata_table
5920                                      ,l_attr_rec.attr_name );
5921 -- abedajna Bug 6134504 end
5922           IF px_attr_diffs(L_ATTRS_INDEX).OLD_ATTR_VALUE_STR IS NOT NULL  THEN
5923             l_attr_rec.attr_value := px_attr_diffs(L_ATTRS_INDEX).OLD_ATTR_VALUE_STR;
5924           ELSIF px_attr_diffs(L_ATTRS_INDEX).OLD_ATTR_VALUE_NUM IS NOT NULL THEN
5925             l_attr_rec.attr_value := TO_CHAR(px_attr_diffs(L_ATTRS_INDEX).OLD_ATTR_VALUE_num);
5926           ELSIF px_attr_diffs(L_ATTRS_INDEX).OLD_ATTR_VALUE_DATE IS NOT NULL THEN
5927 --            l_attr_rec.attr_value := TO_CHAR(px_attr_diffs(L_ATTRS_INDEX).OLD_ATTR_VALUE_DATE);
5928 -- abedajna Bug 6134504 begin
5929             if ( l_curr_attr_metadata_obj.DATA_TYPE_CODE = EGO_EXT_FWK_PUB.G_DATE_TIME_DATA_TYPE) then -- timestamp
5930                 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);
5931             elsif ( l_curr_attr_metadata_obj.DATA_TYPE_CODE = EGO_EXT_FWK_PUB.G_DATE_DATA_TYPE) then -- date
5932                 l_attr_rec.attr_value := to_char(px_attr_diffs(L_ATTRS_INDEX).OLD_ATTR_VALUE_DATE);
5933             end if;
5934 -- abedajna Bug 6134504 end
5935           ELSE
5936             l_attr_rec.attr_value := null;
5937           END IF;
5938 
5939           l_attr_name_val.EXTEND();
5940           l_attr_name_val(l_attr_name_val.LAST) :=  l_attr_rec;
5941           l_attrs_index := px_attr_diffs.NEXT(l_attrs_index);
5942         END LOOP;
5943       END IF;
5944 
5945       ---Raise the event
5946       IF l_attr_name_val.count() > 0 THEN --if attributes are there raise it,
5947         IF p_pre_event_flag IS NULL THEN --Raise post Event
5948            EGO_WF_WRAPPER_PVT.Raise_WF_Business_Event(
5949             p_event_name                  => l_event_name
5950            ,p_event_key                   => l_event_key
5951            ,p_dml_type                    => l_dml_type
5952            ,p_attr_group_name             => p_attr_group_metadata_obj.ATTR_GROUP_NAME
5953            ,p_extension_id                => p_extension_id
5954            ,p_primary_key_1_col_name      => l_primary_key_1_col_name
5955            ,p_primary_key_1_value         => l_primary_key_1_value
5956            ,p_primary_key_2_col_name      => l_primary_key_2_col_name
5957            ,p_primary_key_2_value         => l_primary_key_2_value
5958            ,p_primary_key_3_col_name      => l_primary_key_3_col_name
5959            ,p_primary_key_3_value         => l_primary_key_3_value
5960            ,p_primary_key_4_col_name      => l_primary_key_4_col_name
5961            ,p_primary_key_4_value         => l_primary_key_4_value
5962            ,p_primary_key_5_col_name      => l_primary_key_5_col_name
5963            ,p_primary_key_5_value         => l_primary_key_5_value
5964            ,p_data_level_id               => p_data_level_id
5965            ,p_data_level_1_col_name       => l_data_level_1_col_name
5966            ,p_data_level_1_value          => l_data_level_1_value
5967            ,p_data_level_2_col_name       => l_data_level_2_col_name
5968            ,p_data_level_2_value          => l_data_level_2_value
5969            ,p_data_level_3_col_name       => l_data_level_3_col_name
5970            ,p_data_level_3_value          => l_data_level_3_value
5971            ,p_data_level_4_col_name       => l_data_level_4_col_name
5972            ,p_data_level_4_value          => l_data_level_4_value
5973            ,p_data_level_5_col_name       => l_data_level_5_col_name
5974            ,p_data_level_5_value          => l_data_level_5_value
5975            ,p_user_row_identifier         => G_USER_ROW_IDENTIFIER
5976            ,p_entity_id                   => p_entity_id
5977            ,p_entity_index                => p_entity_index
5978            ,p_entity_code                 => p_entity_code
5979            ,p_add_errors_to_fnd_stack     => G_ADD_ERRORS_TO_FND_STACK
5980           );
5981         ELSE --raise PreEvent
5982           EGO_WF_WRAPPER_PVT.Raise_WF_Business_Event(
5983             p_event_name                  => l_event_name
5984            ,p_event_key                   => l_event_key
5985            ,p_pre_event_flag              => 'T'
5986            ,p_dml_type                    => l_dml_type
5987            ,p_attr_group_name             => p_attr_group_metadata_obj.ATTR_GROUP_NAME
5988            ,p_extension_id                => p_extension_id
5989            ,p_primary_key_1_col_name      => l_primary_key_1_col_name
5990            ,p_primary_key_1_value         => l_primary_key_1_value
5991            ,p_primary_key_2_col_name      => l_primary_key_2_col_name
5992            ,p_primary_key_2_value         => l_primary_key_2_value
5993            ,p_primary_key_3_col_name      => l_primary_key_3_col_name
5994            ,p_primary_key_3_value         => l_primary_key_3_value
5995            ,p_primary_key_4_col_name      => l_primary_key_4_col_name
5996            ,p_primary_key_4_value         => l_primary_key_4_value
5997            ,p_primary_key_5_col_name      => l_primary_key_5_col_name
5998            ,p_primary_key_5_value         => l_primary_key_5_value
5999            ,p_data_level_id               => p_data_level_id
6000            ,p_data_level_1_col_name       => l_data_level_1_col_name
6001            ,p_data_level_1_value          => l_data_level_1_value
6002            ,p_data_level_2_col_name       => l_data_level_2_col_name
6003            ,p_data_level_2_value          => l_data_level_2_value
6004            ,p_data_level_3_col_name       => l_data_level_3_col_name
6005            ,p_data_level_3_value          => l_data_level_3_value
6006            ,p_data_level_4_col_name       => l_data_level_4_col_name
6007            ,p_data_level_4_value          => l_data_level_4_value
6008            ,p_data_level_5_col_name       => l_data_level_5_col_name
6009            ,p_data_level_5_value          => l_data_level_5_value
6010            ,p_user_row_identifier         => G_USER_ROW_IDENTIFIER
6011            ,p_attr_name_val_tbl           => l_attr_name_val
6012            ,p_entity_id                   => p_entity_id
6013            ,p_entity_index                => p_entity_index
6014            ,p_entity_code                 => p_entity_code
6015            ,p_add_errors_to_fnd_stack     => G_ADD_ERRORS_TO_FND_STACK
6016           );
6017         END IF;--end pre event flag.
6018       END IF; ---end count attributes.
6019     END IF;--end if if flag enabled
6020     Debug_Msg( l_api_name ||' done ');
6021   EXCEPTION
6022     --- If subscription fails...don't add to the stack, already added in EGO_WF_WRAPPER_PVT
6023     WHEN EGO_USER_ATTRS_COMMON_PVT.G_SUBSCRIPTION_EXC THEN
6024         raise EGO_USER_ATTRS_COMMON_PVT.G_SUBSCRIPTION_EXC;
6025 
6026     WHEN OTHERS THEN
6027       DECLARE
6028         l_token_table            ERROR_HANDLER.Token_Tbl_Type;
6029       BEGIN
6030         Debug_Msg('GOT EXCEPTION' || SQLERRM);
6031         l_token_table(1).TOKEN_NAME := 'PKG_NAME';
6032         l_token_table(1).TOKEN_VALUE := G_PKG_NAME;
6033         l_token_table(2).TOKEN_NAME := 'API_NAME';
6034         l_token_table(2).TOKEN_VALUE := l_api_name;
6035         l_token_table(3).TOKEN_NAME := 'SQL_ERR_MSG';
6036         l_token_table(3).TOKEN_VALUE := SQLERRM;
6037 
6038         ERROR_HANDLER.Add_Error_Message(
6039           p_message_name      => 'EGO_PLSQL_ERR'
6040          ,p_application_id    => 'EGO'
6041          ,p_token_tbl         => l_token_table
6042          ,p_message_type      => FND_API.G_RET_STS_ERROR
6043          ,p_row_identifier    => G_USER_ROW_IDENTIFIER
6044          ,p_entity_id         => p_entity_id
6045          ,p_entity_index      => p_entity_index
6046          ,p_entity_code       => p_entity_code
6047          ,p_addto_fnd_stack   => G_ADD_ERRORS_TO_FND_STACK
6048         );
6049       END;
6050 END Raise_WF_Event_If_Enabled;
6051 
6052 
6053 ----------------------------------------------------------------------
6054 
6055 
6056                   -------------------------------
6057                   -- Private Set-up Procedures --
6058                   -------------------------------
6059 
6060 ----------------------------------------------------------------------
6061 
6062 PROCEDURE Perform_Preliminary_Checks (
6063         p_object_name                   IN   VARCHAR2
6064        ,p_pk_column_name_value_pairs    IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
6065        ,p_class_code_name_value_pairs   IN   EGO_COL_NAME_VALUE_PAIR_ARRAY DEFAULT NULL
6066        ,p_entity_id                     IN   VARCHAR2
6067        ,p_entity_index                  IN   NUMBER
6068        ,p_entity_code                   IN   VARCHAR2
6069        ,x_return_status                 OUT NOCOPY VARCHAR2
6070 ) IS
6071 
6072     l_object_id              NUMBER;
6073     l_token_table            ERROR_HANDLER.Token_Tbl_Type;
6074     l_ext_table_metadata_obj EGO_EXT_TABLE_METADATA_OBJ;
6075     l_err_msg_name           VARCHAR2(30);
6076 
6077   BEGIN
6078 
6079     Debug_Msg('In Perform_Preliminary_Checks, starting', 2);
6080 
6081     ---------------------------------------------------------------------------------
6082     -- The first thing we do is make sure the passed-in Object Name is a valid one --
6083     -- (the procedure we call caches Object ID, so the call is not a wasted query) --
6084     ---------------------------------------------------------------------------------
6085     l_object_id := Get_Object_Id_From_Name(p_object_name);
6086     IF (l_object_id IS NULL) THEN
6087 
6088       l_token_table(1).TOKEN_NAME := 'OBJ_NAME';
6089       l_token_table(1).TOKEN_VALUE := p_object_name;
6090 
6091       l_err_msg_name := 'EGO_EF_NO_OBJ_ID_FOR_NAME';
6092       ERROR_HANDLER.Add_Error_Message(
6093         p_message_name      => l_err_msg_name
6094        ,p_application_id    => 'EGO'
6095        ,p_token_tbl         => l_token_table
6096        ,p_message_type      => FND_API.G_RET_STS_ERROR
6097        ,p_row_identifier    => G_USER_ROW_IDENTIFIER
6098        ,p_entity_id         => p_entity_id
6099        ,p_entity_index      => p_entity_index
6100        ,p_entity_code       => p_entity_code
6101        ,p_addto_fnd_stack   => G_ADD_ERRORS_TO_FND_STACK
6102       );
6103 
6104       RAISE FND_API.G_EXC_ERROR;
6105 
6106     END IF;
6107 
6108     ---------------------------------------------------------------
6109     -- Next, we make sure the column names passed in by as part  --
6110     -- of the name/value pair arrays match up with the extension --
6111     -- table metadata (again, the Ext Table object we find will  --
6112     -- be cached for later use, so asking for it now is OK).     --
6113     ---------------------------------------------------------------
6114     l_ext_table_metadata_obj := EGO_USER_ATTRS_COMMON_PVT.Get_Ext_Table_Metadata(l_object_id);
6115 
6116     Debug_Msg('In Perform_Preliminary_Checks, getting ext table metadata for object ' || l_object_id, 2);
6117 
6118     IF (l_ext_table_metadata_obj IS NULL) THEN
6119       l_token_table(1).TOKEN_NAME := 'OBJECT_NAME';
6120       l_token_table(1).TOKEN_VALUE := p_object_name;
6121       ERROR_HANDLER.Add_Error_Message(
6122         p_message_name      => 'EGO_EF_EXT_TABLE_METADATA_ERR'
6123        ,p_application_id    => 'EGO'
6124        ,p_token_tbl         => l_token_table
6125        ,p_message_type      => FND_API.G_RET_STS_ERROR
6126        ,p_row_identifier    => G_USER_ROW_IDENTIFIER
6127        ,p_entity_id         => p_entity_id
6128        ,p_entity_index      => p_entity_index
6129        ,p_entity_code       => p_entity_code
6130        ,p_addto_fnd_stack   => G_ADD_ERRORS_TO_FND_STACK
6131       );
6132       RAISE FND_API.G_EXC_ERROR;
6133     END IF;
6134 
6135     IF (NOT Are_Ext_Table_Col_Names_Right(l_ext_table_metadata_obj
6136                                          ,p_pk_column_name_value_pairs
6137                                          ,p_class_code_name_value_pairs)) THEN
6138       l_token_table(1).TOKEN_NAME := 'OBJ_NAME';
6139       l_token_table(1).TOKEN_VALUE := p_object_name;
6140       l_err_msg_name := 'EGO_EF_EXT_TBL_COL_NAME_ERR';
6141       ERROR_HANDLER.Add_Error_Message(
6142         p_message_name      => l_err_msg_name
6143        ,p_application_id    => 'EGO'
6144        ,p_token_tbl         => l_token_table
6145        ,p_message_type      => FND_API.G_RET_STS_ERROR
6146        ,p_row_identifier    => G_USER_ROW_IDENTIFIER
6147        ,p_entity_id         => p_entity_id
6148        ,p_entity_index      => p_entity_index
6149        ,p_entity_code       => p_entity_code
6150        ,p_addto_fnd_stack   => G_ADD_ERRORS_TO_FND_STACK
6151       );
6152       RAISE FND_API.G_EXC_ERROR;
6153     END IF;
6154 
6155     -----------------------------------------------------------------------------
6156     -- Next, we check that the Primary Key column array has at least one value --
6157     -----------------------------------------------------------------------------
6158     IF (p_pk_column_name_value_pairs IS NULL OR
6159         p_pk_column_name_value_pairs(p_pk_column_name_value_pairs.FIRST) IS NULL OR
6160         p_pk_column_name_value_pairs(p_pk_column_name_value_pairs.FIRST).VALUE IS NULL) THEN
6161 
6162       IF (l_ext_table_metadata_obj.pk_column_metadata.COUNT = 1) THEN
6163         l_err_msg_name := 'EGO_EF_NO_PK_VALUES_1';
6164         l_token_table(1).TOKEN_NAME := 'PK1_COL_NAME';
6165         l_token_table(1).TOKEN_VALUE := l_ext_table_metadata_obj.pk_column_metadata(1).COL_NAME;
6166         l_token_table(2).TOKEN_NAME := 'OBJ_NAME';
6167         l_token_table(2).TOKEN_VALUE := p_object_name;
6168       ELSIF (l_ext_table_metadata_obj.pk_column_metadata.COUNT = 2) THEN
6169         l_err_msg_name := 'EGO_EF_NO_PK_VALUES_2';
6170         l_token_table(1).TOKEN_NAME := 'PK1_COL_NAME';
6171         l_token_table(1).TOKEN_VALUE := l_ext_table_metadata_obj.pk_column_metadata(1).COL_NAME;
6172         l_token_table(2).TOKEN_NAME := 'PK2_COL_NAME';
6173         l_token_table(2).TOKEN_VALUE := l_ext_table_metadata_obj.pk_column_metadata(2).COL_NAME;
6174         l_token_table(3).TOKEN_NAME := 'OBJ_NAME';
6175         l_token_table(3).TOKEN_VALUE := p_object_name;
6176       ELSIF (l_ext_table_metadata_obj.pk_column_metadata.COUNT = 3) THEN
6177         l_err_msg_name := 'EGO_EF_NO_PK_VALUES_3';
6178         l_token_table(1).TOKEN_NAME := 'PK1_COL_NAME';
6179         l_token_table(1).TOKEN_VALUE := l_ext_table_metadata_obj.pk_column_metadata(1).COL_NAME;
6180         l_token_table(2).TOKEN_NAME := 'PK2_COL_NAME';
6181         l_token_table(2).TOKEN_VALUE := l_ext_table_metadata_obj.pk_column_metadata(2).COL_NAME;
6182         l_token_table(3).TOKEN_NAME := 'PK3_COL_NAME';
6183         l_token_table(3).TOKEN_VALUE := l_ext_table_metadata_obj.pk_column_metadata(3).COL_NAME;
6184         l_token_table(4).TOKEN_NAME := 'OBJ_NAME';
6185         l_token_table(4).TOKEN_VALUE := p_object_name;
6186       ELSIF (l_ext_table_metadata_obj.pk_column_metadata.COUNT = 4) THEN
6187         l_err_msg_name := 'EGO_EF_NO_PK_VALUES_4';
6188         l_token_table(1).TOKEN_NAME := 'PK1_COL_NAME';
6189         l_token_table(1).TOKEN_VALUE := l_ext_table_metadata_obj.pk_column_metadata(1).COL_NAME;
6190         l_token_table(2).TOKEN_NAME := 'PK2_COL_NAME';
6191         l_token_table(2).TOKEN_VALUE := l_ext_table_metadata_obj.pk_column_metadata(2).COL_NAME;
6192         l_token_table(3).TOKEN_NAME := 'PK3_COL_NAME';
6193         l_token_table(3).TOKEN_VALUE := l_ext_table_metadata_obj.pk_column_metadata(3).COL_NAME;
6194         l_token_table(4).TOKEN_NAME := 'PK4_COL_NAME';
6195         l_token_table(4).TOKEN_VALUE := l_ext_table_metadata_obj.pk_column_metadata(4).COL_NAME;
6196         l_token_table(5).TOKEN_NAME := 'OBJ_NAME';
6197         l_token_table(5).TOKEN_VALUE := p_object_name;
6198       ELSIF (l_ext_table_metadata_obj.pk_column_metadata.COUNT = 5) THEN
6199         l_err_msg_name := 'EGO_EF_NO_PK_VALUES_5';
6200         l_token_table(1).TOKEN_NAME := 'PK1_COL_NAME';
6201         l_token_table(1).TOKEN_VALUE := l_ext_table_metadata_obj.pk_column_metadata(1).COL_NAME;
6202         l_token_table(2).TOKEN_NAME := 'PK2_COL_NAME';
6203         l_token_table(2).TOKEN_VALUE := l_ext_table_metadata_obj.pk_column_metadata(2).COL_NAME;
6204         l_token_table(3).TOKEN_NAME := 'PK3_COL_NAME';
6205         l_token_table(3).TOKEN_VALUE := l_ext_table_metadata_obj.pk_column_metadata(3).COL_NAME;
6206         l_token_table(4).TOKEN_NAME := 'PK4_COL_NAME';
6207         l_token_table(4).TOKEN_VALUE := l_ext_table_metadata_obj.pk_column_metadata(4).COL_NAME;
6208         l_token_table(5).TOKEN_NAME := 'PK5_COL_NAME';
6209         l_token_table(5).TOKEN_VALUE := l_ext_table_metadata_obj.pk_column_metadata(5).COL_NAME;
6210         l_token_table(6).TOKEN_NAME := 'OBJ_NAME';
6211         l_token_table(6).TOKEN_VALUE := p_object_name;
6212       END IF;
6213       ERROR_HANDLER.Add_Error_Message(
6214         p_message_name      => l_err_msg_name
6215        ,p_application_id    => 'EGO'
6216        ,p_token_tbl         => l_token_table
6217        ,p_message_type      => FND_API.G_RET_STS_ERROR
6218        ,p_row_identifier    => G_USER_ROW_IDENTIFIER
6219        ,p_entity_id         => p_entity_id
6220        ,p_entity_index      => p_entity_index
6221        ,p_entity_code       => p_entity_code
6222        ,p_addto_fnd_stack   => G_ADD_ERRORS_TO_FND_STACK
6223       );
6224       RAISE FND_API.G_EXC_ERROR;
6225     END IF;
6226 
6227     x_return_status := FND_API.G_RET_STS_SUCCESS;
6228     Debug_Msg('In Perform_Preliminary_Checks, done', 2);
6229 
6230   EXCEPTION
6231     WHEN FND_API.G_EXC_ERROR THEN
6232       Debug_Msg('In Perform_Preliminary_Checks, EXCEPTION FND_API.G_EXC_ERROR', 2);
6233       x_return_status := FND_API.G_RET_STS_ERROR;
6234 
6235 END Perform_Preliminary_Checks;
6236 
6237 ----------------------------------------------------------------------
6238 -- if p_data_level_row_obj is sent,
6239 -- the privilege will be taken from data_level_row_obj
6240 -- else it is taken from p_attr_group_metadata_obj
6241 ----------------------------------------------------------------------
6242 PROCEDURE Check_Privileges (
6243         p_attr_group_metadata_obj  IN   EGO_ATTR_GROUP_METADATA_OBJ
6244        ,p_data_level_row_obj       IN   EGO_DATA_LEVEL_ROW_OBJ  DEFAULT NULL
6245        ,p_ignore_edit_privilege    IN   BOOLEAN    DEFAULT FALSE
6246        ,p_entity_id                IN   NUMBER     DEFAULT NULL
6247        ,p_entity_index             IN   NUMBER     DEFAULT NULL
6248        ,p_entity_code              IN   VARCHAR2   DEFAULT NULL
6249        ,x_return_status            OUT  NOCOPY VARCHAR2
6250 ) IS
6251 
6252     l_privilege_table_index  NUMBER;
6253     l_has_view_privilege     BOOLEAN := FALSE;
6254     l_has_edit_privilege     BOOLEAN := FALSE;
6255     l_error_message_name     VARCHAR2(30);
6256     l_token_table            ERROR_HANDLER.Token_Tbl_Type;
6257     l_view_privilege         fnd_form_functions.function_name%TYPE;
6258     l_edit_privilege         fnd_form_functions.function_name%TYPE;
6259 
6260   BEGIN
6261 
6262     Debug_Msg('In Check_Privileges, starting', 2);
6263 IF (p_data_level_row_obj IS NULL) THEN
6264 Debug_Msg(' Check_Privileges  view priv: '|| p_data_level_row_obj.view_privilege_id ||' edit priv: '||p_data_level_row_obj.edit_privilege_id);
6265 ELSE
6266 Debug_Msg(' Check_Privileges  view priv: '|| p_attr_group_metadata_obj.VIEW_PRIVILEGE ||' edit priv: '||p_attr_group_metadata_obj.EDIT_PRIVILEGE);
6267 END IF;
6268 
6269     ---------------------------------------------------------------
6270     -- First check for View privilege; if there is one, the user --
6271     -- must have it to even see the AG, let alone modify it      --
6272     ---------------------------------------------------------------
6273     IF (p_data_level_row_obj IS NULL AND p_attr_group_metadata_obj.VIEW_PRIVILEGE IS NULL)
6274        OR
6275        (p_data_level_row_obj IS NOT NULL and p_data_level_row_obj.view_privilege_id IS NULL) THEN
6276 
6277       l_has_view_privilege := TRUE;
6278 
6279     ELSE
6280 
6281       IF p_data_level_row_obj IS NOT NULL THEN
6282         SELECT function_name
6283         INTO l_view_privilege
6284         FROM fnd_form_functions
6285         WHERE function_id = p_data_level_row_obj.view_privilege_id;
6286       ELSE
6287         l_view_privilege  := p_attr_group_metadata_obj.VIEW_PRIVILEGE;
6288       END IF;
6289 Debug_Msg(' Check_Privileges  view priv: '|| l_view_privilege );
6290       --------------------------------------------------------
6291       -- NOTE: We assume that this procedure is only called --
6292       -- when G_CURRENT_USER_PRIVILEGES is not NULL         --
6293       --------------------------------------------------------
6294       IF (G_CURRENT_USER_PRIVILEGES IS NOT NULL AND G_CURRENT_USER_PRIVILEGES.COUNT > 0) THEN
6295         l_privilege_table_index := G_CURRENT_USER_PRIVILEGES.FIRST;
6296         WHILE (l_privilege_table_index <= G_CURRENT_USER_PRIVILEGES.LAST)
6297         LOOP
6298           EXIT WHEN l_has_view_privilege;
6299 
6300           IF (G_CURRENT_USER_PRIVILEGES(l_privilege_table_index) = l_view_privilege) THEN
6301             l_has_view_privilege := TRUE;
6302           END IF;
6303 
6304           l_privilege_table_index := G_CURRENT_USER_PRIVILEGES.NEXT(l_privilege_table_index);
6305         END LOOP;
6306       END IF;
6307     END IF;
6308 
6309     ----------------------------------------------------------------------
6310     -- If the user has View privilege (or if there is none defined), we --
6311     -- check for Edit privilege (assuming that p_ignore_edit_privilege  --
6312     -- is FALSE); if there is an Edit privilege, the user must have it  --
6313     ----------------------------------------------------------------------
6314     IF (NOT l_has_view_privilege) THEN
6315       l_error_message_name := 'EGO_EF_AG_USER_VIEW_PRIV_ERR';
6316     ELSE
6317 
6318       IF ( p_ignore_edit_privilege
6319           OR
6320           (p_data_level_row_obj IS NULL AND p_attr_group_metadata_obj.EDIT_PRIVILEGE IS NULL)
6321           OR
6322           (p_data_level_row_obj IS NOT NULL and p_data_level_row_obj.edit_privilege_id IS NULL) ) THEN
6323 
6324         l_has_edit_privilege := TRUE;
6325 
6326       ELSE
6327         IF p_data_level_row_obj IS NOT NULL THEN
6328           IF p_data_level_row_obj.edit_privilege_id IS NOT NULL THEN
6329             SELECT function_name
6330             INTO l_edit_privilege
6331             FROM fnd_form_functions
6332             WHERE function_id = p_data_level_row_obj.edit_privilege_id;
6333           ELSE
6334             l_edit_privilege := NULL;
6335           END IF;
6336         ELSE
6337           l_edit_privilege := p_attr_group_metadata_obj.EDIT_PRIVILEGE;
6338         END IF;
6339 Debug_Msg(' Check_Privileges  edit priv: '|| l_edit_privilege );
6340 
6341         IF (G_CURRENT_USER_PRIVILEGES.COUNT > 0) THEN
6342           l_privilege_table_index := G_CURRENT_USER_PRIVILEGES.FIRST;
6343           WHILE (l_privilege_table_index <= G_CURRENT_USER_PRIVILEGES.LAST)
6344           LOOP
6345             EXIT WHEN l_has_edit_privilege;
6346 
6347             IF (G_CURRENT_USER_PRIVILEGES(l_privilege_table_index) = l_edit_privilege) THEN
6348               l_has_edit_privilege := TRUE;
6349             END IF;
6350 
6351             l_privilege_table_index := G_CURRENT_USER_PRIVILEGES.NEXT(l_privilege_table_index);
6352           END LOOP;
6353         END IF;
6354       END IF;
6355     END IF;
6356 
6357     IF (l_has_edit_privilege) THEN
6358       x_return_status := FND_API.G_RET_STS_SUCCESS;
6359     ELSIF (l_error_message_name IS NULL) THEN
6360       l_error_message_name := 'EGO_EF_AG_USER_PRIV_ERR';
6361     END IF;
6362 
6363     -----------------------------------------------------------------------
6364     -- If the user is missing a necessary privilege, we report the error --
6365     -----------------------------------------------------------------------
6366     IF (l_error_message_name IS NOT NULL) THEN
6367 
6368       l_token_table(1).TOKEN_NAME := 'USER_NAME';
6369       l_token_table(1).TOKEN_VALUE := FND_GLOBAL.USER_NAME;
6370       l_token_table(2).TOKEN_NAME := 'AG_NAME';
6371       l_token_table(2).TOKEN_VALUE := p_attr_group_metadata_obj.ATTR_GROUP_DISP_NAME;
6372 
6373       ERROR_HANDLER.Add_Error_Message(
6374         p_message_name                  => l_error_message_name
6375        ,p_application_id                => 'EGO'
6376        ,p_token_tbl                     => l_token_table
6377        ,p_message_type                  => FND_API.G_RET_STS_ERROR
6378        ,p_row_identifier                => G_USER_ROW_IDENTIFIER
6379        ,p_entity_id                     => p_entity_id
6380        ,p_entity_index                  => p_entity_index
6381        ,p_entity_code                   => p_entity_code
6382        ,p_addto_fnd_stack               => G_ADD_ERRORS_TO_FND_STACK
6383       );
6384 
6385       x_return_status := FND_API.G_RET_STS_ERROR;
6386     END IF;
6387 
6388     Debug_Msg('In Check_Privileges, done; x_return_status is '||x_return_status, 2);
6389 
6390 END Check_Privileges;
6391 
6392 ----------------------------------------------------------------------
6393 
6394 PROCEDURE Set_Up_Business_Object_Session (
6395         p_bulkload_flag                 IN   BOOLEAN
6396        ,p_user_privileges_on_object     IN   EGO_VARCHAR_TBL_TYPE DEFAULT NULL
6397        ,p_entity_id                     IN   NUMBER     DEFAULT NULL
6398        ,p_entity_index                  IN   NUMBER     DEFAULT NULL
6399        ,p_entity_code                   IN   VARCHAR2   DEFAULT NULL
6400        ,p_debug_level                   IN   NUMBER
6401        ,p_init_error_handler_flag       IN   BOOLEAN
6402        ,p_object_name                   IN   VARCHAR2
6403        ,p_pk_column_name_value_pairs    IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
6404        ,p_class_code_name_value_pairs   IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
6405        ,p_init_fnd_msg_list             IN   VARCHAR2
6406        ,p_add_errors_to_fnd_stack       IN   VARCHAR2
6407        ,p_default_user_row_identifier   IN   NUMBER     DEFAULT NULL
6408        ,p_use_def_vals_on_insert_flag   IN   BOOLEAN    DEFAULT FALSE
6409        ,x_return_status                 OUT NOCOPY VARCHAR2
6410 ) IS
6411 
6412     l_err_msg_name           VARCHAR2(30);
6413     l_api_name               VARCHAR2(50) := 'Set_Up_Business_Object_Session(): ';
6414 
6415   BEGIN
6416 Debug_Msg(l_api_name || 'starting', 3);
6417     ------------------------------------------------------------------
6418     -- This flag determines when certain validations are performed, --
6419     -- how error-handling proceeds, how caching is handled, etc.    --
6420     ------------------------------------------------------------------
6421     G_BULK_PROCESSING_FLAG := p_bulkload_flag;
6422 
6423     ---------------------------------------------------------------
6424     -- This flag determines whether calls to Insert_Row will use --
6425     -- Default Values for Attributes that are NULL or not passed --
6426     ---------------------------------------------------------------
6427     G_DEFAULT_ON_INSERT_FLAG := p_use_def_vals_on_insert_flag OR p_bulkload_flag;
6428 
6429     ---------------------------------------------------------------------------
6430     -- This table holds the current user's privileges on the current object; --
6431     -- if it is non-null and non-empty, we will use it to perform data       --
6432     -- security checks for all Attribute Groups that have privileges defined --
6433     ---------------------------------------------------------------------------
6434     G_CURRENT_USER_PRIVILEGES := p_user_privileges_on_object;
6435 
6436     ---------------------------------------------------------------------
6437     -- If non-null, this is the number we should use for logging error --
6438     -- messages that are outside of the context of any particular row  --
6439     ---------------------------------------------------------------------
6440     IF (p_default_user_row_identifier IS NOT NULL) THEN
6441       G_USER_ROW_IDENTIFIER := p_default_user_row_identifier;
6442     END IF;
6443 
6444     --------------------------------------------------------------------------
6445     -- Reset our cache of metadata so we pick up the latest state of things --
6446     -- (we only want to do this once per bulkload and once per UI call)     --
6447     --------------------------------------------------------------------------
6448     IF (G_NEED_TO_RESET_AG_CACHE) THEN
6449 
6450       EGO_USER_ATTRS_COMMON_PVT.Reset_Cache_And_Globals();
6451       G_ASSOCIATION_DATA_LEVEL_CACHE.DELETE();
6452       G_HIERARCHY_CACHE.DELETE();
6453 
6454       IF (G_BULK_PROCESSING_FLAG) THEN
6455 
6456         G_NEED_TO_RESET_AG_CACHE := FALSE;
6457 
6458       END IF;
6459     END IF;
6460 
6461     ---------------------------------------
6462     -- This global holds the debug level --
6463     ---------------------------------------
6464     G_DEBUG_OUTPUT_LEVEL := p_debug_level;
6465 
6466     -----------------------------------------
6467     -- Initialize FND_MSG_PUB if necessary --
6468     -----------------------------------------
6469     IF (FND_API.To_Boolean(p_init_fnd_msg_list)) THEN
6470 
6471       FND_MSG_PUB.Initialize;
6472 
6473     END IF;
6474 
6475     ---------------------------------------
6476     -- Set up ERROR_HANDLER if necessary --
6477     ---------------------------------------
6478     IF (p_init_error_handler_flag) THEN
6479 
6480       ERROR_HANDLER.Initialize();
6481 
6482       ----------------------------------------------------------
6483       -- If we're debugging we have to set up a Debug session --
6484       ----------------------------------------------------------
6485       IF (p_debug_level > 0) THEN
6486 
6487         Set_Up_Debug_Session(p_entity_id, p_entity_code, p_debug_level);
6488 
6489       END IF;
6490     END IF;
6491 
6492     IF (FND_API.To_Boolean(p_add_errors_to_fnd_stack)) THEN
6493       G_ADD_ERRORS_TO_FND_STACK := 'Y';
6494     ELSE
6495       G_ADD_ERRORS_TO_FND_STACK := 'N';
6496     END IF;
6497 
6498     ---------------------------------------------------
6499     -- Before we begin processing rows, we make sure --
6500     -- the basic information passed in is correct    --
6501     ---------------------------------------------------
6502     Perform_Preliminary_Checks(
6503         p_object_name                   => p_object_name
6504        ,p_pk_column_name_value_pairs    => p_pk_column_name_value_pairs
6505        ,p_class_code_name_value_pairs   => p_class_code_name_value_pairs
6506        ,p_entity_id                     => p_entity_id
6507        ,p_entity_index                  => p_entity_index
6508        ,p_entity_code                   => p_entity_code
6509        ,x_return_status                 => x_return_status
6510     );
6511 Debug_Msg(l_api_name || 'done', 3);
6512 
6513 END Set_Up_Business_Object_Session;
6514 
6515 ----------------------------------------------------------------------
6516 
6517 PROCEDURE Close_Business_Object_Session (
6518         p_init_error_handler_flag       IN   BOOLEAN
6519        ,p_log_errors                    IN   BOOLEAN
6520        ,p_write_to_concurrent_log       IN   BOOLEAN
6521 ) IS
6522 
6523   BEGIN
6524 
6525     --------------------------------------------
6526     -- We log errors if we were told to do so --
6527     --------------------------------------------
6528     IF (p_log_errors) THEN
6529       IF (p_write_to_concurrent_log) THEN
6530         ERROR_HANDLER.Log_Error(
6531           p_write_err_to_inttable       => 'Y'
6532          ,p_write_err_to_conclog        => 'Y'
6533          ,p_write_err_to_debugfile      => ERROR_HANDLER.Get_Debug()
6534         );
6535       ELSE
6536         ERROR_HANDLER.Log_Error(
6537           p_write_err_to_inttable       => 'Y'
6538          ,p_write_err_to_debugfile      => ERROR_HANDLER.Get_Debug()
6539         );
6540       END IF;
6541     END IF;
6542 
6543     --------------------------------------------------------
6544     -- Set our various flags back to their initial values --
6545     --------------------------------------------------------
6546     -- FP Bug:6266004 (Base Bug:6086581)
6547     -- Start Reverting the fix done as a part of bug 3713278
6548 
6549     G_BULK_PROCESSING_FLAG := FALSE;
6550     G_DEFAULT_ON_INSERT_FLAG := FALSE;
6551     G_NEED_TO_RESET_AG_CACHE := TRUE;
6552     G_ADD_ERRORS_TO_FND_STACK := 'N';
6553 
6554     --Bug Fix 3713728
6555     --------------------------------------------------------
6556     -- We conditionally clear the user cache , only if it
6557     -- is not in Bulk Load Session
6558     --------------------------------------------------------
6559 
6560 --    IF(G_BULK_PROCESSING_FLAG = FALSE) THEN
6561 --      G_NEED_TO_RESET_AG_CACHE := TRUE;
6562 --    END IF;
6563 --    G_BULK_PROCESSING_FLAG := FALSE;
6564     --Bug Fix 3713728
6565 
6566     -- FP Bug:6266004 (Base Bug:6086581)
6567     -- End Reverting the fix done as a part of bug 3713278
6568 
6569     --------------------------------------------------------------
6570     -- If we were debugging, we have to close the debug session --
6571     --------------------------------------------------------------
6572     IF (p_init_error_handler_flag AND
6573         G_DEBUG_OUTPUT_LEVEL > 0 AND
6574         ERROR_HANDLER.Get_Debug() = 'Y') THEN
6575 
6576       ERROR_HANDLER.Close_Debug_Session();
6577       G_DEBUG_OUTPUT_LEVEL := 0;
6578 
6579     END IF;
6580 
6581   EXCEPTION
6582     WHEN OTHERS THEN
6583 
6584       ----------------------------------------------------------
6585       -- The ERROR_HANDLER call may fail for various reasons, --
6586       -- but we don't want that to halt our processing        --
6587       ----------------------------------------------------------
6588       NULL;
6589 
6590 END Close_Business_Object_Session;
6591 
6592 ----------------------------------------------------------------------
6593 
6594 FUNCTION Get_Table_Columns_List (
6595         p_application_id                IN   NUMBER
6596        ,p_from_table_name               IN   VARCHAR2
6597        ,p_from_cols_to_exclude_list     IN   VARCHAR2   DEFAULT NULL
6598        ,p_from_table_alias_prefix       IN   VARCHAR2   DEFAULT NULL
6599        ,p_to_table_name                 IN   VARCHAR2   DEFAULT NULL
6600        ,p_to_table_alias_prefix         IN   VARCHAR2   DEFAULT NULL
6601        ,p_in_line_view_where_clause     IN   VARCHAR2   DEFAULT NULL
6602        ,p_cast_date_cols_to_char        IN   BOOLEAN    DEFAULT FALSE
6603 )
6604 RETURN VARCHAR2
6605 IS
6606 
6607     l_dynamic_sql             VARCHAR2(20000);
6608     l_table_column_names_list VARCHAR2(32767);
6609     l_in_update_mode          BOOLEAN;
6610     l_update_expression       VARCHAR2(32767);
6611     l_column_name             VARCHAR2(30);
6612     l_column_type             VARCHAR2(1);
6613 
6614     TYPE DYNAMIC_CUR IS REF CURSOR;
6615     l_dynamic_cursor         DYNAMIC_CUR;
6616 
6617   BEGIN
6618 
6619     -------------------------------------------------------------------
6620     -- Build a query to fetch names of all columns we want to append --
6621     -------------------------------------------------------------------
6622     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)
6623                        ' FROM SYS.ALL_TAB_COLUMNS ' ||
6624                       ' WHERE TABLE_NAME = :1 ';
6625     --Bug No:5346472
6626     -- We can't use a bind as :3 which is replaced by
6627     -- p_from_cols_to_exclude_list below.Since it is of type VARCHAR2
6628     -- and mainly it contains a long string with comma seperated values.
6629     -- Using :3 in this case will fetch wrong results.
6630     IF (p_from_cols_to_exclude_list IS NOT NULL) THEN
6631       --Bug no:5346472
6632       --l_dynamic_sql := l_dynamic_sql||' AND C.COLUMN_NAME NOT IN ( :3 )';
6633       l_dynamic_sql := l_dynamic_sql||' AND COLUMN_NAME NOT IN ( '||p_from_cols_to_exclude_list||' )';
6634     END IF;
6635     l_dynamic_sql := l_dynamic_sql||' ORDER BY COLUMN_NAME';
6636 
6637     -----------------------------------------------------------------------
6638     -- Determine whether we're in update mode (in which, instead of just --
6639     -- making a list of column names, we make an update expression using --
6640     -- the two table names (and possibly aliases) passed in)             --
6641     -----------------------------------------------------------------------
6642     l_in_update_mode := (p_to_table_name IS NOT NULL);
6643 
6644     ----------------------------------------------------
6645     -- Fetch all the table column names, prefixing or --
6646     -- building an update expression as appropriate   --
6647     ----------------------------------------------------
6648     IF (p_from_cols_to_exclude_list IS NOT NULL) THEN
6649       OPEN l_dynamic_cursor FOR l_dynamic_sql
6650       USING p_from_table_name;--Bug No:5346472 --, p_from_cols_to_exclude_list;
6651     ELSE
6652       OPEN l_dynamic_cursor FOR l_dynamic_sql
6653       USING p_from_table_name;
6654     END IF;
6655     LOOP
6656       FETCH l_dynamic_cursor INTO l_column_name, l_column_type;
6657       EXIT WHEN l_dynamic_cursor%NOTFOUND;
6658 
6659       -------------------------------------------
6660       -- If we're casting Dates to char, do so --
6661       -------------------------------------------
6662       IF (p_cast_date_cols_to_char AND l_column_type = 'D') THEN
6663         l_table_column_names_list := l_table_column_names_list||' TO_CHAR(';
6664       END IF;
6665 
6666       -------------------------------------------
6667       -- If there's a from table alias, add it --
6668       -------------------------------------------
6669       IF (p_from_table_alias_prefix IS NOT NULL) THEN
6670         l_table_column_names_list := l_table_column_names_list||p_from_table_alias_prefix||'.';
6671       END IF;
6672 
6673       ------------------------------------------------------------------
6674       -- Whether or not there's an alias, add the current column name --
6675       ------------------------------------------------------------------
6676       l_table_column_names_list := l_table_column_names_list || l_column_name || ' ';
6677 
6678       -----------------------------------------------------------
6679       -- If we're in update mode, add a from column alias, the --
6680       -- to column and its alias (we assume table aliases in   --
6681       -- update mode), and append to our update expression     --
6682       -----------------------------------------------------------
6683       IF (l_in_update_mode) THEN
6684         l_table_column_names_list := l_table_column_names_list ||
6685                                      p_from_table_alias_prefix || '_' ||
6686                                      l_column_name || ',' ||
6687                                      p_to_table_alias_prefix || '.' ||
6688                                      l_column_name || ' ' ||
6689                                      p_to_table_alias_prefix || '_' ||
6690                                      l_column_name;
6691 
6692         l_update_expression := l_update_expression ||
6693                                p_to_table_alias_prefix || '_' ||
6694                                l_column_name || '=' ||
6695                                p_from_table_alias_prefix || '_' ||
6696                                l_column_name || ',';
6697 
6698       END IF;
6699 
6700       ---------------------------------------------------------------------
6701       -- If we're casting Dates to char, close the parentheses correctly --
6702       ---------------------------------------------------------------------
6703       IF (p_cast_date_cols_to_char) THEN
6704         IF (l_column_type = 'D') THEN
6705           l_table_column_names_list := l_table_column_names_list||','''||
6706                                        EGO_USER_ATTRS_COMMON_PVT.G_DATE_FORMAT||''') '||
6707                                        l_column_name;
6708         END IF;
6709       END IF;
6710 
6711       ---------------------------------------------------------
6712       -- Add a comma to end each loop regardless of the mode --
6713       ---------------------------------------------------------
6714       l_table_column_names_list := l_table_column_names_list || ',';
6715 
6716     END LOOP;
6717     CLOSE l_dynamic_cursor;
6718 
6719     -----------------------------------------------------------------------
6720     -- Trim the trailing ',' from l_table_column_names_list if necessary --
6721     -----------------------------------------------------------------------
6722     IF (LENGTH(l_table_column_names_list) > 0) THEN
6723       l_table_column_names_list := RTRIM(l_table_column_names_list, ',');
6724     END IF;
6725 
6726     -----------------------------------------------------------------
6727     -- Trim the trailing ',' from l_update_expression if necessary --
6728     -----------------------------------------------------------------
6729     IF (LENGTH(l_update_expression) > 0) THEN
6730       l_update_expression := RTRIM(l_update_expression, ',');
6731     END IF;
6732 
6733     ----------------------------------------------------------------------
6734     -- If we're in update mode, assemble the complete update expression --
6735     ----------------------------------------------------------------------
6736     IF (l_in_update_mode) THEN
6737       l_table_column_names_list := 'UPDATE /*+ BYPASS_UJVC */ (SELECT '||l_table_column_names_list||
6738                                    ' FROM '||p_from_table_name||' '||p_from_table_alias_prefix||
6739                                    ','||p_to_table_name||' '||p_to_table_alias_prefix||' '||
6740                                    p_in_line_view_where_clause||') SET '||l_update_expression;
6741     END IF;
6742 
6743     RETURN l_table_column_names_list;
6744 
6745 END Get_Table_Columns_List;
6746 
6747 ----------------------------------------------------------------------
6748 
6749 
6750 
6751                     ----------------------------
6752                     -- Private Procedure APIs --
6753                     ----------------------------
6754 
6755 ----------------------------------------------------------------------
6756 
6757 PROCEDURE Insert_Row (
6758         p_api_version                   IN   NUMBER
6759        ,p_attr_group_metadata_obj       IN   EGO_ATTR_GROUP_METADATA_OBJ
6760        ,p_ext_table_metadata_obj        IN   EGO_EXT_TABLE_METADATA_OBJ
6761        ,p_pk_column_name_value_pairs    IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
6762        ,p_class_code_name_value_pairs   IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
6763        ,p_data_level                    IN   VARCHAR2   DEFAULT NULL --R12C
6764        ,p_data_level_name_value_pairs   IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
6765        ,p_extension_id                  IN   NUMBER
6766        ,p_attr_name_value_pairs         IN   EGO_USER_ATTR_DATA_TABLE
6767        ,p_language_to_process           IN   VARCHAR2
6768        ,p_change_obj                    IN   EGO_USER_ATTR_CHANGE_OBJ
6769        ,p_extra_pk_col_name_val_pairs   IN   EGO_COL_NAME_VALUE_PAIR_ARRAY DEFAULT NULL
6770        ,p_extra_attr_name_value_pairs   IN   EGO_COL_NAME_VALUE_PAIR_ARRAY DEFAULT NULL
6771        ,p_pending_b_table_name          IN   VARCHAR2
6772        ,p_pending_tl_table_name         IN   VARCHAR2
6773        ,p_execute_dml                   IN   VARCHAR2   DEFAULT FND_API.G_TRUE
6774        ,p_entity_id                     IN   VARCHAR2
6775        ,p_entity_index                  IN   NUMBER
6776        ,p_entity_code                   IN   VARCHAR2
6777        ,p_commit                        IN   VARCHAR2
6778        ,p_bulkload_flag                 IN   BOOLEAN    DEFAULT FALSE
6779        ,px_attr_diffs                   IN OUT NOCOPY EGO_USER_ATTR_DIFF_TABLE
6780        ,p_raise_business_event          IN   BOOLEAN DEFAULT TRUE
6781        ,x_extension_id                  OUT NOCOPY NUMBER
6782        ,x_return_status                 OUT NOCOPY VARCHAR2
6783 ) IS
6784 
6785     l_api_name               CONSTANT VARCHAR2(30) := 'Insert_Row';
6786 
6787     --we don't use l_api_version yet, but eventually we might:
6788     --if we change required parameters, version goes FROM n.x to (n+1).x
6789     --if we change optional parameters, version goes FROM x.n to x.(n+1)
6790     l_api_version            CONSTANT NUMBER := 1.0;
6791 
6792     l_b_table_name           VARCHAR2(30);
6793     l_tl_table_name          VARCHAR2(30);
6794     l_pk_col_names           VARCHAR2(175);
6795     l_dl_col_names           VARCHAR2(200);
6796     l_cc_col_names           VARCHAR2(50);
6797     l_change_col_names       VARCHAR2(50);
6798     l_all_col_names          VARCHAR2(425);
6799     l_pk_col_values          VARCHAR2(775);
6800     l_dl_col_values          VARCHAR2(100);
6801     l_cc_col_values          VARCHAR2(300);
6802     l_change_col_values      VARCHAR2(50);
6803     l_all_col_values         VARCHAR2(1175);
6804     l_default_values_or_not  VARCHAR2(10);
6805     l_default_columns_or_not VARCHAR2(11);
6806     l_new_extension_id       NUMBER;
6807     l_dynamic_sql            VARCHAR2(32767); --the largest a VARCHAR2 can be
6808     l_cursor_id              NUMBER;
6809     l_number_of_rows         NUMBER;
6810     l_dummy                  VARCHAR2(1175);
6811     l_error_message          VARCHAR2(4000);
6812     l_event_name             VARCHAR2(240);
6813     l_is_event_enabled_flag  VARCHAR2(1);
6814     l_event_key              VARCHAR2(240);
6815     l_parameter_list         WF_PARAMETER_LIST_T := WF_PARAMETER_LIST_T();
6816     l_parameter_t            WF_PARAMETER_T:= WF_PARAMETER_T(null, null);
6817 
6818     l_propagate_hierarchy    BOOLEAN := TRUE;
6819     l_attr_diffs_event       EGO_USER_ATTR_DIFF_TABLE;
6820     l_pre_raise_flag         VARCHAR2(1);  --4105841
6821 
6822     l_extra_col_names        VARCHAR2(10000);
6823     l_extra_col_values       VARCHAR2(10000);
6824     l_index                  NUMBER;
6825 
6826     l_current_user_id        NUMBER := FND_GLOBAL.User_Id;
6827     l_current_login_id       NUMBER := FND_GLOBAL.Login_Id;
6828     l_data_level_id          NUMBER;
6829     l_dl_col_mdata_array     EGO_COL_METADATA_ARRAY;
6830   BEGIN
6831 
6832     Debug_Msg('In Insert_Row, starting', 1);
6833 
6834     IF FND_API.To_Boolean(p_commit) THEN
6835       SAVEPOINT Insert_Row;
6836     END IF;
6837 
6838     l_pre_raise_flag := 'F';
6839     -- Check for call compatibility
6840     IF NOT FND_API.Compatible_API_Call (l_api_version, p_api_version,
6841                                         l_api_name, G_PKG_NAME)
6842     THEN
6843       RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
6844     END IF;
6845 
6846     IF (p_bulkload_flag) THEN
6847       l_propagate_hierarchy := FALSE;
6848     END IF;
6849 
6850     ----------------------------------------------------------------------
6851     -- We take in p_extension_id for the case where the caller wants to --
6852     -- add a row to the pending changes table based on a production row --
6853     -- for a Multi-Row Attr Group but with changed values for unique    --
6854     -- key Attrs; in such a case, we won't be able to find the current  --
6855     -- Extension ID from the production row (since we rely on UK values --
6856     -- our Get_Extension_Id_For_Row query), so it must be passed in.    --
6857     -- We also take in p_extension_id from Implement_Change_Line.       --
6858     ----------------------------------------------------------------------
6859     IF (p_extension_id IS NOT NULL) THEN
6860       l_new_extension_id := p_extension_id;
6861     END IF;
6862 
6863     ----------------------------
6864     -- Add the extra columns .--
6865     ----------------------------
6866     l_extra_col_names := '';
6867     l_extra_col_values := '';
6868 
6869     IF(p_extra_pk_col_name_val_pairs IS NOT NULL) THEN
6870 
6871       l_index := p_extra_pk_col_name_val_pairs.FIRST;
6872       WHILE (l_index IS NOT NULL)
6873       LOOP
6874 
6875          IF (p_extra_pk_col_name_val_pairs(l_index).NAME IS NOT NULL) THEN
6876            l_extra_col_names := l_extra_col_names || p_extra_pk_col_name_val_pairs(l_index).NAME || ' , ';
6877            IF (p_extra_pk_col_name_val_pairs(l_index).VALUE IS NOT NULL) THEN
6878              l_extra_col_values := l_extra_col_values || p_extra_pk_col_name_val_pairs(l_index).VALUE || ' , ';
6879            ELSE
6880              l_extra_col_values := l_extra_col_values || ' NULL , ';
6881            END IF;
6882          END IF;
6883       l_index := p_extra_pk_col_name_val_pairs.NEXT(l_index);
6884 
6885       END LOOP;
6886     END IF;
6887 
6888 
6889     IF(p_extra_attr_name_value_pairs IS NOT NULL) THEN
6890       l_index := p_extra_attr_name_value_pairs.FIRST;
6891 
6892       WHILE (l_index IS NOT NULL)
6893       LOOP
6894          IF (p_extra_attr_name_value_pairs(l_index).NAME IS NOT NULL) THEN
6895 
6896            l_extra_col_names := l_extra_col_names || p_extra_attr_name_value_pairs(l_index).NAME || ' , ';
6897            IF (p_extra_attr_name_value_pairs(l_index).VALUE IS NOT NULL) THEN
6898              l_extra_col_values := l_extra_col_values || p_extra_attr_name_value_pairs(l_index).VALUE || ' , ';
6899            ELSE
6900              l_extra_col_values := l_extra_col_values || ' NULL , ';
6901            END IF;
6902 
6903          END IF;
6904          l_index := p_extra_attr_name_value_pairs.NEXT(l_index);
6905       END LOOP;
6906     END IF;
6907 
6908     --------------------------------------------------------------------------
6909     -- Determine whether we're in Change mode and set variables accordingly --
6910     --------------------------------------------------------------------------
6911     IF (p_change_obj IS NOT NULL AND
6912         p_pending_b_table_name IS NOT NULL AND
6913         p_pending_tl_table_name IS NOT NULL) THEN
6914 
6915       IF (p_extension_id IS NULL) THEN
6916         IF (p_change_obj.ACD_TYPE <> 'ADD') THEN
6917 
6918           l_new_extension_id := Get_Extension_Id_For_Row(
6919                                   p_attr_group_metadata_obj     => p_attr_group_metadata_obj
6920                                  ,p_ext_table_metadata_obj      => p_ext_table_metadata_obj
6921                                  ,p_pk_column_name_value_pairs  => p_pk_column_name_value_pairs
6922                                  ,p_data_level                  => p_data_level
6923                                  ,p_data_level_name_value_pairs => p_data_level_name_value_pairs
6924                                  ,p_attr_name_value_pairs       => p_attr_name_value_pairs
6925                                 );
6926 
6927         END IF;
6928       END IF;
6929 
6930       l_b_table_name := p_pending_b_table_name;
6931       l_tl_table_name := p_pending_tl_table_name;
6932       l_change_col_names := ' CHANGE_ID, CHANGE_LINE_ID, ACD_TYPE, ';
6933       IF (p_change_obj.CHANGE_ID IS NOT NULL) THEN
6934         l_change_col_values := p_change_obj.CHANGE_ID||', ';
6935       ELSE
6936         l_change_col_values := 'NULL, ';
6937       END IF;
6938       IF (p_change_obj.CHANGE_LINE_ID IS NOT NULL) THEN
6939         l_change_col_values := l_change_col_values||
6940                                p_change_obj.CHANGE_LINE_ID||', ';
6941       ELSE
6942         l_change_col_values := l_change_col_values||'NULL, ';
6943       END IF;
6944       IF (p_change_obj.ACD_TYPE IS NOT NULL) THEN
6945         l_change_col_values := l_change_col_values || '''' || p_change_obj.ACD_TYPE || ''', ';
6946       ELSE
6947         l_change_col_values := l_change_col_values || '''NULL'', ';
6948       END IF;
6949 
6950     ELSE
6951 
6952       l_b_table_name := p_attr_group_metadata_obj.EXT_TABLE_B_NAME;
6953       l_tl_table_name := p_attr_group_metadata_obj.EXT_TABLE_TL_NAME;
6954       l_change_col_names := '';
6955       l_change_col_values := '';
6956 
6957     END IF;
6958 
6959     ---------------------------------
6960     -- we need to construct the    --
6961     -- DML for the provided tables --
6962     ---------------------------------
6963 
6964    IF (p_pending_b_table_name IS NOT NULL) THEN
6965       l_b_table_name := p_pending_b_table_name;
6966    END IF;
6967 
6968    IF (p_pending_b_table_name IS NOT NULL) THEN
6969       l_tl_table_name := p_pending_tl_table_name;
6970    END IF;
6971 
6972     ------------------------------------------------------------------
6973     -- If we haven't set it yet, get a sequence-generated extension --
6974     -- ID to use for insertion into both the base and TL tables     --
6975     ------------------------------------------------------------------
6976     IF (l_new_extension_id IS NULL) THEN
6977       SELECT EGO_EXTFWK_S.NEXTVAL INTO l_new_extension_id FROM DUAL;
6978     END IF;
6979 
6980     --Start 4105841
6981     Get_Changed_Attributes(
6982           p_dml_operation                 => 'INSERT'
6983         , p_object_name                   => null
6984         , p_pk_column_name_value_pairs    => p_pk_column_name_value_pairs
6985         , p_attr_group_metadata_obj       => p_attr_group_metadata_obj
6986         , p_ext_table_metadata_obj        => p_ext_table_metadata_obj
6987         , p_data_level                    => p_data_level
6988         , p_data_level_name_value_pairs   => p_data_level_name_value_pairs
6989         , p_attr_name_value_pairs         => p_attr_name_value_pairs
6990         , p_extension_id                  => null
6991         , p_entity_id                     => p_entity_id
6992         , p_entity_index                  => p_entity_index
6993         , p_entity_code                   => p_entity_code
6994         , px_attr_diffs                   => l_attr_diffs_event);
6995     --End 4105841
6996 
6997     -- Only propagate if at least one attribute has EIH code = LP/AP
6998     IF (l_propagate_hierarchy AND
6999         p_attr_group_metadata_obj.HIERARCHY_PROPAGATE_FLAG = 'Y') THEN
7000     --4105841 : Removing call to Get_Changed_Attributes as it's called before this check
7001       px_attr_diffs := l_attr_diffs_event;
7002     END IF;
7003 
7004     -----------------------------------------------
7005     -- Now we open a cursor for the statement(s) --
7006     -- and initialize FND_DSQL for our DMLs      --
7007     -----------------------------------------------
7008     l_cursor_id := DBMS_SQL.Open_Cursor;
7009     Init();
7010 
7011     --------------------------------------------------------------------------------
7012     -- If we're bulkloading, we want to default any values the user left blank,   --
7013     -- but if we're coming from the UI, then the user explicitly set them to NULL --
7014     --------------------------------------------------------------------------------
7015     IF (G_DEFAULT_ON_INSERT_FLAG) THEN
7016 
7017       l_default_values_or_not := 'VALUES_DEF';
7018       l_default_columns_or_not := 'COLUMNS_DEF';
7019 
7020     ELSE
7021 
7022       l_default_values_or_not := 'VALUES';
7023       l_default_columns_or_not := 'COLUMNS';
7024 
7025     END IF;
7026 
7027     ------------------------------------------------------------------
7028     -- We pass p_language_to_process from Implement_Change_Line; if --
7029     -- we have it, then we only insert if the passed-in language is --
7030     -- equal to USERENV('LANG'); otherwise we behave normally       --
7031     ------------------------------------------------------------------
7032     IF (p_language_to_process IS NULL OR
7033         p_language_to_process = USERENV('LANG')) THEN
7034 
7035       ------------------------------------------------------
7036       -- FND_DSQL and start our first DML statement       --
7037       -- NOTE: we insert into both tables regardless of   --
7038       -- whether there are any Attr values for each table --
7039       -- so that the VL doesn't have to outer join        --
7040       ------------------------------------------------------
7041 
7042       -- CM expects extension Id to be the first bind
7043       -- in the generated DML
7044       FND_DSQL.Add_Text('INSERT INTO '||l_b_table_name||
7045                         ' ('||
7046                         'EXTENSION_ID, ');
7047 
7048       -----------------------------------------------------
7049       -- Add attr_group_id only if table has this column --
7050       -----------------------------------------------------
7051       IF (p_attr_group_metadata_obj.ATTR_GROUP_ID_FLAG ='Y') THEN
7052         FND_DSQL.Add_Text('ATTR_GROUP_ID, ');
7053       END IF;
7054 
7055       -----------------------------------------------------
7056       -- Add data_level_id only if it has been provided  --
7057       -----------------------------------------------------
7058       IF(p_data_level IS NOT NULL
7059          AND
7060          FND_API.TO_BOOLEAN(
7061               EGO_USER_ATTRS_COMMON_PVT.has_column_in_table(p_table_name  => l_b_table_name
7062                                                            ,p_column_name => 'DATA_LEVEL_ID'
7063                                                            )
7064                            )
7065          ) THEN
7066         FND_DSQL.Add_Text('DATA_LEVEL_ID, ');
7067       END IF;
7068 
7069       --------------------------------------------------------------------------
7070       -- We trust that the names and values (fetched separately) will match   --
7071       -- up, because we checked this in Validate_Row.  If the caller bypassed --
7072       -- Validate_Row and went straight to Perform_DML_On_Row, then our       --
7073       -- assumption that names and values will match up could cause an error. --
7074       --------------------------------------------------------------------------
7075 
7076 Debug_Msg(l_api_name || ' calling  EGO_USER_ATTRS_COMMON_PVT.Get_List_For_Table_Cols for PK ');
7077       l_pk_col_names := EGO_USER_ATTRS_COMMON_PVT.Get_List_For_Table_Cols(
7078                                                     p_ext_table_metadata_obj.pk_column_metadata
7079                                                    ,p_pk_column_name_value_pairs
7080                                                    ,'NAMES'
7081                                                    ,TRUE
7082                                                   );
7083 Debug_Msg(l_api_name || ' calling  EGO_USER_ATTRS_COMMON_PVT.Get_List_For_Table_Cols for CC ');
7084       l_cc_col_names := EGO_USER_ATTRS_COMMON_PVT.Get_List_For_Table_Cols(
7085                                                     p_ext_table_metadata_obj.class_code_metadata
7086                                                    ,p_class_code_name_value_pairs
7087                                                    ,'NAMES'
7088                                                    ,TRUE
7089                                                    ,', '
7090                                                   );
7091       --------------------------------------------
7092       -- NOTE: if inserting into the pending    --
7093       -- table, we don't insert Data Level info --
7094       --------------------------------------------
7095 
7096       l_dl_col_mdata_array := EGO_USER_ATTRS_COMMON_PVT.Get_Data_Level_Col_Array(p_attr_group_metadata_obj.APPLICATION_ID,
7097                                                                                  p_attr_group_metadata_obj.ATTR_GROUP_TYPE);
7098 /***
7099         FOR i IN l_dl_col_mdata_array.FIRST .. l_dl_col_mdata_array.LAST
7100         LOOP
7101            Debug_Msg('dl col--'||l_dl_col_mdata_array(i).COL_NAME);
7102         END LOOP;
7103 ***/
7104       IF (p_data_level_name_value_pairs IS NOT NULL AND
7105           p_data_level_name_value_pairs.COUNT > 0 AND
7106           p_change_obj IS NULL) THEN
7107 Debug_Msg(l_api_name || ' calling  EGO_USER_ATTRS_COMMON_PVT.Get_List_For_Table_Cols for DL ');
7108         l_dl_col_names := EGO_USER_ATTRS_COMMON_PVT.Get_List_For_Table_Cols(
7109                                                       l_dl_col_mdata_array
7110                                                      ,p_data_level_name_value_pairs
7111                                                      ,'NAMES'
7112                                                      ,TRUE
7113                                                      ,', '
7114                                                     );
7115       END IF;
7116 
7117 Debug_Msg('  l_dl_col_names-'||l_dl_col_names);
7118 
7119       FND_DSQL.Add_Text(', ' || l_change_col_names || l_extra_col_names);
7120 
7121       -----------------------------------------------
7122       -- Add the Attr column info to the statement --
7123       -----------------------------------------------
7124 Debug_Msg(l_api_name || ' calling  Add_Attr_Info_To_Statement ');
7125       Add_Attr_Info_To_Statement(p_attr_group_metadata_obj.attr_metadata_table
7126                                 ,p_attr_name_value_pairs
7127                                 ,', '
7128                                 ,l_default_columns_or_not
7129                                 ,'NONTRANS');
7130 
7131       ----------------------------------------------------------------------
7132       -- (No need to add a comma here, because Add_Attr_Info_To_Statement --
7133       -- adds a trailing separator to the list if it adds anything to it) --
7134       ----------------------------------------------------------------------
7135 
7136       -------------------------------------
7137       -- Add the rest of the column info --
7138       -------------------------------------
7139       FND_DSQL.Add_Text('CREATED_BY, '||
7140                         'CREATION_DATE, '||
7141                         'LAST_UPDATED_BY, '||
7142                         'LAST_UPDATE_DATE, '||
7143                         'LAST_UPDATE_LOGIN'||
7144                         ') VALUES ( ');
7145 
7146       ------------------------------------------------
7147       -- Now bind the values, including Attr values --
7148       ------------------------------------------------
7149       Add_Bind(p_bind_identifier => 'EXTENSION_ID'
7150               ,p_value           => l_new_extension_id);
7151 
7152       -----------------------------------------------------
7153       -- Add attr_group_id only if table has this column --
7154       -----------------------------------------------------
7155       IF (p_attr_group_metadata_obj.ATTR_GROUP_ID_FLAG ='Y') THEN
7156         FND_DSQL.Add_Text(', ');
7157         Add_Bind(p_bind_identifier => 'ATTR_GROUP_ID'
7158                  ,p_value          => p_attr_group_metadata_obj.ATTR_GROUP_ID);
7159       END IF;
7160 
7161       -----------------------------------------------------
7162       -- Add data_level_id only if it has been provided  --
7163       -----------------------------------------------------
7164       Debug_Msg(' in insert_row -- p_data_level-'||p_data_level);
7165       IF(p_data_level IS NOT NULL
7166          AND
7167          FND_API.TO_BOOLEAN(
7168               EGO_USER_ATTRS_COMMON_PVT.has_column_in_table(p_table_name  => l_b_table_name
7169                                                            ,p_column_name => 'DATA_LEVEL_ID'
7170                                                            )
7171                            )
7172          ) THEN
7173         l_data_level_id := Get_Data_Level_Id( p_attr_group_metadata_obj.APPLICATION_ID
7174                                              ,p_attr_group_metadata_obj.ATTR_GROUP_TYPE
7175                                              ,p_data_level);
7176         FND_DSQL.Add_Text(', ');
7177         Add_Bind(p_bind_identifier => 'DATA_LEVEL_ID'
7178                 ,p_value           => l_data_level_id);
7179       Debug_Msg(' in insert_row -- l_data_level_id-'||l_data_level_id);
7180       END IF;
7181 
7182 
7183       FND_DSQL.Add_Text(', ');
7184 Debug_Msg(l_api_name || ' calling  EGO_USER_ATTRS_COMMON_PVT.Get_List_For_Table_Cols for PK 2 ');
7185       l_pk_col_values := EGO_USER_ATTRS_COMMON_PVT.Get_List_For_Table_Cols(
7186                                                      p_ext_table_metadata_obj.pk_column_metadata
7187                                                     ,p_pk_column_name_value_pairs
7188                                                     ,'VALUES'
7189                                                     ,TRUE
7190                                                    );
7191 Debug_Msg(l_api_name || ' calling  EGO_USER_ATTRS_COMMON_PVT.Get_List_For_Table_Cols for CC 2 ');
7192       l_cc_col_values := EGO_USER_ATTRS_COMMON_PVT.Get_List_For_Table_Cols(
7193                                                      p_ext_table_metadata_obj.class_code_metadata
7194                                                     ,p_class_code_name_value_pairs
7195                                                     ,'VALUES'
7196                                                     ,TRUE
7197                                                     ,', '
7198                                                    );
7199       --------------------------------------------
7200       -- NOTE: if inserting into the pending    --
7201       -- table, we don't insert Data Level info --
7202       --------------------------------------------
7203       IF (p_data_level_name_value_pairs IS NOT NULL AND
7204           p_data_level_name_value_pairs.COUNT > 0 AND
7205           p_change_obj IS NULL) THEN
7206 Debug_Msg(l_api_name || ' calling  EGO_USER_ATTRS_COMMON_PVT.Get_List_For_Table_Cols for DL 2 ');
7207         l_dl_col_values := EGO_USER_ATTRS_COMMON_PVT.Get_List_For_Table_Cols(
7208                                                        l_dl_col_mdata_array
7209                                                       ,p_data_level_name_value_pairs
7210                                                       ,'VALUES'
7211                                                       ,TRUE
7212                                                       ,', '
7213                                                      );
7214       END IF;
7215 
7216       FND_DSQL.Add_Text(', '||l_change_col_values|| l_extra_col_values);
7217 
7218       Add_Attr_Info_To_Statement(p_attr_group_metadata_obj.attr_metadata_table
7219                                 ,p_attr_name_value_pairs
7220                                 ,', '
7221                                 ,l_default_values_or_not
7222                                 ,'NONTRANS');
7223 
7224       ----------------------------------------------------------------------
7225       -- (No need to add a comma here, because Add_Attr_Info_To_Statement --
7226       -- adds a trailing separator to the list if it adds anything to it) --
7227       ----------------------------------------------------------------------
7228 
7229       Add_Bind(p_bind_identifier => 'CREATED_BY'
7230               ,p_value           => l_current_user_id);
7231       FND_DSQL.Add_Text(', ');
7232       Add_Bind(p_bind_identifier => 'CREATION_DATE'
7233               ,p_value           => SYSDATE);
7234       FND_DSQL.Add_Text(', ');
7235       Add_Bind(p_bind_identifier => 'LAST_UPDATED_BY'
7236               ,p_value           => l_current_user_id);
7237       FND_DSQL.Add_Text(', ');
7238       Add_Bind(p_bind_identifier => 'LAST_UPDATE_DATE'
7239               ,p_value           => SYSDATE);
7240       FND_DSQL.Add_Text(', ');
7241       Add_Bind(p_bind_identifier => 'LAST_UPDATE_LOGIN'
7242               ,p_value           => l_current_login_id);
7243       FND_DSQL.Add_Text(')');
7244 
7245       l_dynamic_sql := FND_DSQL.Get_Text(FALSE);
7246 
7247       Debug_Msg('In Insert_Row, l_dynamic_sql for base table is as follows:', 3);
7248       Debug_Msg(l_dynamic_sql,3);
7249       Debug_SQL(FND_DSQL.Get_Text(TRUE));
7250       Set_Binds_And_Dml(l_dynamic_sql,'B');
7251 
7252       ---------------------------------------------------------------------
7253       -- Next we parse the statement, bind our variables, and execute it --
7254       ---------------------------------------------------------------------
7255 
7256       IF (p_execute_dml = FND_API.G_TRUE) THEN
7257         DBMS_SQL.Parse(l_cursor_id, l_dynamic_sql, DBMS_SQL.Native);
7258         FND_DSQL.Set_Cursor(l_cursor_id);
7259         FND_DSQL.Do_Binds();
7260       END IF;
7261 
7262       --Start 4105841 Raise pre event
7263       IF (p_change_obj IS  NULL) THEN
7264         IF(p_raise_business_event) THEN
7265           Raise_WF_Event_If_Enabled(
7266                 p_dml_type                      => 'CREATE'
7267                ,p_attr_group_metadata_obj       => p_attr_group_metadata_obj
7268                ,p_extension_id                  => l_new_extension_id
7269                ,p_pk_column_name_value_pairs    => p_pk_column_name_value_pairs
7270                ,p_data_level_name_value_pairs   => p_data_level_name_value_pairs
7271                ,p_entity_id                     => p_entity_id
7272                ,p_entity_index                  => p_entity_index
7273                ,p_entity_code                   => p_entity_code
7274                ,p_pre_event_flag                => 'T'
7275                ,p_data_level_id                 => l_data_level_id
7276                ,px_attr_diffs                   => l_attr_diffs_event
7277               );
7278           l_pre_raise_flag := 'T';
7279         END IF;
7280       END IF;
7281       --End 4105841
7282 
7283       IF (p_execute_dml = FND_API.G_TRUE) THEN
7284         l_number_of_rows := DBMS_SQL.Execute(l_cursor_id);
7285       END IF;
7286 
7287     END IF;
7288 
7289 
7290     ----------------------------------------------------------------
7291     -- Now we do basically the same thing except for the TL table --
7292     -- NOTE: again, we insert into the TL table regardless of     --
7293     -- whether there are any translatable Attr values so that the --
7294     -- VL doesn't have to outer join                              --
7295     ----------------------------------------------------------------
7296     IF (p_attr_group_metadata_obj.EXT_TABLE_TL_NAME IS NOT NULL) THEN
7297 
7298       Init();
7299       -- CM expects extension Id to be the first bind
7300       -- in the generated DML
7301       FND_DSQL.Add_Text('INSERT INTO '||l_tl_table_name||
7302                         ' ('||
7303                         'EXTENSION_ID, ');
7304 
7305       -----------------------------------------------------
7306       -- Add attr_group_id only if table has this column --
7307       -----------------------------------------------------
7308       IF (p_attr_group_metadata_obj.ATTR_GROUP_ID_FLAG ='Y') THEN
7309         FND_DSQL.Add_Text('ATTR_GROUP_ID, ');
7310       END IF;
7311 
7312       -----------------------------------------------------
7313       -- Add data_level_id only if it has been provided  --
7314       -----------------------------------------------------
7315       IF(p_data_level IS NOT NULL
7316          AND
7317          FND_API.TO_BOOLEAN(
7318               EGO_USER_ATTRS_COMMON_PVT.has_column_in_table(p_table_name  => l_tl_table_name
7319                                                            ,p_column_name => 'DATA_LEVEL_ID'
7320                                                            )
7321                            )
7322          ) THEN
7323         FND_DSQL.Add_Text('DATA_LEVEL_ID, ');
7324       END IF;
7325 
7326       l_pk_col_names := EGO_USER_ATTRS_COMMON_PVT.Get_List_For_Table_Cols(
7327                                                     p_ext_table_metadata_obj.pk_column_metadata
7328                                                    ,p_pk_column_name_value_pairs
7329                                                    ,'NAMES'
7330                                                    ,TRUE
7331                                                   );
7332       l_cc_col_names := EGO_USER_ATTRS_COMMON_PVT.Get_List_For_Table_Cols(
7333                                                     p_ext_table_metadata_obj.class_code_metadata
7334                                                    ,p_class_code_name_value_pairs
7335                                                    ,'NAMES'
7336                                                    ,TRUE
7337                                                    ,', '
7338                                                   );
7339       IF (p_data_level_name_value_pairs IS NOT NULL AND
7340           p_data_level_name_value_pairs.COUNT > 0 AND
7341           p_change_obj IS NULL) THEN
7342         l_dl_col_names := EGO_USER_ATTRS_COMMON_PVT.Get_List_For_Table_Cols(
7343                                                       l_dl_col_mdata_array
7344                                                      ,p_data_level_name_value_pairs
7345                                                      ,'NAMES'
7346                                                      ,TRUE
7347                                                      ,', '
7348                                                     );
7349       END IF;
7350 
7351       FND_DSQL.Add_Text(', ' || l_change_col_names||l_extra_col_names);
7352 
7353       Add_Attr_Info_To_Statement(p_attr_group_metadata_obj.attr_metadata_table
7354                                 ,p_attr_name_value_pairs
7355                                 ,', '
7356                                 ,l_default_columns_or_not
7357                                 ,'TRANS');
7358 
7359       ----------------------------------------------------------------------
7360       -- (No need to add a comma here, because Add_Attr_Info_To_Statement --
7361       -- adds a trailing separator to the list if it adds anything to it) --
7362       ----------------------------------------------------------------------
7363 
7364       FND_DSQL.Add_Text('CREATED_BY, '||
7365                         'CREATION_DATE, '||
7366                         'LAST_UPDATED_BY, '||
7367                         'LAST_UPDATE_DATE, '||
7368                         'LAST_UPDATE_LOGIN, '||
7369                         'SOURCE_LANG, '||
7370                         'LANGUAGE) '||
7371                         'SELECT ');
7372 
7373       Add_Bind(p_bind_identifier => 'EXTENSION_ID'
7374               ,p_value           => l_new_extension_id);
7375 
7376       -----------------------------------------------------
7377       -- Add attr_group_id only if table has this column --
7378       -----------------------------------------------------
7379       IF (p_attr_group_metadata_obj.ATTR_GROUP_ID_FLAG ='Y') THEN
7380         FND_DSQL.Add_Text(', ');
7381         Add_Bind(p_bind_identifier => 'ATTR_GROUP_ID'
7382                 ,p_value           => p_attr_group_metadata_obj.ATTR_GROUP_ID);
7383       END IF;
7384 
7385       -----------------------------------------------------
7386       -- Add data_level_id only if it has been provided  --
7387       -----------------------------------------------------
7388       IF(p_data_level IS NOT NULL
7389          AND
7390          FND_API.TO_BOOLEAN(
7391               EGO_USER_ATTRS_COMMON_PVT.has_column_in_table(p_table_name  => l_tl_table_name
7392                                                            ,p_column_name => 'DATA_LEVEL_ID'
7393                                                            )
7394                            )
7395          ) THEN
7396         l_data_level_id := Get_Data_Level_Id( p_attr_group_metadata_obj.APPLICATION_ID
7397                                              ,p_attr_group_metadata_obj.ATTR_GROUP_TYPE
7398                                              ,p_data_level);
7399         FND_DSQL.Add_Text(', ');
7400         Add_Bind(p_bind_identifier => 'DATA_LEVEL_ID'
7401                 ,p_value           => l_data_level_id);
7402       END IF;
7403 
7404       FND_DSQL.Add_Text(', ');
7405       l_pk_col_values := EGO_USER_ATTRS_COMMON_PVT.Get_List_For_Table_Cols(
7406                                                      p_ext_table_metadata_obj.pk_column_metadata
7407                                                     ,p_pk_column_name_value_pairs
7408                                                     ,'VALUES'
7409                                                     ,TRUE
7410                                                    );
7411       l_cc_col_values := EGO_USER_ATTRS_COMMON_PVT.Get_List_For_Table_Cols(
7412                                                      p_ext_table_metadata_obj.class_code_metadata
7413                                                     ,p_class_code_name_value_pairs
7414                                                     ,'VALUES'
7415                                                     ,TRUE
7416                                                     ,', '
7417                                                    );
7418       IF (p_data_level_name_value_pairs IS NOT NULL AND
7419           p_data_level_name_value_pairs.COUNT > 0 AND
7420           p_change_obj IS NULL) THEN
7421         l_dl_col_values := EGO_USER_ATTRS_COMMON_PVT.Get_List_For_Table_Cols(
7422                                                        l_dl_col_mdata_array
7423                                                       ,p_data_level_name_value_pairs
7424                                                       ,'VALUES'
7425                                                       ,TRUE
7426                                                       ,', '
7427                                                      );
7428       END IF;
7429 
7430       FND_DSQL.Add_Text(', '||l_change_col_values||l_extra_col_values);
7431 
7432       Add_Attr_Info_To_Statement(p_attr_group_metadata_obj.attr_metadata_table
7433                                 ,p_attr_name_value_pairs
7434                                 ,', '
7435                                 ,l_default_values_or_not
7436                                 ,'TRANS');
7437 
7438       ----------------------------------------------------------------------
7439       -- (No need to add a comma here, because Add_Attr_Info_To_Statement --
7440       -- adds a trailing separator to the list if it adds anything to it) --
7441       ----------------------------------------------------------------------
7442 
7443       Add_Bind(p_bind_identifier => 'CREATED_BY'
7444               ,p_value           => l_current_user_id);
7445       FND_DSQL.Add_Text(', ');
7446       Add_Bind(p_bind_identifier => 'CREATION_DATE'
7447               ,p_value           => SYSDATE);
7448       FND_DSQL.Add_Text(', ');
7449       Add_Bind(p_bind_identifier => 'LAST_UPDATED_BY'
7450               ,p_value           => l_current_user_id);
7451       FND_DSQL.Add_Text(', ');
7452       Add_Bind(p_bind_identifier => 'LAST_UPDATE_DATE'
7453               ,p_value           => SYSDATE);
7454       FND_DSQL.Add_Text(', ');
7455       Add_Bind(p_bind_identifier => 'LAST_UPDATE_LOGIN'
7456               ,p_value           => l_current_login_id);
7457       FND_DSQL.Add_Text(', ');
7458       Add_Bind(p_bind_identifier => 'SOURCE_LANG'
7459               ,p_value           => USERENV('LANG'));
7460       FND_DSQL.Add_Text(', L.LANGUAGE_CODE '||
7461                         'FROM '||
7462                         'FND_LANGUAGES L '||
7463                         'WHERE L.INSTALLED_FLAG IN (''I'', ''B'')');
7464 
7465       -----------------------------------------------------------------
7466       -- We pass p_language_to_process from Implement_Change_Line so --
7467       -- that each pending TL row only inserts one production row    --
7468       -----------------------------------------------------------------
7469       IF (p_language_to_process IS NOT NULL) THEN
7470         FND_DSQL.Add_Text(' AND L.LANGUAGE_CODE = ');
7471         Add_Bind(p_bind_identifier => 'LANGUAGE'
7472                 ,p_value           => p_language_to_process);
7473       END IF;
7474 
7475       l_dynamic_sql := FND_DSQL.Get_Text(FALSE);
7476 
7477       Set_Binds_And_Dml(l_dynamic_sql,'TL');
7478 
7479       Debug_Msg('In Insert_Row, l_dynamic_sql for TL table is as follows:', 3);
7480       Debug_SQL(FND_DSQL.Get_Text(TRUE));
7481 
7482       ---------------------------------------------------
7483       -- We re-use our cursor from the first statement --
7484       ---------------------------------------------------
7485       IF (p_execute_dml = FND_API.G_TRUE) THEN
7486         DBMS_SQL.Parse(l_cursor_id, l_dynamic_sql, DBMS_SQL.Native);
7487         FND_DSQL.Set_Cursor(l_cursor_id);
7488        FND_DSQL.Do_Binds();
7489       END IF;
7490 
7491       ---Start 4105841
7492       --raise the event if it has not been raised
7493 
7494       IF  (p_change_obj IS NULL) AND (l_pre_raise_flag = 'F') THEN
7495         IF(p_raise_business_event) THEN
7496           Raise_WF_Event_If_Enabled(
7497                 p_dml_type                      => 'CREATE'
7498                ,p_attr_group_metadata_obj       => p_attr_group_metadata_obj
7499                ,p_extension_id                  => l_new_extension_id
7500                ,p_pk_column_name_value_pairs    => p_pk_column_name_value_pairs
7501                ,p_data_level_name_value_pairs   => p_data_level_name_value_pairs
7502                ,p_entity_id                     => p_entity_id
7503                ,p_entity_index                  => p_entity_index
7504                ,p_entity_code                   => p_entity_code
7505                ,p_pre_event_flag                => 'T'
7506                ,p_data_level_id                 => l_data_level_id
7507                ,px_attr_diffs                   => l_attr_diffs_event
7508                );
7509           l_pre_raise_flag := 'T';
7510         END IF;
7511       END IF;
7512       --End 4105841
7513 
7514       IF (p_execute_dml = FND_API.G_TRUE) THEN
7515         l_number_of_rows := DBMS_SQL.Execute(l_cursor_id);
7516       END IF;
7517 
7518     END IF;
7519 
7520     ----------------------------------
7521     -- Finally, we close our cursor --
7522     ----------------------------------
7523     DBMS_SQL.Close_Cursor(l_cursor_id);
7524 
7525     IF (l_propagate_hierarchy
7526         AND p_attr_group_metadata_obj.HIERARCHY_PROPAGATE_FLAG = 'Y'
7527         AND px_attr_diffs.COUNT > 0 AND p_execute_dml = FND_API.G_TRUE) THEN --Bug fix 5220020
7528       Propagate_Attributes( p_pk_column_name_value_pairs
7529                           , p_class_code_name_value_pairs
7530                           , p_data_level_name_value_pairs
7531                           , px_attr_diffs
7532                           , G_CREATE_MODE
7533                           , p_attr_group_metadata_obj
7534                           , x_return_status
7535                           , l_error_message);
7536     END IF;
7537     IF (x_return_status IN (G_RET_STS_ERROR, G_RET_STS_UNEXP_ERROR )) THEN
7538       fnd_message.set_name('EGO','EGO_GENERIC_MSG_TEXT');
7539       fnd_message.set_token('MESSAGE',l_error_message);
7540       fnd_msg_pub.Add;
7541       RETURN;
7542     END IF;
7543 
7544     --------------------------------------------------
7545     -- If we inserted into the production tables... --
7546     -- we see about raising a Business Event      --
7547     --------------------------------------------------
7548     IF (p_change_obj IS NULL) THEN
7549       IF(p_raise_business_event) THEN
7550       Raise_WF_Event_If_Enabled(
7551         p_dml_type                      => 'CREATE'
7552        ,p_attr_group_metadata_obj       => p_attr_group_metadata_obj
7553        ,p_extension_id                  => l_new_extension_id
7554        ,p_pk_column_name_value_pairs    => p_pk_column_name_value_pairs
7555        ,p_data_level_name_value_pairs   => p_data_level_name_value_pairs
7556        ,p_entity_id                     => p_entity_id
7557        ,p_entity_index                  => p_entity_index
7558        ,p_entity_code                   => p_entity_code
7559        ,p_data_level_id                 => l_data_level_id
7560        ,px_attr_diffs                   => l_attr_diffs_event
7561       );
7562       END IF;
7563     END IF;
7564 
7565     x_extension_id := l_new_extension_id;
7566 
7567     Debug_Msg('In Insert_Row, done', 1);
7568 
7569     IF FND_API.To_Boolean(p_commit) THEN
7570       COMMIT WORK;
7571     END IF;
7572 
7573     x_return_status := FND_API.G_RET_STS_SUCCESS;
7574 
7575   EXCEPTION
7576     -----------------------------------------------------------
7577     -- There are no expected errors in this procedure, so... --
7578     -----------------------------------------------------------
7579     --Start 4105841
7580     --Checking for Exception raised by preAttribute Change Event
7581     --don't put to the stack already added in EGO_WF_WRAPPER_PVT
7582     WHEN EGO_USER_ATTRS_COMMON_PVT.G_SUBSCRIPTION_EXC THEN
7583       Debug_Msg('Insert_Row EXCEPTION  EGO_USER_ATTRS_COMMON_PVT.G_SUBSCRIPTION_EXC ');
7584       IF FND_API.To_Boolean(p_commit) THEN
7585         ROLLBACK TO insert_row;
7586       END IF;
7587       x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
7588     --End 4105841
7589 
7590     WHEN OTHERS THEN
7591 
7592       Debug_Msg('Insert_Row EXCEPTION  others '||SQLERRM);
7593       IF FND_API.To_Boolean(p_commit) THEN
7594         ROLLBACK TO insert_row;
7595       END IF;
7596       x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
7597 
7598       DECLARE
7599         l_token_table            ERROR_HANDLER.Token_Tbl_Type;
7600       BEGIN
7601         l_token_table(1).TOKEN_NAME := 'PKG_NAME';
7602         l_token_table(1).TOKEN_VALUE := G_PKG_NAME;
7603         l_token_table(2).TOKEN_NAME := 'API_NAME';
7604         l_token_table(2).TOKEN_VALUE := l_api_name;
7605         l_token_table(3).TOKEN_NAME := 'SQL_ERR_MSG';
7606         l_token_table(3).TOKEN_VALUE := SQLERRM;
7607 
7608         ERROR_HANDLER.Add_Error_Message(
7609           p_message_name      => 'EGO_PLSQL_ERR'
7610          ,p_application_id    => 'EGO'
7611          ,p_token_tbl         => l_token_table
7612          ,p_message_type      => FND_API.G_RET_STS_ERROR
7613          ,p_row_identifier    => G_USER_ROW_IDENTIFIER
7614          ,p_entity_id         => p_entity_id
7615          ,p_entity_index      => p_entity_index
7616          ,p_entity_code       => p_entity_code
7617          ,p_addto_fnd_stack   => G_ADD_ERRORS_TO_FND_STACK
7618         );
7619       END;
7620 
7621 END Insert_Row;
7622 
7623 ----------------------------------------------------------------------
7624 
7625 PROCEDURE Update_Row (
7626         p_api_version                   IN   NUMBER
7627        ,p_attr_group_metadata_obj       IN   EGO_ATTR_GROUP_METADATA_OBJ
7628        ,p_ext_table_metadata_obj        IN   EGO_EXT_TABLE_METADATA_OBJ
7629        ,p_pk_column_name_value_pairs    IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
7630        ,p_class_code_name_value_pairs   IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
7631        ,p_data_level                    IN   VARCHAR2   DEFAULT NULL --R12C
7632        ,p_data_level_name_value_pairs   IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
7633        ,p_extension_id                  IN   NUMBER
7634        ,p_attr_name_value_pairs         IN   EGO_USER_ATTR_DATA_TABLE
7635        ,p_language_to_process           IN   VARCHAR2
7636        ,p_change_obj                    IN   EGO_USER_ATTR_CHANGE_OBJ
7637        ,p_extra_attr_name_value_pairs   IN   EGO_COL_NAME_VALUE_PAIR_ARRAY DEFAULT NULL
7638        ,p_extra_pk_col_name_val_pairs   IN   EGO_COL_NAME_VALUE_PAIR_ARRAY DEFAULT NULL
7639        ,p_pending_b_table_name          IN   VARCHAR2
7640        ,p_pending_tl_table_name         IN   VARCHAR2
7641        ,p_execute_dml                   IN   VARCHAR2   DEFAULT FND_API.G_TRUE
7642        ,p_entity_id                     IN   VARCHAR2
7643        ,p_entity_index                  IN   NUMBER
7644        ,p_entity_code                   IN   VARCHAR2
7645        ,p_commit                        IN   VARCHAR2
7646        ,p_bulkload_flag                 IN   BOOLEAN    DEFAULT FALSE
7647        ,px_attr_diffs                   IN OUT NOCOPY EGO_USER_ATTR_DIFF_TABLE
7648        ,p_raise_business_event          IN   BOOLEAN DEFAULT TRUE
7649        ,x_return_status                 OUT NOCOPY VARCHAR2
7650 ) IS
7651 
7652     l_api_name               CONSTANT VARCHAR2(30) := 'Update_Row';
7653 
7654     --we don't use l_api_version yet, but eventually we might:
7655     --if we change required parameters, version goes FROM n.x to (n+1).x
7656     --if we change optional parameters, version goes FROM x.n to x.(n+1)
7657     l_api_version            CONSTANT NUMBER := 1.0;
7658 
7659     l_b_table_name           VARCHAR2(30);
7660     l_tl_table_name          VARCHAR2(30);
7661     l_which_attrs_to_update  VARCHAR2(10);
7662     l_attr_value_string      VARCHAR2(10000);
7663     l_change_col_where_string VARCHAR2(100);
7664     l_change_col_value_string VARCHAR2(50);
7665     l_extra_col_value_string VARCHAR2(10000);
7666     l_extra_col_where_string VARCHAR2(10000);
7667     l_dynamic_sql            VARCHAR2(32767); --the largest a VARCHAR2 can be
7668     l_cursor_id              NUMBER;
7669     l_number_of_rows         NUMBER;
7670 
7671     l_event_name             VARCHAR2(240);
7672     l_is_event_enabled_flag  VARCHAR2(1);
7673     l_event_key              VARCHAR2(240);
7674     l_parameter_list         WF_PARAMETER_LIST_T := WF_PARAMETER_LIST_T();
7675     l_parameter_t            WF_PARAMETER_T:= WF_PARAMETER_T(null, null);
7676     l_error_message          VARCHAR2(4000);
7677     l_propagate_hierarchy    BOOLEAN := TRUE;
7678     --Start 4105841
7679     l_attr_diffs_event       EGO_USER_ATTR_DIFF_TABLE;
7680     l_pre_event_flag         VARCHAR2(1);
7681     --End 4105841
7682     ctr                      NUMBER;
7683     l_index                  NUMBER;
7684 
7685     l_current_user_id        NUMBER := FND_GLOBAL.User_Id;
7686     l_current_login_id       NUMBER := FND_GLOBAL.Login_Id;
7687     --Start Bug 5211171
7688      l_col_value             VARCHAR2(1000);
7689      l_col_name              VARCHAR2(1000);
7690      l_col_values_index      NUMBER;
7691     --End Bug 5211171
7692     l_data_level_id          NUMBER;
7693 
7694   BEGIN
7695 
7696     Debug_Msg('In Update_Row, starting', 1);
7697 
7698     IF FND_API.To_Boolean(p_commit) THEN
7699       SAVEPOINT update_row;
7700     END IF;
7701 
7702     l_pre_event_flag := 'F';
7703     -- Check for call compatibility
7704     IF NOT FND_API.Compatible_API_Call (l_api_version, p_api_version,
7705                                         l_api_name, G_PKG_NAME)
7706     THEN
7707       RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
7708     END IF;
7709 
7710     IF (p_bulkload_flag) THEN
7711       l_propagate_hierarchy := FALSE;
7712     END IF;
7713 
7714     -----------------------------------------------------------------------------------
7715     -- In case the extra columns are passed to be updated we push them into the dml
7716     -----------------------------------------------------------------------------------
7717     l_extra_col_value_string := null;
7718     ctr := 0;
7719     IF (p_extra_attr_name_value_pairs IS NOT NULL AND
7720         p_extra_attr_name_value_pairs.COUNT > 0) THEN
7721 
7722       l_index := p_extra_attr_name_value_pairs.FIRST;
7723       WHILE (l_index IS NOT NULL)
7724       LOOP
7725         IF (p_extra_attr_name_value_pairs(l_index).NAME IS NOT NULL) THEN
7726            ctr := ctr+1;
7727            IF ( ctr >1 ) THEN
7728              l_extra_col_value_string := l_extra_col_value_string||' , ';
7729            END IF;
7730            IF (p_extra_attr_name_value_pairs(l_index).VALUE IS NOT NULL) THEN
7731               l_extra_col_value_string := l_extra_col_value_string || p_extra_attr_name_value_pairs(l_index).NAME || ' = '
7732                                                                    ||  p_extra_attr_name_value_pairs(l_index).VALUE ;
7733            ELSE
7734               l_extra_col_value_string := l_extra_col_value_string || p_extra_attr_name_value_pairs(l_index).NAME || ' =  NULL ';
7735            END IF;
7736         END IF;
7737         l_index := p_extra_attr_name_value_pairs.NEXT(l_index);
7738       END LOOP;
7739 
7740     END IF;
7741 
7742     ------------------------------------------------------------------------------------------
7743     -- In case the extra pk columns values are passed we add them into the dml where clause
7744     ------------------------------------------------------------------------------------------
7745 
7746     l_extra_col_where_string := ' ';
7747 
7748     IF (p_extra_pk_col_name_val_pairs IS NOT NULL AND
7749         p_extra_pk_col_name_val_pairs.COUNT > 0) THEN
7750 
7751       l_index := p_extra_pk_col_name_val_pairs.FIRST;
7752       WHILE (l_index IS NOT NULL)
7753       LOOP
7754 
7755         IF (p_extra_pk_col_name_val_pairs(l_index).NAME IS NOT NULL) THEN
7756            l_extra_col_where_string := l_extra_col_where_string || ' AND ';
7757            IF (p_extra_pk_col_name_val_pairs(l_index).VALUE IS NOT NULL) THEN
7758               l_extra_col_where_string := l_extra_col_where_string || p_extra_pk_col_name_val_pairs(l_index).NAME || ' = '
7759                                                                    ||  p_extra_pk_col_name_val_pairs(l_index).VALUE ;
7760            ELSE
7761               l_extra_col_where_string := l_extra_col_where_string || p_extra_pk_col_name_val_pairs(l_index).NAME || ' IS  NULL ';
7762            END IF;
7763         END IF;
7764         l_index := p_extra_pk_col_name_val_pairs.NEXT(l_index);
7765 
7766       END LOOP;
7767 
7768     END IF;
7769 
7770    --------------------------------------------------------------------------
7771     -- Determine whether we're in Change mode and set variables accordingly --
7772     --------------------------------------------------------------------------
7773     IF (p_change_obj IS NOT NULL AND
7774         p_pending_b_table_name IS NOT NULL AND
7775         p_pending_tl_table_name IS NOT NULL) THEN
7776 
7777       l_b_table_name := p_pending_b_table_name;
7778       l_tl_table_name := p_pending_tl_table_name;
7779       IF (p_change_obj.CHANGE_ID IS NOT NULL) THEN
7780         l_change_col_where_string := ' AND CHANGE_ID = '||p_change_obj.CHANGE_ID||' AND ';
7781       ELSE
7782         l_change_col_where_string := ' AND CHANGE_ID IS NULL AND ';
7783       END IF;
7784       IF (p_change_obj.CHANGE_LINE_ID IS NOT NULL) THEN
7785         l_change_col_where_string := l_change_col_where_string||
7786                                      'CHANGE_LINE_ID = '||
7787                                      p_change_obj.CHANGE_LINE_ID||' ';
7788       ELSE
7789         l_change_col_where_string := l_change_col_where_string||
7790                                      'CHANGE_LINE_ID IS NULL ';
7791       END IF;
7792 
7793       -------------------------
7794       -- Update the ACD Type --
7795       -------------------------
7796       l_change_col_value_string := 'ACD_TYPE = '''||
7797                                    NVL(p_change_obj.ACD_TYPE, 'NULL')||''', ';
7798     ELSE
7799 
7800       l_b_table_name := p_attr_group_metadata_obj.EXT_TABLE_B_NAME;
7801       l_tl_table_name := p_attr_group_metadata_obj.EXT_TABLE_TL_NAME;
7802       l_change_col_where_string := '';
7803       l_change_col_value_string := '';
7804 
7805     END IF;
7806 
7807     -------------------------------------------------------------------------------
7808     -- In case the p_pending_b_table_name and p_pending_tl_table_name are passed
7809     -- we will use them.
7810     -------------------------------------------------------------------------------
7811     IF (p_pending_b_table_name IS NOT NULL) THEN
7812         l_b_table_name := p_pending_b_table_name;
7813         l_tl_table_name := p_pending_tl_table_name;
7814     END IF;
7815 
7816      -- Start 4105841
7817      Get_Changed_Attributes(
7818             p_dml_operation                 => 'UPDATE'
7819           , p_object_name                   =>  null
7820           , p_pk_column_name_value_pairs    =>  p_pk_column_name_value_pairs
7821           , p_attr_group_metadata_obj       =>  p_attr_group_metadata_obj
7822           , p_ext_table_metadata_obj        =>  p_ext_table_metadata_obj
7823           , p_data_level                    =>  p_data_level
7824           , p_data_level_name_value_pairs   =>  p_data_level_name_value_pairs
7825           , p_attr_name_value_pairs         =>  p_attr_name_value_pairs
7826           , p_extension_id                  =>  p_extension_id
7827           , p_entity_id                     =>  p_entity_id
7828           , p_entity_index                  =>  p_entity_index
7829           , p_entity_code                   =>  p_entity_code
7830           , px_attr_diffs                   =>  l_attr_diffs_event);
7831     -- End 4105841
7832     -- Only propagate if at least one attribute has EIH code = LP/AP
7833     IF (l_propagate_hierarchy AND
7834         p_attr_group_metadata_obj.HIERARCHY_PROPAGATE_FLAG = 'Y') THEN
7835     --4105841 : Removing call to Get_Changed_Attributes as it's called before this check
7836       px_attr_diffs := l_attr_diffs_event;
7837     END IF;
7838     --------------------------------------------------------------
7839     -- First we open a cursor for use in one or both statements --
7840     --------------------------------------------------------------
7841     l_cursor_id := DBMS_SQL.Open_Cursor;
7842 
7843     ------------------------------------------------------------------
7844     -- We pass p_language_to_process from Implement_Change_Line; if --
7845     -- we have it, then we only insert if the passed-in language is --
7846     -- equal to USERENV('LANG').  Otherwise we update the base      --
7847     -- table if there are any non-translatable Attributes.          --
7848     ------------------------------------------------------------------
7849     IF (p_attr_group_metadata_obj.TRANS_ATTRS_COUNT <
7850         p_attr_group_metadata_obj.attr_metadata_table.COUNT AND
7851         (p_language_to_process IS NULL OR
7852          p_language_to_process = USERENV('LANG'))) THEN
7853 
7854       Init();
7855       FND_DSQL.Add_Text('UPDATE '||l_b_table_name||
7856                         ' SET '||l_extra_col_value_string||l_change_col_value_string);
7857 
7858       Add_Attr_Info_To_Statement(p_attr_group_metadata_obj.attr_metadata_table
7859                                 ,p_attr_name_value_pairs
7860                                 ,', '
7861                                 ,'EQUALS'
7862                                 ,'NONTRANS');
7863 
7864       ----------------------------------------------------------------------
7865       -- (No need to add a comma here, because Add_Attr_Info_To_Statement --
7866       -- adds a trailing separator to the list if it adds anything to it) --
7867       ----------------------------------------------------------------------
7868 
7869       FND_DSQL.Add_Text('LAST_UPDATED_BY = ');
7870       Add_Bind(p_bind_identifier => 'LAST_UPDATED_BY'
7871               ,p_value           => l_current_user_id);
7872       FND_DSQL.Add_Text(', ');
7873       FND_DSQL.Add_Text('LAST_UPDATE_DATE = ');
7874       Add_Bind(p_bind_identifier => 'LAST_UPDATE_DATE'
7875               ,p_value           => SYSDATE);
7876       FND_DSQL.Add_Text(', ');
7877       FND_DSQL.Add_Text('LAST_UPDATE_LOGIN = ');
7878       Add_Bind(p_bind_identifier => 'LAST_UPDATE_LOGIN'
7879               ,p_value           => l_current_login_id);
7880 
7881       FND_DSQL.Add_Text(' WHERE EXTENSION_ID = ');
7882       Add_Bind(p_bind_identifier => 'EXTENSION_ID'
7883               ,p_value           => p_extension_id);
7884 
7885       ----------------------------------------------------------------------------
7886       --We add the data_level_id to the where clause, it would be passed in
7887       --by the implementing team if the R12C changes for enhanced data level
7888       --support have been taken up.
7889       ----------------------------------------------------------------------------
7890       IF(p_data_level IS NOT NULL
7891          AND
7892          FND_API.TO_BOOLEAN(
7893               EGO_USER_ATTRS_COMMON_PVT.has_column_in_table(p_table_name  => l_b_table_name
7894                                                            ,p_column_name => 'DATA_LEVEL_ID'
7895                                                            )
7896                            )
7897          ) THEN
7898 
7899         l_data_level_id := Get_Data_Level_Id( p_attr_group_metadata_obj.APPLICATION_ID
7900                                              ,p_attr_group_metadata_obj.ATTR_GROUP_TYPE
7901                                              ,p_data_level);
7902 
7903       FND_DSQL.Add_Text(' AND DATA_LEVEL_ID = ');
7904       Add_Bind(p_bind_identifier => 'DATA_LEVEL_ID'
7905               ,p_value           => l_data_level_id);
7906 
7907       END IF;
7908 
7909       --Start Bug 5211171
7910       IF (p_data_level_name_value_pairs IS NOT NULL
7911          AND p_data_level_name_value_pairs.COUNT <> 0
7912          AND p_data_level_name_value_pairs(p_data_level_name_value_pairs.FIRST).VALUE IS NOT NULL) THEN
7913            l_col_values_index := p_data_level_name_value_pairs.FIRST;
7914            WHILE (l_col_values_index <= p_data_level_name_value_pairs.LAST)
7915            LOOP
7916 
7917              l_col_name := p_data_level_name_value_pairs(l_col_values_index).NAME;
7918              l_col_value := p_data_level_name_value_pairs(l_col_values_index).VALUE;
7919              IF (l_col_value is not NULL) THEN
7920                FND_DSQL.Add_Text(' AND '||l_col_name||' = ');
7921                Add_Bind(p_bind_identifier => l_col_name
7922                        ,p_value           => l_col_value);
7923              END IF;
7924              l_col_values_index := p_data_level_name_value_pairs.NEXT(l_col_values_index);
7925            END LOOP;
7926       END IF;--p_data_level_name_value_pairs IS NOT NULL
7927       --End Bug 5211171
7928 
7929       FND_DSQL.Add_Text(l_change_col_where_string);
7930       FND_DSQL.Add_Text(l_extra_col_where_string);
7931 
7932 
7933 
7934       l_dynamic_sql := FND_DSQL.Get_Text(FALSE);
7935 
7936       Debug_Msg('In Update_Row, l_dynamic_sql for base table is as follows:', 3);
7937       Debug_Msg('In Update_Row, l_dynamic_sql:'||l_dynamic_sql, 3);
7938       Debug_SQL(FND_DSQL.Get_Text(TRUE));
7939       Set_Binds_And_Dml(l_dynamic_sql ,'B');
7940 
7941       IF (p_execute_dml = FND_API.G_TRUE) THEN
7942         DBMS_SQL.Parse(l_cursor_id, l_dynamic_sql, DBMS_SQL.Native);
7943         FND_DSQL.Set_Cursor(l_cursor_id);
7944         FND_DSQL.Do_Binds();
7945       END IF;
7946 
7947       --Start 4105841 Raise Pre Event
7948       IF (p_change_obj IS NULL) THEN
7949         IF(p_raise_business_event) THEN
7950         Raise_WF_Event_If_Enabled(
7951             p_dml_type                      => 'UPDATE'
7952            ,p_attr_group_metadata_obj       => p_attr_group_metadata_obj
7953            ,p_extension_id                  => p_extension_id
7954            ,p_pk_column_name_value_pairs    => p_pk_column_name_value_pairs
7955            ,p_data_level_name_value_pairs   => p_data_level_name_value_pairs
7956            ,p_entity_id                     => p_entity_id
7957            ,p_entity_index                  => p_entity_index
7958            ,p_entity_code                   => p_entity_code
7959            ,p_pre_event_flag                => 'T'
7960            ,p_data_level_id                 => l_data_level_id
7961            ,px_attr_diffs                   => l_attr_diffs_event
7962           );
7963         l_pre_event_flag := 'T';
7964         END IF;
7965        END IF;
7966        --End 4105841
7967 
7968       IF (p_execute_dml =  FND_API.G_TRUE) THEN
7969         l_number_of_rows := DBMS_SQL.Execute(l_cursor_id);
7970       END IF;
7971 
7972     END IF;
7973 
7974     -------------------------------------------
7975     -- If there are translatable Attributes, --
7976     -- we will need to update the TL table   --
7977     -------------------------------------------
7978     IF (p_attr_group_metadata_obj.TRANS_ATTRS_COUNT > 0 AND
7979         p_attr_group_metadata_obj.EXT_TABLE_TL_NAME IS NOT NULL) THEN
7980 
7981       Init();
7982       FND_DSQL.Add_Text('UPDATE '||l_tl_table_name||
7983                         ' SET '||l_change_col_value_string);
7984 
7985       Add_Attr_Info_To_Statement(p_attr_group_metadata_obj.attr_metadata_table
7986                                 ,p_attr_name_value_pairs
7987                                 ,', '
7988                                 ,'EQUALS'
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       FND_DSQL.Add_Text('LAST_UPDATED_BY = ');
7997       Add_Bind(p_bind_identifier => 'LAST_UPDATED_BY'
7998               ,p_value           => l_current_user_id);
7999       FND_DSQL.Add_Text(', ');
8000       FND_DSQL.Add_Text('LAST_UPDATE_DATE = ');
8001       Add_Bind(p_bind_identifier => 'LAST_UPDATE_DATE'
8002               ,p_value           => SYSDATE);
8003       FND_DSQL.Add_Text(', ');
8004       FND_DSQL.Add_Text('LAST_UPDATE_LOGIN = ');
8005       Add_Bind(p_bind_identifier => 'LAST_UPDATE_LOGIN'
8006               ,p_value           => l_current_login_id);
8007       FND_DSQL.Add_Text(', ');
8008       FND_DSQL.Add_Text('SOURCE_LANG = ');
8009       Add_Bind(p_bind_identifier => 'SOURCE_LANG'
8010               ,p_value           => USERENV('LANG'));
8011       FND_DSQL.Add_Text(' WHERE EXTENSION_ID = ');
8012       Add_Bind(p_bind_identifier => 'EXTENSION_ID'
8013               ,p_value           => p_extension_id);
8014 
8015       ----------------------------------------------------------------------------
8016       --We add the data_level_id to the where clause, it would be passed in
8017       --by the implementing team if the R12C changes for enhanced data level
8018       --support have been taken up.
8019       ----------------------------------------------------------------------------
8020       IF(p_data_level IS NOT NULL
8021          AND
8022          FND_API.TO_BOOLEAN(
8023               EGO_USER_ATTRS_COMMON_PVT.has_column_in_table(p_table_name  => l_tl_table_name
8024                                                            ,p_column_name => 'DATA_LEVEL_ID'
8025                                                            )
8026                            )
8027          ) THEN
8028 
8029         l_data_level_id := Get_Data_Level_Id( p_attr_group_metadata_obj.APPLICATION_ID
8030                                              ,p_attr_group_metadata_obj.ATTR_GROUP_TYPE
8031                                              ,p_data_level);
8032 
8033       FND_DSQL.Add_Text(' AND DATA_LEVEL_ID = ');
8034       Add_Bind(p_bind_identifier => 'DATA_LEVEL_ID'
8035               ,p_value           => l_data_level_id);
8036 
8037       END IF;
8038 
8039 
8040        --Start Bug 5211171
8041       IF (p_data_level_name_value_pairs IS NOT NULL
8042          AND p_data_level_name_value_pairs.COUNT <> 0
8043          AND p_data_level_name_value_pairs(p_data_level_name_value_pairs.FIRST).VALUE IS NOT NULL) THEN
8044            l_col_values_index := p_data_level_name_value_pairs.FIRST;
8045            Debug_Msg('In UPDATE_ROW ,p_data_level_name_value_pairs IS NOT NULL');
8046            WHILE (l_col_values_index <= p_data_level_name_value_pairs.LAST)
8047            LOOP
8048              l_col_name := p_data_level_name_value_pairs(l_col_values_index).NAME;
8049              l_col_value := p_data_level_name_value_pairs(l_col_values_index).VALUE;
8050              IF (l_col_value is not NULL) THEN
8051                FND_DSQL.Add_Text(' AND '||l_col_name||' = ');
8052                Add_Bind(p_bind_identifier => l_col_name
8053                        ,p_value           => l_col_value);
8054              END IF;
8055              l_col_values_index := p_class_code_name_value_pairs.NEXT(l_col_values_index);
8056            END LOOP;
8057       END IF;--p_data_level_name_value_pairs IS NOT NULL
8058       --End Bug 5211171
8059 
8060       FND_DSQL.Add_Text(l_change_col_where_string);
8061 
8062       -----------------------------------------------------------------
8063       -- We pass p_language_to_process from Implement_Change_Line so --
8064       -- that each pending TL row only updates one production row    --
8065       -----------------------------------------------------------------
8066       IF (p_language_to_process IS NOT NULL) THEN
8067         FND_DSQL.Add_Text(' AND ((SOURCE_LANG = ');
8068         Add_Bind(p_bind_identifier => 'SOURCE_LANG'
8069                 ,p_value           => USERENV('LANG'));
8070         FND_DSQL.Add_Text(' AND LANGUAGE = ');
8071         Add_Bind(p_bind_identifier => 'LANGUAGE'
8072                 ,p_value           => p_language_to_process);
8073         FND_DSQL.Add_Text(') OR (SOURCE_LANG <> ');
8074         Add_Bind(p_bind_identifier => 'SOURCE_LANG'
8075                 ,p_value           => USERENV('LANG'));
8076         FND_DSQL.Add_Text(' AND LANGUAGE = ');
8077         Add_Bind(p_bind_identifier => 'LANGUAGE'
8078                 ,p_value           => USERENV('LANG'));
8079         FND_DSQL.Add_Text('))');
8080       ELSE
8081         ----------------------------------------------------------
8082         -- In all other flows, we want to update all rows whose --
8083         -- language or source language is the current language  --
8084         ----------------------------------------------------------
8085         FND_DSQL.Add_Text(' AND (LANGUAGE = ');
8086         Add_Bind(p_bind_identifier => 'LANGUAGE'
8087                 ,p_value           => USERENV('LANG'));
8088         FND_DSQL.Add_Text(' OR SOURCE_LANG = ');
8089         Add_Bind(p_bind_identifier => 'SOURCE_LANG'
8090                 ,p_value           => USERENV('LANG'));
8091         FND_DSQL.Add_Text(')');
8092       END IF;
8093 
8094 
8095       l_dynamic_sql := FND_DSQL.Get_Text(FALSE);
8096       Set_Binds_And_Dml(l_dynamic_sql ,'TL');
8097 
8098       Debug_Msg('In Update_Row, l_dynamic_sql for TL table is as follows:', 3);
8099       Debug_SQL(FND_DSQL.Get_Text(TRUE));
8100 
8101       IF (p_execute_dml = FND_API.G_TRUE) THEN
8102         DBMS_SQL.Parse(l_cursor_id, l_dynamic_sql, DBMS_SQL.Native);
8103         FND_DSQL.Set_Cursor(l_cursor_id);
8104         FND_DSQL.Do_Binds();
8105       END IF;
8106 
8107       --Start 4105841
8108       --Raise pre Event if not already raised
8109       IF (p_change_obj IS NULL) AND (l_pre_event_flag = 'F') THEN
8110         IF(p_raise_business_event) THEN
8111         Raise_WF_Event_If_Enabled(
8112             p_dml_type                      => 'UPDATE'
8113            ,p_attr_group_metadata_obj       => p_attr_group_metadata_obj
8114            ,p_extension_id                  => p_extension_id
8115            ,p_pk_column_name_value_pairs    => p_pk_column_name_value_pairs
8116            ,p_data_level_name_value_pairs   => p_data_level_name_value_pairs
8117            ,p_entity_id                     => p_entity_id
8118            ,p_entity_index                  => p_entity_index
8119            ,p_entity_code                   => p_entity_code
8120            ,p_pre_event_flag                => 'T'
8121            ,p_data_level_id                 => l_data_level_id
8122            ,px_attr_diffs                   => l_attr_diffs_event
8123           );
8124         l_pre_event_flag := 'T';
8125         END IF;
8126       END IF;
8127       --End 4105841
8128 
8129       IF (p_execute_dml = FND_API.G_TRUE) THEN
8130         l_number_of_rows := DBMS_SQL.Execute(l_cursor_id);
8131       END IF;
8132 
8133 
8134     END IF;
8135 
8136 
8137     ----------------------------------
8138     -- Finally, we close our cursor --
8139     ----------------------------------
8140     DBMS_SQL.Close_Cursor(l_cursor_id);
8141 
8142     --
8143     -- If caller passes multiple rows with same UK values, what should I do?
8144     -- Currently, I think they'll be treated as multiple instances of the same row,
8145     -- so the data for the last-loaded one will overwrite all previous data.
8146     -- I think that's OK.
8147     --
8148 
8149     IF (l_propagate_hierarchy
8150         AND p_attr_group_metadata_obj.HIERARCHY_PROPAGATE_FLAG = 'Y'
8151         AND px_attr_diffs.COUNT > 0 AND p_execute_dml = FND_API.G_TRUE) THEN --Bug fix 5220020
8152       Propagate_Attributes( p_pk_column_name_value_pairs
8153                           , p_class_code_name_value_pairs
8154                           , p_data_level_name_value_pairs
8155                           , px_attr_diffs
8156                           , G_UPDATE_MODE
8157                           , p_attr_group_metadata_obj
8158                           , x_return_status
8159                           , l_error_message);
8160     END IF;
8161     IF (x_return_status IN (G_RET_STS_ERROR, G_RET_STS_UNEXP_ERROR )) THEN
8162       fnd_message.set_name('EGO','EGO_GENERIC_MSG_TEXT');
8163       fnd_message.set_token('MESSAGE',l_error_message);
8164       fnd_msg_pub.Add;
8165       RETURN;
8166     END IF;
8167 
8168     --------------------------------------------------
8169     -- If we inserted into the production tables... --
8170     -- we see about raising a Business Event      --
8171     --------------------------------------------------
8172     IF (p_change_obj IS NULL) THEN
8173      IF(p_raise_business_event) THEN
8174       Raise_WF_Event_If_Enabled(
8175         p_dml_type                      => 'UPDATE'
8176        ,p_attr_group_metadata_obj       => p_attr_group_metadata_obj
8177        ,p_extension_id                  => p_extension_id
8178        ,p_pk_column_name_value_pairs    => p_pk_column_name_value_pairs
8179        ,p_data_level_name_value_pairs   => p_data_level_name_value_pairs
8180        ,p_entity_id                     => p_entity_id
8181        ,p_entity_index                  => p_entity_index
8182        ,p_entity_code                   => p_entity_code
8183        ,p_data_level_id                 => l_data_level_id
8184        ,px_attr_diffs                   => l_attr_diffs_event
8185       );
8186       END IF;
8187     END IF;
8188 
8189     Debug_Msg('In Update_Row, done', 1);
8190 
8191     IF FND_API.To_Boolean(p_commit) THEN
8192       COMMIT WORK;
8193     END IF;
8194 
8195     x_return_status := FND_API.G_RET_STS_SUCCESS;
8196 
8197   EXCEPTION
8198     -----------------------------------------------------------
8199     -- There are no expected errors in this procedure, so... --
8200     -----------------------------------------------------------
8201     --Start 4105841
8202     --Checking for Exception raised by preAttribute Change Event
8203     --don't put to the stack already added in EGO_WF_WRAPPER_PVT
8204     WHEN EGO_USER_ATTRS_COMMON_PVT.G_SUBSCRIPTION_EXC THEN
8205       Debug_Msg('Update_Row EXCEPTION  EGO_USER_ATTRS_COMMON_PVT.G_SUBSCRIPTION_EXC ');
8206 
8207       IF FND_API.To_Boolean(p_commit) THEN
8208         ROLLBACK TO update_row;
8209       END IF;
8210       x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
8211     --End 4105841
8212 
8213     WHEN OTHERS THEN
8214       Debug_Msg('Update_Row EXCEPTION  others '||SQLERRM);
8215       IF FND_API.To_Boolean(p_commit) THEN
8216         ROLLBACK TO update_row;
8217       END IF;
8218       x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
8219 
8220       DECLARE
8221         l_token_table            ERROR_HANDLER.Token_Tbl_Type;
8222       BEGIN
8223         l_token_table(1).TOKEN_NAME := 'PKG_NAME';
8224         l_token_table(1).TOKEN_VALUE := G_PKG_NAME;
8225         l_token_table(2).TOKEN_NAME := 'API_NAME';
8226         l_token_table(2).TOKEN_VALUE := l_api_name;
8227         l_token_table(3).TOKEN_NAME := 'SQL_ERR_MSG';
8228         l_token_table(3).TOKEN_VALUE := SQLERRM;
8229 
8230         ERROR_HANDLER.Add_Error_Message(
8231           p_message_name      => 'EGO_PLSQL_ERR'
8232          ,p_application_id    => 'EGO'
8233          ,p_token_tbl         => l_token_table
8234          ,p_message_type      => FND_API.G_RET_STS_ERROR
8235          ,p_row_identifier    => G_USER_ROW_IDENTIFIER
8236          ,p_entity_id         => p_entity_id
8237          ,p_entity_index      => p_entity_index
8238          ,p_entity_code       => p_entity_code
8239          ,p_addto_fnd_stack   => G_ADD_ERRORS_TO_FND_STACK
8240         );
8241       END;
8242 
8243 END Update_Row;
8244 
8245 ----------------------------------------------------------------------
8246 PROCEDURE Delete_Row (
8247         p_api_version                   IN   NUMBER
8248        ,p_attr_group_metadata_obj       IN   EGO_ATTR_GROUP_METADATA_OBJ
8249        ,p_pk_column_name_value_pairs    IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
8250        ,p_class_code_name_value_pairs   IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
8251        ,p_data_level                    IN   VARCHAR2   DEFAULT NULL --R12C
8252        ,p_data_level_name_value_pairs   IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
8253        ,p_extension_id                  IN   NUMBER
8254         -- Start ssingal -For Ucc Net Attribute Propagation
8255        ,p_attr_name_value_pairs         IN   EGO_USER_ATTR_DATA_TABLE
8256        ,p_ext_table_metadata_obj        IN   EGO_EXT_TABLE_METADATA_OBJ
8257         -- End ssingal
8258        ,p_language_to_process           IN   VARCHAR2
8259        ,p_change_obj                    IN   EGO_USER_ATTR_CHANGE_OBJ
8260        ,p_extra_pk_col_name_val_pairs   IN   EGO_COL_NAME_VALUE_PAIR_ARRAY DEFAULT NULL
8261        ,p_pending_b_table_name          IN   VARCHAR2
8262        ,p_pending_tl_table_name         IN   VARCHAR2
8263        ,p_execute_dml                   IN   VARCHAR2   DEFAULT FND_API.G_TRUE
8264         -- Start ssingal -For Ucc Net Attribute Propagation
8265        ,p_bulkload_flag                 IN   BOOLEAN DEFAULT FALSE
8266        ,px_attr_diffs                   IN   OUT NOCOPY EGO_USER_ATTR_DIFF_TABLE
8267         -- End ssingal -For Ucc Net Attribute Propagation
8268        ,p_entity_id                     IN   VARCHAR2
8269        ,p_entity_index                  IN   NUMBER
8270        ,p_entity_code                   IN   VARCHAR2
8271        ,p_commit                        IN   VARCHAR2
8272        ,p_raise_business_event          IN   BOOLEAN DEFAULT TRUE
8273        ,x_return_status                 OUT  NOCOPY VARCHAR2
8274 ) IS
8275 
8276     l_api_name               CONSTANT VARCHAR2(30) := 'Delete_Row';
8277 
8278     --we don't use l_api_version yet, but eventually we might:
8279     --if we change required parameters, version goes FROM n.x to (n+1).x
8280     --if we change optional parameters, version goes FROM x.n to x.(n+1)
8281     l_api_version            CONSTANT NUMBER := 1.0;
8282 
8283     l_b_table_name           VARCHAR2(30);
8284     l_tl_table_name          VARCHAR2(30);
8285     l_change_col_where_string VARCHAR2(1000);
8286     l_dynamic_sql            VARCHAR2(1000);
8287     l_error_message          VARCHAR2(4000);
8288     l_event_name             VARCHAR2(240);
8289     l_is_event_enabled_flag  VARCHAR2(1);
8290     l_event_key              VARCHAR2(240);
8291     l_parameter_list         WF_PARAMETER_LIST_T := WF_PARAMETER_LIST_T();
8292     l_parameter_t            WF_PARAMETER_T:= WF_PARAMETER_T(null, null);
8293     -- Start ssingal -For Ucc Net Attribute Propagation
8294     l_propagate_hierarchy    BOOLEAN :=TRUE;
8295     -- End ssingal -For Ucc Net Attribute Propagation
8296     --Start 4105841
8297     l_attr_diffs_event       EGO_USER_ATTR_DIFF_TABLE;
8298     l_extra_col_where_string VARCHAR2(1000);
8299     l_index                  NUMBER;
8300     l_data_level_id          NUMBER;
8301 
8302   BEGIN
8303 
8304     Debug_Msg('In Delete_Row, starting', 1);
8305 
8306     IF FND_API.To_Boolean(p_commit) THEN
8307       SAVEPOINT delete_row;
8308     END IF;
8309 
8310     -- Check for call compatibility
8311     IF NOT FND_API.Compatible_API_Call (l_api_version, p_api_version,
8312                                         l_api_name, G_PKG_NAME)
8313     THEN
8314       RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
8315     END IF;
8316 
8317     IF (p_extension_id IS NULL) THEN
8318       RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
8319     END IF;
8320     -- Start ssingal -For Ucc Net Attribute Propagation
8321     IF  p_bulkload_flag THEN
8322       l_propagate_hierarchy := FALSE;
8323     END IF;
8324 
8325     --Start 4105841
8326     Get_Changed_Attributes(
8327            p_dml_operation                 => 'DELETE'
8328          , p_object_name                   =>  null
8329          , p_pk_column_name_value_pairs    =>  p_pk_column_name_value_pairs
8330          , p_attr_group_metadata_obj       =>  p_attr_group_metadata_obj
8331          , p_ext_table_metadata_obj        =>  p_ext_table_metadata_obj
8332          , p_data_level                    =>  p_data_level
8333          , p_data_level_name_value_pairs   =>  p_data_level_name_value_pairs
8334          , p_attr_name_value_pairs         =>  p_attr_name_value_pairs
8335          , p_extension_id                  =>  p_extension_id
8336          , p_entity_id                     =>  p_entity_id
8337          , p_entity_index                  =>  p_entity_index
8338          , p_entity_code                   =>  p_entity_code
8339          , px_attr_diffs                   =>  l_attr_diffs_event);
8340     --End 4105841
8341 
8342    IF (l_propagate_hierarchy AND
8343         p_attr_group_metadata_obj.HIERARCHY_PROPAGATE_FLAG = 'Y'
8344        ) THEN
8345     --4105841 : Removing call to Get_Changed_Attributes as it's called before this check
8346        px_attr_diffs :=  l_attr_diffs_event;
8347      END IF;
8348 
8349     -- End ssingal -For Ucc Net Attribute Propagation
8350 
8351     --------------------------------------------------------------------------
8352     -- Determine whether we're in Change mode and set variables accordingly --
8353     --------------------------------------------------------------------------
8354 
8355     IF (p_change_obj IS NOT NULL AND
8356         p_pending_b_table_name IS NOT NULL AND
8357         p_pending_tl_table_name IS NOT NULL) THEN
8358 
8359       l_b_table_name := p_pending_b_table_name;
8360       l_tl_table_name := p_pending_tl_table_name;
8361       IF (p_change_obj.CHANGE_ID IS NOT NULL) THEN
8362         l_change_col_where_string := ' AND CHANGE_ID = '||p_change_obj.CHANGE_ID||' AND ';
8363       ELSE
8364         l_change_col_where_string := ' AND CHANGE_ID IS NULL AND ';
8365       END IF;
8366       IF (p_change_obj.CHANGE_LINE_ID IS NOT NULL) THEN
8367         l_change_col_where_string := l_change_col_where_string||
8368                                      'CHANGE_LINE_ID = '||
8369                                      p_change_obj.CHANGE_LINE_ID||' ';
8370       ELSE
8371         l_change_col_where_string := l_change_col_where_string||
8372                                      'CHANGE_LINE_ID IS NULL ';
8373       END IF;
8374     ELSE
8375 
8376       l_b_table_name := p_attr_group_metadata_obj.EXT_TABLE_B_NAME;
8377       l_tl_table_name := p_attr_group_metadata_obj.EXT_TABLE_TL_NAME;
8378       l_change_col_where_string := '';
8379 
8380     END IF;
8381 
8382     ------------------------------------------------------------------------------------------
8383     -- In case the extra pk columns values are passed we add them into the dml where clause
8384     ------------------------------------------------------------------------------------------
8385 
8386     l_extra_col_where_string := ' ';
8387 
8388     IF (p_extra_pk_col_name_val_pairs IS NOT NULL AND
8389         p_extra_pk_col_name_val_pairs.COUNT > 0) THEN
8390 
8391       l_index := p_extra_pk_col_name_val_pairs.FIRST;
8392       WHILE (l_index IS NOT NULL)
8393       LOOP
8394 
8395         IF (p_extra_pk_col_name_val_pairs(l_index).NAME IS NOT NULL) THEN
8396            l_extra_col_where_string := l_extra_col_where_string || ' AND ';
8397            IF (p_extra_pk_col_name_val_pairs(l_index).VALUE IS NOT NULL) THEN
8398               l_extra_col_where_string := l_extra_col_where_string || p_extra_pk_col_name_val_pairs(l_index).NAME || ' = '
8399                                                                    ||  p_extra_pk_col_name_val_pairs(l_index).VALUE ;
8400            ELSE
8401               l_extra_col_where_string := l_extra_col_where_string || p_extra_pk_col_name_val_pairs(l_index).NAME || ' IS  NULL ';
8402            END IF;
8403         END IF;
8404         l_index := p_extra_pk_col_name_val_pairs.NEXT(l_index);
8405 
8406       END LOOP;
8407 
8408     END IF;
8409 
8410     -------------------------------------------------------------------------------
8411     -- In case the p_pending_b_table_name and p_pending_tl_table_name are passed
8412     -- we will use them.
8413     -------------------------------------------------------------------------------
8414     IF (p_pending_b_table_name IS NOT NULL) THEN
8415         l_b_table_name := p_pending_b_table_name;
8416         l_tl_table_name := p_pending_tl_table_name;
8417     END IF;
8418 
8419     l_data_level_id := Get_Data_Level_Id( p_attr_group_metadata_obj.APPLICATION_ID
8420                                          ,p_attr_group_metadata_obj.ATTR_GROUP_TYPE
8421                                          ,p_data_level);
8422 
8423     ---------------------------------------------------------------
8424     -- We pass p_language_to_process from Implement_Change_Line; --
8425     -- if we have it, then we only delete from the base table if --
8426     -- the passed-in language is equal to USERENV('LANG') and we --
8427     -- only delete the TL row for that language.                 --
8428     -- Otherwise we delete from both tables normally.            --
8429     ---------------------------------------------------------------
8430     IF (p_language_to_process IS NULL OR
8431         p_language_to_process = USERENV('LANG')) THEN
8432       l_dynamic_sql := 'DELETE FROM '||l_b_table_name||
8433                        ' WHERE EXTENSION_ID = '||p_extension_id||l_change_col_where_string||l_extra_col_where_string;
8434 
8435       Debug_SQL(l_dynamic_sql);
8436       --Start 4105841 Raise Pre event
8437       IF (p_change_obj IS NULL) THEN
8438        IF(p_raise_business_event) THEN
8439         Raise_WF_Event_If_Enabled(
8440           p_dml_type                      => 'DELETE'
8441          ,p_attr_group_metadata_obj       => p_attr_group_metadata_obj
8442          ,p_extension_id                  => p_extension_id
8443          ,p_pk_column_name_value_pairs    => p_pk_column_name_value_pairs
8444          ,p_data_level_name_value_pairs   => p_data_level_name_value_pairs
8445          ,p_entity_id                     => p_entity_id
8446          ,p_entity_index                  => p_entity_index
8447          ,p_entity_code                   => p_entity_code
8448          ,p_pre_event_flag                => 'T'
8449          ,p_data_level_id                 => l_data_level_id
8450          ,px_attr_diffs                   => l_attr_diffs_event
8451         );
8452         END IF;
8453       END IF;
8454       --End 4105841
8455 
8456       Set_Binds_And_Dml(l_dynamic_sql ,'B');
8457 
8458       IF (p_execute_dml = FND_API.G_TRUE) THEN
8459         EXECUTE IMMEDIATE l_dynamic_sql;
8460       END IF;
8461     END IF;
8462 
8463     IF (l_tl_table_name IS NOT NULL) THEN
8464 
8465       l_dynamic_sql := 'DELETE FROM '||l_tl_table_name||
8466                        ' WHERE EXTENSION_ID = '||p_extension_id||l_change_col_where_string||l_extra_col_where_string;
8467 
8468       -----------------------------------------------------------------
8469       -- We pass p_language_to_process from Implement_Change_Line so --
8470       -- that each pending TL row only deletes one production row    --
8471       -----------------------------------------------------------------
8472       IF (p_language_to_process IS NOT NULL) THEN
8473         FND_DSQL.Add_Text(' AND LANGUAGE = ');
8474         Add_Bind(p_value => p_language_to_process);
8475       END IF;
8476     END IF;
8477 
8478     Debug_SQL(l_dynamic_sql);
8479 
8480     Set_Binds_And_Dml(l_dynamic_sql ,'TL');
8481 
8482     IF (p_execute_dml = FND_API.G_TRUE) THEN
8483       EXECUTE IMMEDIATE l_dynamic_sql;
8484     END IF;
8485     -- Start ssingal -For Ucc Net Attribute Propagation
8486 
8487     -- Only propagate if at least one attribute has EIH code = LP/AP
8488     IF (l_propagate_hierarchy AND
8489         p_attr_group_metadata_obj.HIERARCHY_PROPAGATE_FLAG = 'Y'
8490         AND px_attr_diffs.COUNT > 0  AND p_execute_dml = FND_API.G_TRUE) THEN --Bug fix 5220020
8491 
8492       Propagate_Attributes( p_pk_column_name_value_pairs
8493                           , p_class_code_name_value_pairs
8494                           , p_data_level_name_value_pairs
8495                           , px_attr_diffs
8496                           , G_DELETE_MODE
8497                           , p_attr_group_metadata_obj
8498                           , x_return_status
8499                           , l_error_message);
8500     END IF;
8501     -- End ssingal -For Ucc Net Attribute Propagation
8502     IF (x_return_status IN (G_RET_STS_ERROR, G_RET_STS_UNEXP_ERROR )) THEN
8503       fnd_message.set_name('EGO','EGO_GENERIC_MSG_TEXT');
8504       fnd_message.set_token('MESSAGE',l_error_message);
8505       fnd_msg_pub.Add;
8506       RETURN;
8507     END IF;
8508 
8509     -------------------------------------------------
8510     -- If we deleted from the production tables... --
8511     -- we see about raising a Business Event      --
8512     -------------------------------------------------
8513     IF (p_change_obj IS NULL) THEN
8514       IF(p_raise_business_event) THEN
8515       Raise_WF_Event_If_Enabled(
8516         p_dml_type                      => 'DELETE'
8517        ,p_attr_group_metadata_obj       => p_attr_group_metadata_obj
8518        ,p_extension_id                  => p_extension_id
8519        ,p_pk_column_name_value_pairs    => p_pk_column_name_value_pairs
8520        ,p_data_level_name_value_pairs   => p_data_level_name_value_pairs
8521        ,p_entity_id                     => p_entity_id
8522        ,p_entity_index                  => p_entity_index
8523        ,p_entity_code                   => p_entity_code
8524        ,p_data_level_id                 => l_data_level_id
8525        ,px_attr_diffs                   => l_attr_diffs_event
8526       );
8527       END IF;
8528     END IF;
8529 
8530     Debug_Msg('In Delete_Row, done', 1);
8531 
8532     IF FND_API.To_Boolean(p_commit) THEN
8533       COMMIT WORK;
8534     END IF;
8535 
8536     x_return_status := FND_API.G_RET_STS_SUCCESS;
8537 
8538   EXCEPTION
8539     -----------------------------------------------------------
8540     -- There are no expected errors in this procedure, so... --
8541     -----------------------------------------------------------
8542     --Start 4105841
8543     --Checking for Exception raised by preAttribute Change Event
8544     --don't put to the stack already added in EGO_WF_WRAPPER_PVT
8545     WHEN EGO_USER_ATTRS_COMMON_PVT.G_SUBSCRIPTION_EXC THEN
8546       Debug_Msg('Delete_Row EXCEPTION  EGO_USER_ATTRS_COMMON_PVT.G_SUBSCRIPTION_EXC ');
8547 
8548       IF FND_API.To_Boolean(p_commit) THEN
8549         ROLLBACK TO delete_row;
8550       END IF;
8551       x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
8552     --End 4105841
8553     WHEN OTHERS THEN
8554       Debug_Msg('Delete_Row EXCEPTION  others '||SQLERRM);
8555       IF FND_API.To_Boolean(p_commit) THEN
8556         ROLLBACK TO delete_row;
8557       END IF;
8558       x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
8559 
8560       DECLARE
8561         l_token_table            ERROR_HANDLER.Token_Tbl_Type;
8562       BEGIN
8563         l_token_table(1).TOKEN_NAME := 'PKG_NAME';
8564         l_token_table(1).TOKEN_VALUE := G_PKG_NAME;
8565         l_token_table(2).TOKEN_NAME := 'API_NAME';
8566         l_token_table(2).TOKEN_VALUE := l_api_name;
8567         l_token_table(3).TOKEN_NAME := 'SQL_ERR_MSG';
8568         l_token_table(3).TOKEN_VALUE := SQLERRM;
8569 
8570         ERROR_HANDLER.Add_Error_Message(
8571           p_message_name      => 'EGO_PLSQL_ERR'
8572          ,p_application_id    => 'EGO'
8573          ,p_token_tbl         => l_token_table
8574          ,p_message_type      => FND_API.G_RET_STS_ERROR
8575          ,p_row_identifier    => G_USER_ROW_IDENTIFIER
8576          ,p_entity_id         => p_entity_id
8577          ,p_entity_index      => p_entity_index
8578          ,p_entity_code       => p_entity_code
8579          ,p_addto_fnd_stack   => G_ADD_ERRORS_TO_FND_STACK
8580         );
8581       END;
8582 
8583 END Delete_Row;
8584 
8585 ----------------------------------------------------------------------
8586 
8587 PROCEDURE Validate_Row_Pvt (
8588         p_api_version                   IN   NUMBER
8589        ,p_object_id                     IN   NUMBER
8590        ,p_validate_hierarchy            IN   VARCHAR2   DEFAULT FND_API.G_TRUE --Added for bugFix:5275391
8591        ,p_attr_group_metadata_obj       IN   EGO_ATTR_GROUP_METADATA_OBJ
8592        ,p_ext_table_metadata_obj        IN   EGO_EXT_TABLE_METADATA_OBJ
8593        ,p_pk_column_name_value_pairs    IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
8594        ,p_class_code_name_value_pairs   IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
8595        ,p_data_level                    IN   VARCHAR2   DEFAULT NULL --R12C
8596        ,p_data_level_name_value_pairs   IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
8597        ,p_extension_id                  IN   NUMBER
8598        ,p_mode                          IN   VARCHAR2
8599        ,p_entity_id                     IN   VARCHAR2   DEFAULT NULL
8600        ,p_entity_index                  IN   NUMBER     DEFAULT NULL
8601        ,p_entity_code                   IN   VARCHAR2   DEFAULT NULL
8602        ,px_attr_name_value_pairs        IN OUT NOCOPY EGO_USER_ATTR_DATA_TABLE
8603        ,x_return_status                 OUT NOCOPY VARCHAR2
8604 ) IS
8605 
8606     l_api_name               CONSTANT VARCHAR2(30) := 'Validate_Row_Pvt';
8607 
8608     --we don't use l_api_version yet, but eventually we might:
8609     --if we change required parameters, version goes FROM n.x to (n+1).x
8610     --if we change optional parameters, version goes FROM x.n to x.(n+1)
8611     l_api_version            CONSTANT NUMBER := 1.0;
8612 
8613     l_is_valid_row           BOOLEAN := TRUE;
8614     l_err_msg_name           VARCHAR2(30);
8615     l_token_table            ERROR_HANDLER.Token_Tbl_Type;
8616     l_is_duplicate_attr      BOOLEAN;
8617     l_duplicate_attr_index   NUMBER;
8618     l_attr_value_index       NUMBER;
8619     l_attr_metadata_obj      EGO_ATTR_METADATA_OBJ;
8620     l_attr_name_table        LOCAL_VARCHAR_TABLE;
8621     l_hierarchy_results      LOCAL_HIERARCHY_REC;
8622 
8623   BEGIN
8624 
8625     Debug_Msg(l_api_name || ' starting', 1);
8626 
8627     -- Check for call compatibility
8628     IF NOT FND_API.Compatible_API_Call (l_api_version, p_api_version,
8629                                         l_api_name, G_PKG_NAME)
8630     THEN
8631       RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
8632     END IF;
8633 
8634     Debug_Msg(l_api_name || ' calling Is_Data_Level_Correct ', 1);
8635     IF (NOT Is_Data_Level_Correct(
8636               p_object_id                     => p_object_id
8637              ,p_attr_group_id                 => p_attr_group_metadata_obj.ATTR_GROUP_ID
8638              ,p_ext_table_metadata_obj        => p_ext_table_metadata_obj
8639              ,p_class_code_name_value_pairs   => p_class_code_name_value_pairs
8640              ,p_data_level                    => p_data_level
8641              ,p_data_level_name_value_pairs   => p_data_level_name_value_pairs
8642              ,p_attr_group_disp_name          => p_attr_group_metadata_obj.ATTR_GROUP_DISP_NAME
8643              ,x_err_msg_name                  => l_err_msg_name
8644              ,x_token_table                   => l_token_table)
8645        ) THEN
8646 
8647       ERROR_HANDLER.Add_Error_Message(
8648         p_message_name      => l_err_msg_name
8649        ,p_application_id    => 'EGO'
8650        ,p_token_tbl         => l_token_table
8651        ,p_message_type      => FND_API.G_RET_STS_ERROR
8652        ,p_row_identifier    => G_USER_ROW_IDENTIFIER
8653        ,p_entity_id         => p_entity_id
8654        ,p_entity_index      => p_entity_index
8655        ,p_entity_code       => p_entity_code
8656        ,p_addto_fnd_stack   => G_ADD_ERRORS_TO_FND_STACK
8657       );
8658 
8659       l_token_table.DELETE();
8660 
8661       l_is_valid_row := FALSE;
8662 
8663       Debug_Msg(l_api_name || ' l_is_valid_row is now FALSE ', 1);
8664 
8665     END IF;
8666     Debug_Msg(l_api_name || ' returned Is_Data_Level_Correct ', 1);
8667 
8668 IF px_attr_name_value_pairs.COUNT > 0 THEN
8669     Debug_Msg(l_api_name || ' px_attr_name_value_pairs has values', 1);
8670 ELSE
8671     Debug_Msg(l_api_name || ' px_attr_name_value_pairs IS NULL!! ', 1);
8672 END IF;
8673     l_attr_value_index := px_attr_name_value_pairs.FIRST;
8674     WHILE (l_attr_value_index <= px_attr_name_value_pairs.LAST)
8675     LOOP
8676 
8677       l_attr_metadata_obj := EGO_USER_ATTRS_COMMON_PVT.Find_Metadata_For_Attr(
8678                                p_attr_metadata_table => p_attr_group_metadata_obj.attr_metadata_table
8679                               ,p_attr_name           => px_attr_name_value_pairs(l_attr_value_index).ATTR_NAME
8680                              );
8681 
8682       ---------------------------------------------------------------------------
8683       -- First we check whether we have already processed this Attribute.  The --
8684       -- caller may have passed multiple values for the same Attribute, which  --
8685       -- is an error, and we also don't want to spend time validating the same --
8686       -- Attribute more than once.                                             --
8687       ---------------------------------------------------------------------------
8688       l_is_duplicate_attr := FALSE;
8689       IF (l_attr_name_table.COUNT > 0) THEN
8690         l_duplicate_attr_index := l_attr_name_table.FIRST;
8691         WHILE (l_duplicate_attr_index <= l_attr_name_table.LAST)
8692         LOOP
8693           EXIT WHEN (l_is_duplicate_attr);
8694           IF (l_attr_metadata_obj.ATTR_NAME = l_attr_name_table(l_duplicate_attr_index)) THEN
8695             l_is_duplicate_attr := TRUE;
8696           END IF;
8697           l_duplicate_attr_index := l_attr_name_table.NEXT(l_duplicate_attr_index);
8698         END LOOP;
8699       END IF;
8700 
8701       IF (l_is_duplicate_attr) THEN
8702 
8703         l_err_msg_name := 'EGO_EF_MULT_VALUES_FOR_ATTR';
8704 
8705         l_token_table(1).TOKEN_NAME := 'ATTR_NAME';
8706         l_token_table(1).TOKEN_VALUE := l_attr_metadata_obj.ATTR_DISP_NAME;
8707         l_token_table(2).TOKEN_NAME := 'AG_NAME';
8708         l_token_table(2).TOKEN_VALUE := p_attr_group_metadata_obj.ATTR_GROUP_DISP_NAME;
8709 
8710             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);
8711 
8712         ERROR_HANDLER.Add_Error_Message(
8713           p_message_name      => l_err_msg_name
8714          ,p_application_id    => 'EGO'
8715          ,p_token_tbl         => l_token_table
8716          ,p_message_type      => FND_API.G_RET_STS_ERROR
8717          ,p_row_identifier    => G_USER_ROW_IDENTIFIER
8718          ,p_entity_id         => p_entity_id
8719          ,p_entity_index      => p_entity_index
8720          ,p_entity_code       => p_entity_code
8721          ,p_addto_fnd_stack   => G_ADD_ERRORS_TO_FND_STACK
8722         );
8723 
8724         l_token_table.DELETE();
8725 
8726         l_is_valid_row := FALSE;
8727 
8728             Debug_Msg(l_api_name ||'l_is_valid_row is now FALSE', 1);
8729 
8730       ELSE
8731 
8732         ----------------------------------------------------------------------
8733         -- Add the Internal Name for checking against subsequent Attributes --
8734         ----------------------------------------------------------------------
8735         l_attr_name_table(l_attr_name_table.COUNT+1) := l_attr_metadata_obj.ATTR_NAME;
8736 
8737         ---------------------------------------------------------------------------
8738         -- If the Attribute is marked as Required and the mode is G_CREATE_MODE, --
8739         -- then the user must pass a value for the Attribute                     --
8740         ---------------------------------------------------------------------------
8741             Debug_Msg(l_api_name ||' loop '||l_attr_value_index||', checking required flag');
8742 
8743         IF (NOT Is_Required_Flag_Respected(l_attr_metadata_obj
8744                                           ,p_mode
8745                                           ,px_attr_name_value_pairs(l_attr_value_index)
8746                                           ,p_attr_group_metadata_obj.ATTR_GROUP_DISP_NAME
8747                                           ,l_err_msg_name
8748                                           ,l_token_table)) THEN
8749 
8750           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);
8751 
8752           ERROR_HANDLER.Add_Error_Message(
8753             p_message_name      => l_err_msg_name
8754            ,p_application_id    => 'EGO'
8755            ,p_token_tbl         => l_token_table
8756            ,p_message_type      => FND_API.G_RET_STS_ERROR
8757            ,p_row_identifier    => G_USER_ROW_IDENTIFIER
8758            ,p_entity_id         => p_entity_id
8759            ,p_entity_index      => p_entity_index
8760            ,p_entity_code       => p_entity_code
8761            ,p_addto_fnd_stack   => G_ADD_ERRORS_TO_FND_STACK
8762           );
8763 
8764           l_token_table.DELETE();
8765 
8766           l_is_valid_row := FALSE;
8767 
8768           Debug_Msg(l_api_name ||' l_is_valid_row is now FALSE', 1);
8769 
8770         END IF;
8771 
8772         ---------------------------------------------------------------------------
8773         -- The user must pass a value of the correct data type for the Attribute --
8774         ---------------------------------------------------------------------------
8775             Debug_Msg(l_api_name ||' loop '||l_attr_value_index||', checking data type');
8776 
8777         IF (NOT Is_Data_Type_Correct(l_attr_metadata_obj
8778                                     ,px_attr_name_value_pairs(l_attr_value_index)
8779                                     ,p_attr_group_metadata_obj.ATTR_GROUP_DISP_NAME
8780                                     ,l_err_msg_name
8781                                     ,l_token_table)) THEN
8782 
8783           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);
8784 
8785           ERROR_HANDLER.Add_Error_Message(
8786             p_message_name      => l_err_msg_name
8787            ,p_application_id    => 'EGO'
8788            ,p_token_tbl         => l_token_table
8789            ,p_message_type      => FND_API.G_RET_STS_ERROR
8790            ,p_row_identifier    => G_USER_ROW_IDENTIFIER
8791            ,p_entity_id         => p_entity_id
8792            ,p_entity_index      => p_entity_index
8793            ,p_entity_code       => p_entity_code
8794            ,p_addto_fnd_stack   => G_ADD_ERRORS_TO_FND_STACK
8795           );
8796 
8797           l_token_table.DELETE();
8798 
8799           l_is_valid_row := FALSE;
8800 
8801           Debug_Msg(l_api_name ||'l_is_valid_row is now FALSE', 1);
8802 
8803         END IF;
8804 
8805         -------------------------------------------------------------------------
8806         -- Some Attributes have a maximum allowable size; we enforce that here --
8807         -------------------------------------------------------------------------
8808             Debug_Msg(l_api_name ||' loop '||l_attr_value_index||', checking max size');
8809 
8810         IF (NOT Is_Max_Size_Respected(l_attr_metadata_obj
8811                                      ,px_attr_name_value_pairs(l_attr_value_index)
8812                                      ,p_attr_group_metadata_obj.ATTR_GROUP_DISP_NAME
8813                                      ,l_err_msg_name
8814                                      ,l_token_table)) THEN
8815 
8816           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);
8817 
8818           ERROR_HANDLER.Add_Error_Message(
8819             p_message_name      => l_err_msg_name
8820            ,p_application_id    => 'EGO'
8821            ,p_token_tbl         => l_token_table
8822            ,p_message_type      => FND_API.G_RET_STS_ERROR
8823            ,p_row_identifier    => G_USER_ROW_IDENTIFIER
8824            ,p_entity_id         => p_entity_id
8825            ,p_entity_index      => p_entity_index
8826            ,p_entity_code       => p_entity_code
8827            ,p_addto_fnd_stack   => G_ADD_ERRORS_TO_FND_STACK
8828           );
8829 
8830           l_token_table.DELETE();
8831 
8832           l_is_valid_row := FALSE;
8833 
8834           Debug_Msg(l_api_name ||' l_is_valid_row is now FALSE', 1);
8835 
8836         END IF;
8837 
8838         -------------------------------------------------------------------
8839         -- If the Attribute has a Unit Of Measure, we need to process it --
8840         -------------------------------------------------------------------
8841             Debug_Msg(l_api_name ||' loop '||l_attr_value_index||', processing UOM');
8842 
8843         IF (NOT Is_UOM_Valid(l_attr_metadata_obj
8844                             ,px_attr_name_value_pairs(l_attr_value_index))) THEN
8845 
8846           l_token_table(1).TOKEN_NAME := 'ATTR_NAME';
8847           l_token_table(1).TOKEN_VALUE := l_attr_metadata_obj.ATTR_DISP_NAME;
8848 
8849           l_token_table(2).TOKEN_NAME := 'UOM_CLASS';
8850           l_token_table(2).TOKEN_VALUE := l_attr_metadata_obj.UNIT_OF_MEASURE_CLASS;
8851 
8852           l_err_msg_name := 'EGO_EF_UOM_NOT_IN_UOM_CLASS';
8853 
8854           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);
8855 
8856           ERROR_HANDLER.Add_Error_Message(
8857             p_message_name      => l_err_msg_name
8858            ,p_application_id    => 'EGO'
8859            ,p_token_tbl         => l_token_table
8860            ,p_message_type      => FND_API.G_RET_STS_ERROR
8861            ,p_row_identifier    => G_USER_ROW_IDENTIFIER
8862            ,p_entity_id         => p_entity_id
8863            ,p_entity_index      => p_entity_index
8864            ,p_entity_code       => p_entity_code
8865            ,p_addto_fnd_stack   => G_ADD_ERRORS_TO_FND_STACK
8866           );
8867 
8868           l_token_table.DELETE();
8869 
8870           l_is_valid_row := FALSE;
8871 
8872               Debug_Msg(l_api_name ||' l_is_valid_row is now FALSE', 1);
8873 
8874         END IF;
8875 
8876         --------------------------------------------------------------
8877         -- Finally, we check all user-defined Value Set constraints --
8878         -- (We log errors in this function itself rather than here) --
8879         --------------------------------------------------------------
8880         Debug_Msg(l_api_name ||' loop '||l_attr_value_index||', checking Value Set');
8881 
8882         IF (NOT Is_Value_Set_Respected(l_attr_metadata_obj
8883                                       ,p_attr_group_metadata_obj
8884                                       ,p_ext_table_metadata_obj
8885                                       ,p_pk_column_name_value_pairs
8886                                       ,p_data_level_name_value_pairs
8887                                       ,p_entity_id
8888                                       ,p_entity_index
8889                                       ,p_entity_code
8890                                       ,px_attr_name_value_pairs
8891                                       ,px_attr_name_value_pairs(l_attr_value_index))) THEN
8892 
8893           l_is_valid_row := FALSE;
8894 
8895           Debug_Msg(l_api_name ||' l_is_valid_row is now FALSE', 1);
8896 
8897         END IF;
8898 
8899         -------------------------------------------------------------------------
8900         -- Check if hierarchy security flags prevent the current changes from
8901         -- being made.
8902         -------------------------------------------------------------------------
8903 
8904         IF (FND_API.To_Boolean(p_validate_hierarchy) AND--Added for bugFix:5275391
8905             NOT (l_attr_metadata_obj.EDIT_IN_HIERARCHY_CODE = 'A' OR
8906                  l_attr_metadata_obj.EDIT_IN_HIERARCHY_CODE = 'AP')
8907            ) THEN
8908           -- Get is_root/is_leaf
8909           l_hierarchy_results :=
8910             Get_Hierarchy_For_AG_Type(p_attr_group_metadata_obj.ATTR_GROUP_TYPE
8911                                      ,p_pk_column_name_value_pairs);
8912 
8913           -- Compare results of hierarchy query to vih/eih modes
8914           IF (l_attr_metadata_obj.EDIT_IN_HIERARCHY_CODE = 'R' OR
8915               l_attr_metadata_obj.EDIT_IN_HIERARCHY_CODE = 'RP') THEN
8916 
8917             IF (l_hierarchy_results.IS_ROOT_NODE <> 'Y') THEN
8918 
8919               -- ERROR!  TODO: handle this correctly
8920               l_err_msg_name := 'HIERARCHY SECURITY VALIDATION';
8921               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);
8922 
8923               ERROR_HANDLER.Add_Error_Message(
8924                 p_message_name      => l_err_msg_name
8925                ,p_application_id    => 'EGO'
8926                ,p_token_tbl         => l_token_table
8927                ,p_message_type      => FND_API.G_RET_STS_ERROR
8928                ,p_row_identifier    => G_USER_ROW_IDENTIFIER
8929                ,p_entity_id         => p_entity_id
8930                ,p_entity_index      => p_entity_index
8931                ,p_entity_code       => p_entity_code
8932                ,p_addto_fnd_stack   => G_ADD_ERRORS_TO_FND_STACK
8933               );
8934 
8935               l_token_table.DELETE();
8936               l_is_valid_row := FALSE;
8937               Debug_Msg(l_api_name ||' l_is_valid_row is now FALSE', 1);
8938 
8939             END IF;
8940 
8941           ELSIF (l_attr_metadata_obj.EDIT_IN_HIERARCHY_CODE = 'L' OR
8942                  l_attr_metadata_obj.EDIT_IN_HIERARCHY_CODE = 'LP') THEN
8943 
8944             IF (l_hierarchy_results.IS_LEAF_NODE <> 'Y') THEN
8945 
8946               -- ERROR!  TODO: handle this correctly
8947               l_err_msg_name := 'HIERARCHY SECURITY VALIDATION';
8948               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);
8949 
8950               ERROR_HANDLER.Add_Error_Message(
8951                 p_message_name      => l_err_msg_name
8952                ,p_application_id    => 'EGO'
8953                ,p_token_tbl         => l_token_table
8954                ,p_message_type      => FND_API.G_RET_STS_ERROR
8955                ,p_row_identifier    => G_USER_ROW_IDENTIFIER
8956                ,p_entity_id         => p_entity_id
8957                ,p_entity_index      => p_entity_index
8958                ,p_entity_code       => p_entity_code
8959                ,p_addto_fnd_stack   => G_ADD_ERRORS_TO_FND_STACK
8960               );
8961 
8962               l_token_table.DELETE();
8963 
8964               l_is_valid_row := FALSE;
8965 
8966               Debug_Msg(l_api_name ||' l_is_valid_row is now FALSE', 1);
8967 
8968             END IF;
8969 
8970           END IF;
8971 
8972         END IF;
8973 
8974       END IF;
8975 
8976       l_attr_value_index := px_attr_name_value_pairs.NEXT(l_attr_value_index);
8977     END LOOP;
8978 
8979     -------------------------------------------------------------------------
8980     -- Finally, if the mode is 'CREATE', we want to check whether the user --
8981     -- failed to pass any required Attributes.  If we find a non-passed    --
8982     -- required Attribute, we check whether it has a default value: if so, --
8983     -- we build an Attribute data object for it and add it to our list of  --
8984     -- Attr values, but if not we raise an error for each missing required --
8985     -- Attribute (these errors are logged in the function itself).         --
8986     -------------------------------------------------------------------------
8987     IF (p_mode = G_CREATE_MODE AND
8988         NOT Verify_All_Required_Attrs(l_attr_name_table
8989                                      ,p_attr_group_metadata_obj.attr_metadata_table
8990                                      ,p_entity_id
8991                                      ,p_entity_index
8992                                      ,p_entity_code
8993                                      ,p_attr_group_metadata_obj.ATTR_GROUP_DISP_NAME
8994                                      ,px_attr_name_value_pairs)) THEN
8995 
8996       l_is_valid_row := FALSE;
8997 
8998       Debug_Msg(l_api_name ||' l_is_valid_row is now FALSE', 1);
8999 
9000     END IF;
9001 
9002     Debug_Msg(l_api_name ||' done', 1);
9003 
9004     IF (NOT l_is_valid_row) THEN
9005 
9006       RAISE FND_API.G_EXC_ERROR;
9007 
9008     END IF;
9009 
9010 -----------------------------------
9011 
9012     x_return_status := FND_API.G_RET_STS_SUCCESS;
9013 
9014   EXCEPTION
9015     WHEN FND_API.G_EXC_ERROR THEN
9016       Debug_Msg(l_api_name ||' EXCEPTION FND_API.G_EXC_ERROR  raised ', 1);
9017       x_return_status := FND_API.G_RET_STS_ERROR;
9018 
9019     WHEN OTHERS THEN
9020       Debug_Msg(l_api_name ||' EXCEPTION OTHERS  raised '||SQLERRM, 1);
9021       x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
9022 
9023       l_token_table.DELETE();
9024       l_token_table(1).TOKEN_NAME := 'PKG_NAME';
9025       l_token_table(1).TOKEN_VALUE := G_PKG_NAME;
9026       l_token_table(2).TOKEN_NAME := 'API_NAME';
9027       l_token_table(2).TOKEN_VALUE := l_api_name;
9028       l_token_table(3).TOKEN_NAME := 'SQL_ERR_MSG';
9029       l_token_table(3).TOKEN_VALUE := SQLERRM;
9030 
9031       ERROR_HANDLER.Add_Error_Message(
9032         p_message_name      => 'EGO_PLSQL_ERR'
9033        ,p_application_id    => 'EGO'
9034        ,p_token_tbl         => l_token_table
9035        ,p_message_type      => FND_API.G_RET_STS_ERROR
9036        ,p_row_identifier    => G_USER_ROW_IDENTIFIER
9037        ,p_entity_id         => p_entity_id
9038        ,p_entity_index      => p_entity_index
9039        ,p_entity_code       => p_entity_code
9040        ,p_addto_fnd_stack   => G_ADD_ERRORS_TO_FND_STACK
9041       );
9042 
9043 END Validate_Row_Pvt;
9044 
9045 ----------------------------------------------------------------------
9046 
9047 PROCEDURE Perform_DML_On_Row_Pvt (
9048         p_api_version                   IN   NUMBER
9049        ,p_object_id                     IN   NUMBER
9050        ,p_attr_group_metadata_obj       IN   EGO_ATTR_GROUP_METADATA_OBJ
9051        ,p_ext_table_metadata_obj        IN   EGO_EXT_TABLE_METADATA_OBJ
9052        ,p_pk_column_name_value_pairs    IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
9053        ,p_class_code_name_value_pairs   IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
9054        ,p_data_level                    IN   VARCHAR2   DEFAULT NULL --R12C
9055        ,p_data_level_name_value_pairs   IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
9056        ,p_extension_id                  IN   NUMBER
9057        ,p_attr_name_value_pairs         IN   EGO_USER_ATTR_DATA_TABLE
9058        ,p_language_to_process           IN   VARCHAR2   DEFAULT NULL
9059        ,p_mode                          IN   VARCHAR2
9060        ,p_change_obj                    IN   EGO_USER_ATTR_CHANGE_OBJ DEFAULT NULL
9061        ,p_extra_pk_col_name_val_pairs   IN   EGO_COL_NAME_VALUE_PAIR_ARRAY DEFAULT NULL
9062        ,p_extra_attr_name_value_pairs   IN   EGO_COL_NAME_VALUE_PAIR_ARRAY DEFAULT NULL
9063        ,p_pending_b_table_name          IN   VARCHAR2   DEFAULT NULL
9064        ,p_pending_tl_table_name         IN   VARCHAR2   DEFAULT NULL
9065        ,p_execute_dml                   IN   VARCHAR2   DEFAULT FND_API.G_TRUE
9066        ,p_entity_id                     IN   VARCHAR2   DEFAULT NULL
9067        ,p_entity_index                  IN   NUMBER     DEFAULT NULL
9068        ,p_entity_code                   IN   VARCHAR2   DEFAULT NULL
9069        ,p_commit                        IN   VARCHAR2
9070        ,p_bulkload_flag                 IN   BOOLEAN    DEFAULT FALSE
9071        ,p_raise_business_event          IN   BOOLEAN    DEFAULT TRUE
9072        ,x_extension_id                  OUT NOCOPY NUMBER
9073        ,x_return_status                 OUT NOCOPY VARCHAR2
9074 ) IS
9075 
9076     l_api_name               CONSTANT VARCHAR2(30) := 'Perform_DML_On_Row_Pvt';
9077 
9078     --we don't use l_api_version yet, but eventually we might:
9079     --if we change required parameters, version goes FROM n.x to (n+1).x
9080     --if we change optional parameters, version goes FROM x.n to x.(n+1)
9081     l_api_version            CONSTANT NUMBER := 1.0;
9082     l_attr_diffs             EGO_USER_ATTR_DIFF_TABLE := EGO_USER_ATTR_DIFF_TABLE();
9083 
9084   BEGIN
9085 
9086     Debug_Msg(l_api_name || ' starting with p_data_level '||p_data_level, 1);
9087 
9088     IF FND_API.To_Boolean(p_commit) THEN
9089       SAVEPOINT Perform_DML_On_Row_PVT;
9090     END IF;
9091 
9092     -- Check for call compatibility
9093     IF NOT FND_API.Compatible_API_Call (l_api_version, p_api_version,
9094                                         l_api_name, G_PKG_NAME)
9095     THEN
9096       RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
9097     END IF;
9098 
9099     IF (p_mode = G_CREATE_MODE) THEN
9100       Insert_Row(
9101         p_api_version                   => p_api_version
9102        ,p_attr_group_metadata_obj       => p_attr_group_metadata_obj
9103        ,p_ext_table_metadata_obj        => p_ext_table_metadata_obj
9104        ,p_pk_column_name_value_pairs    => p_pk_column_name_value_pairs
9105        ,p_class_code_name_value_pairs   => p_class_code_name_value_pairs
9106        ,p_data_level                    => p_data_level
9107        ,p_data_level_name_value_pairs   => p_data_level_name_value_pairs
9108        ,p_extension_id                  => p_extension_id
9109        ,p_attr_name_value_pairs         => p_attr_name_value_pairs
9110        ,p_language_to_process           => p_language_to_process
9111        ,p_change_obj                    => p_change_obj
9112        ,p_extra_pk_col_name_val_pairs   => p_extra_pk_col_name_val_pairs
9113        ,p_extra_attr_name_value_pairs   => p_extra_attr_name_value_pairs
9114        ,p_pending_b_table_name          => p_pending_b_table_name
9115        ,p_pending_tl_table_name         => p_pending_tl_table_name
9116        ,p_execute_dml                   => p_execute_dml
9117        ,p_entity_id                     => p_entity_id
9118        ,p_entity_index                  => p_entity_index
9119        ,p_entity_code                   => p_entity_code
9120        ,p_commit                        => FND_API.G_FALSE
9121        ,p_bulkload_flag                 => p_bulkload_flag
9122        ,px_attr_diffs                   => l_attr_diffs
9123        ,p_raise_business_event          => p_raise_business_event
9124        ,x_extension_id                  => x_extension_id
9125        ,x_return_status                 => x_return_status
9126       );
9127     ELSIF (p_mode = G_UPDATE_MODE) THEN
9128       Update_Row(
9129         p_api_version                   => p_api_version
9130        ,p_attr_group_metadata_obj       => p_attr_group_metadata_obj
9131        ,p_ext_table_metadata_obj        => p_ext_table_metadata_obj
9132        ,p_pk_column_name_value_pairs    => p_pk_column_name_value_pairs
9133        ,p_class_code_name_value_pairs   => p_class_code_name_value_pairs
9134        ,p_data_level                    => p_data_level
9135        ,p_data_level_name_value_pairs   => p_data_level_name_value_pairs
9136        ,p_extension_id                  => p_extension_id
9137        ,p_attr_name_value_pairs         => p_attr_name_value_pairs
9138        ,p_language_to_process           => p_language_to_process
9139        ,p_change_obj                    => p_change_obj
9140        ,p_extra_pk_col_name_val_pairs   => p_extra_pk_col_name_val_pairs
9141        ,p_extra_attr_name_value_pairs   => p_extra_attr_name_value_pairs
9142        ,p_pending_b_table_name          => p_pending_b_table_name
9143        ,p_pending_tl_table_name         => p_pending_tl_table_name
9144        ,p_execute_dml                   => p_execute_dml
9145        ,p_entity_id                     => p_entity_id
9146        ,p_entity_index                  => p_entity_index
9147        ,p_entity_code                   => p_entity_code
9148        ,p_commit                        => FND_API.G_FALSE
9149        ,p_bulkload_flag                 => p_bulkload_flag
9150        ,px_attr_diffs                   => l_attr_diffs
9151        ,p_raise_business_event          => p_raise_business_event
9152        ,x_return_status                 => x_return_status
9153       );
9154     ELSIF (p_mode = G_DELETE_MODE) THEN -- mode must be G_DELETE_MODE
9155       Delete_Row(
9156         p_api_version                   => p_api_version
9157        ,p_attr_group_metadata_obj       => p_attr_group_metadata_obj
9158        ,p_pk_column_name_value_pairs    => p_pk_column_name_value_pairs
9159        ,p_class_code_name_value_pairs   => p_class_code_name_value_pairs
9160        ,p_data_level                    => p_data_level
9161        ,p_data_level_name_value_pairs   => p_data_level_name_value_pairs
9162        ,p_extension_id                  => p_extension_id
9163        ,p_attr_name_value_pairs         => p_attr_name_value_pairs
9164        ,p_ext_table_metadata_obj        => p_ext_table_metadata_obj
9165        ,p_language_to_process           => p_language_to_process
9166        ,p_change_obj                    => p_change_obj
9167        ,p_pending_b_table_name          => p_pending_b_table_name
9168        ,p_pending_tl_table_name         => p_pending_tl_table_name
9169        ,p_execute_dml                   => p_execute_dml
9170        ,p_bulkload_flag                 => p_bulkload_flag
9171        ,px_attr_diffs                   => l_attr_diffs
9172        ,p_entity_id                     => p_entity_id
9173        ,p_entity_index                  => p_entity_index
9174        ,p_entity_code                   => p_entity_code
9175        ,p_commit                        => FND_API.G_FALSE
9176        ,p_raise_business_event          => p_raise_business_event
9177        ,x_return_status                 => x_return_status
9178       );
9179     ELSE
9180       RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
9181 
9182     END IF;
9183 
9184     IF (x_return_status <> FND_API.G_RET_STS_SUCCESS) THEN
9185       RAISE FND_API.G_EXC_ERROR;
9186     END IF;
9187 
9188     IF(x_extension_id IS NULL AND p_extension_id IS NOT NULL ) THEN
9189        x_extension_id := p_extension_id;
9190     END IF;
9191 
9192     IF FND_API.To_Boolean(p_commit) THEN
9193       COMMIT WORK;
9194     END IF;
9195 
9196     x_return_status := FND_API.G_RET_STS_SUCCESS;
9197     Debug_Msg( l_api_name || ' ending ', 1);
9198 
9199   EXCEPTION
9200     WHEN FND_API.G_EXC_ERROR THEN
9201       Debug_Msg( l_api_name || ' EXCEPTION FND_API.G_EXC_ERROR ', 1);
9202       IF FND_API.To_Boolean(p_commit) THEN
9203         ROLLBACK TO Perform_DML_On_Row_PVT;
9204       END IF;
9205       -----------------------------------------------------------
9206       -- If we get here, then the nested API call (whichever   --
9207       -- it was) must have failed; that call will have already --
9208       -- initialized the relevant out parameters.              --
9209       -----------------------------------------------------------
9210 
9211     WHEN OTHERS THEN
9212       Debug_Msg( l_api_name || ' EXCEPTION OTHERS '||SQLERRM, 1);
9213       IF FND_API.To_Boolean(p_commit) THEN
9214         ROLLBACK TO Perform_DML_On_Row_PVT;
9215       END IF;
9216       x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
9217 
9218       DECLARE
9219         l_token_table            ERROR_HANDLER.Token_Tbl_Type;
9220       BEGIN
9221         l_token_table(1).TOKEN_NAME := 'PKG_NAME';
9222         l_token_table(1).TOKEN_VALUE := G_PKG_NAME;
9223         l_token_table(2).TOKEN_NAME := 'API_NAME';
9224         l_token_table(2).TOKEN_VALUE := l_api_name;
9225         l_token_table(3).TOKEN_NAME := 'SQL_ERR_MSG';
9226         l_token_table(3).TOKEN_VALUE := SQLERRM;
9227 
9228         ERROR_HANDLER.Add_Error_Message(
9229           p_message_name      => 'EGO_PLSQL_ERR'
9230          ,p_application_id    => 'EGO'
9231          ,p_token_tbl         => l_token_table
9232          ,p_message_type      => FND_API.G_RET_STS_ERROR
9233          ,p_row_identifier    => G_USER_ROW_IDENTIFIER
9234          ,p_entity_id         => p_entity_id
9235          ,p_entity_index      => p_entity_index
9236          ,p_entity_code       => p_entity_code
9237          ,p_addto_fnd_stack   => G_ADD_ERRORS_TO_FND_STACK
9238         );
9239       END;
9240 
9241 END Perform_DML_On_Row_Pvt;
9242 
9243 ----------------------------------------------------------------------
9244 -- private procedure
9245 ----------------------------------------------------------------------
9246 PROCEDURE Perform_DML_On_Template_Row (
9247         p_object_id                     IN   NUMBER
9248        ,p_attr_group_metadata_obj       IN   EGO_ATTR_GROUP_METADATA_OBJ
9249        ,p_ext_table_metadata_obj        IN   EGO_EXT_TABLE_METADATA_OBJ
9250        ,p_pk_column_name_value_pairs    IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
9251        ,p_class_code_name_value_pairs   IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
9252        ,p_data_level                    IN   VARCHAR2
9253        ,p_data_level_name_value_pairs   IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
9254        ,p_commit                        IN   VARCHAR2
9255        ,px_attr_name_value_pairs        IN OUT NOCOPY EGO_USER_ATTR_DATA_TABLE
9256 ) IS
9257 
9258     l_api_name               VARCHAR2(50) := 'Perform_DML_On_Template_Row';
9259     l_extension_id           NUMBER;
9260     l_dummy_ext_id           NUMBER;
9261     l_mode                   VARCHAR2(10);
9262     l_return_status          VARCHAR2(1);
9263 
9264   BEGIN
9265     Debug_Msg(l_api_name || ' starting ',1);
9266     -------------------------------------------------------------------------------
9267     -- If an Attribute in this Attribute Group has a "Table" Value Set that uses --
9268     -- bind values, we will have to sort the name/value pairs table so that the  --
9269     -- upcoming calls to Get_Int_Val_For_Disp_Val all behave as they should      --
9270     -------------------------------------------------------------------------------
9271     IF (p_attr_group_metadata_obj.SORT_ATTR_VALUES_FLAG = 'Y') THEN
9272       Sort_Attr_Values_Table(p_attr_group_metadata_obj
9273                             ,px_attr_name_value_pairs);
9274     END IF;
9275 
9276     -----------------------------------------------------------------------
9277     -- We now make sure we are dealing with only the internal values for --
9278     -- all Attributes (this is important to do before looking for the    --
9279     -- extension ID because we may need Unique Key Attribute internal    --
9280     -- values to perform the extension ID search)                        --
9281     -----------------------------------------------------------------------
9282     Debug_Msg(l_api_name || ' calling Generate_Attr_Int_Values ',1);
9283     Generate_Attr_Int_Values(
9284       p_attr_group_metadata_obj       => p_attr_group_metadata_obj
9285      ,p_ext_table_metadata_obj        => p_ext_table_metadata_obj
9286      ,p_pk_column_name_value_pairs    => p_pk_column_name_value_pairs
9287      ,p_data_level_name_value_pairs   => p_data_level_name_value_pairs
9288      ,px_attr_name_value_pairs        => px_attr_name_value_pairs
9289      ,x_return_status                 => l_return_status
9290                             );
9291     IF (l_return_status <> FND_API.G_RET_STS_SUCCESS) THEN
9292       RAISE FND_API.G_EXC_ERROR;
9293     END IF;
9294 
9295     --------------------------------------------------
9296     -- Find out whether we're inserting or updating --
9297     -- (and check for Unique Key violations)        --
9298     --------------------------------------------------
9299     Debug_Msg(l_api_name || ' calling Get_Extension_Id_And_Mode ',1);
9300     Get_Extension_Id_And_Mode(
9301       p_attr_group_metadata_obj       => p_attr_group_metadata_obj
9302      ,p_ext_table_metadata_obj        => p_ext_table_metadata_obj
9303      ,p_pk_column_name_value_pairs    => p_pk_column_name_value_pairs
9304      ,p_data_level                    => p_data_level
9305      ,p_data_level_name_value_pairs   => p_data_level_name_value_pairs
9306      ,p_attr_name_value_pairs         => px_attr_name_value_pairs
9307      ,x_extension_id                  => l_extension_id
9308      ,x_mode                          => l_mode
9309      ,x_return_status                 => l_return_status
9310                              );
9311     IF (l_return_status <> FND_API.G_RET_STS_SUCCESS) THEN
9312       RAISE FND_API.G_EXC_ERROR;
9313     END IF;
9314 
9315     ----------------------------------------------------------------------
9316     -- Validate the current collection of Attribute values prior to DML --
9317     ----------------------------------------------------------------------
9318     Debug_Msg(l_api_name || ' calling Validate_Row_Pvt ',1);
9319     Validate_Row_Pvt(
9320       p_api_version                   => 1.0
9321      ,p_object_id                     => p_object_id
9322      ,p_attr_group_metadata_obj       => p_attr_group_metadata_obj
9323      ,p_ext_table_metadata_obj        => p_ext_table_metadata_obj
9324      ,p_pk_column_name_value_pairs    => p_pk_column_name_value_pairs
9325      ,p_class_code_name_value_pairs   => p_class_code_name_value_pairs
9326      ,p_data_level                    => p_data_level
9327      ,p_data_level_name_value_pairs   => p_data_level_name_value_pairs
9328      ,p_extension_id                  => l_extension_id
9329      ,p_mode                          => l_mode
9330      ,px_attr_name_value_pairs        => px_attr_name_value_pairs
9331      ,x_return_status                 => l_return_status
9332                     );
9333     IF (l_return_status <> FND_API.G_RET_STS_SUCCESS) THEN
9334       RAISE FND_API.G_EXC_ERROR;
9335     END IF;
9336 
9337     -----------------------------------------------------
9338     -- If the row is valid, either insert or update it --
9339     -----------------------------------------------------
9340     Debug_Msg(l_api_name || ' calling Perform_DML_On_Row_Pvt ',1);
9341     Perform_DML_On_Row_Pvt(
9342       p_api_version                   => 1.0
9343      ,p_object_id                     => p_object_id
9344      ,p_attr_group_metadata_obj       => p_attr_group_metadata_obj
9345      ,p_ext_table_metadata_obj        => p_ext_table_metadata_obj
9346      ,p_pk_column_name_value_pairs    => p_pk_column_name_value_pairs
9347      ,p_class_code_name_value_pairs   => p_class_code_name_value_pairs
9348      ,p_data_level                    => p_data_level
9349      ,p_data_level_name_value_pairs   => p_data_level_name_value_pairs
9350      ,p_extension_id                  => l_extension_id
9351      ,p_attr_name_value_pairs         => px_attr_name_value_pairs
9352      ,p_mode                          => l_mode
9353      ,p_commit                        => p_commit
9354      ,x_extension_id                  => l_dummy_ext_id
9355      ,x_return_status                 => l_return_status
9356                           );
9357     IF (l_return_status <> FND_API.G_RET_STS_SUCCESS) THEN
9358       RAISE FND_API.G_EXC_ERROR;
9359     END IF;
9360     Debug_Msg(l_api_name || ' ending ',1);
9361 
9362 END Perform_DML_On_Template_Row;
9363 
9364 ----------------------------------------------------------------------
9365 
9366 PROCEDURE Perform_Setup_Operations (
9367         p_object_name                   IN  VARCHAR2
9368        ,p_attr_group_id                 IN  NUMBER
9369        ,p_application_id                IN  NUMBER
9370        ,p_attr_group_type               IN  VARCHAR2
9371        ,p_attr_group_name               IN  VARCHAR2
9372        ,p_pk_column_name_value_pairs    IN  EGO_COL_NAME_VALUE_PAIR_ARRAY
9373        ,p_class_code_name_value_pairs   IN  EGO_COL_NAME_VALUE_PAIR_ARRAY
9374        ,p_data_level                    IN   VARCHAR2   DEFAULT NULL --R12C
9375        ,p_data_level_name_value_pairs   IN  EGO_COL_NAME_VALUE_PAIR_ARRAY
9376        ,p_extension_id                  IN  NUMBER
9377        ,p_entity_id                     IN  VARCHAR2
9378        ,p_entity_index                  IN  NUMBER
9379        ,p_entity_code                   IN  VARCHAR2
9380        ,p_debug_level                   IN  NUMBER     DEFAULT 0
9381        ,p_add_errors_to_fnd_stack       IN  VARCHAR2
9382        ,p_use_def_vals_on_insert_flag   IN  BOOLEAN    DEFAULT FALSE
9383        ,p_init_fnd_msg_list             IN  VARCHAR2
9384        ,p_mode                          IN  VARCHAR2
9385        ,p_change_obj                    IN  EGO_USER_ATTR_CHANGE_OBJ DEFAULT NULL
9386        ,p_extra_pk_col_name_val_pairs   IN  EGO_COL_NAME_VALUE_PAIR_ARRAY DEFAULT NULL
9387        ,p_pending_b_table_name          IN  VARCHAR2   DEFAULT NULL
9388        ,p_pending_vl_name               IN  VARCHAR2   DEFAULT NULL
9389        ,p_bulkload_flag                 IN  BOOLEAN    DEFAULT FALSE
9390        ,px_object_id                    IN OUT NOCOPY NUMBER
9391        ,px_attr_name_value_pairs        IN OUT NOCOPY EGO_USER_ATTR_DATA_TABLE
9392        ,x_attr_group_metadata_obj       OUT NOCOPY EGO_ATTR_GROUP_METADATA_OBJ
9393        ,x_ext_table_metadata_obj        OUT NOCOPY EGO_EXT_TABLE_METADATA_OBJ
9394        ,x_extension_id                  OUT NOCOPY NUMBER
9395        ,x_mode                          OUT NOCOPY VARCHAR2
9396        ,x_return_status                 OUT NOCOPY VARCHAR2
9397 ) IS
9398 
9399     l_api_name               CONSTANT VARCHAR2(30) := 'Perform_Setup_Operations';
9400     l_token_table            ERROR_HANDLER.Token_Tbl_Type;
9401     l_err_msg_name           VARCHAR2(30);
9402 
9403   BEGIN
9404 
9405     Debug_Msg(l_api_name || ' starting', 2);
9406 
9407     ------------------------------------------------------------------------
9408     -- We need to record which row number we are processing so we can log --
9409     -- error messages appropriately.  We need to use a global variable to --
9410     -- handle the case where p_attr_name_value_pairs is NULL or empty     --
9411     ------------------------------------------------------------------------
9412     IF (px_attr_name_value_pairs IS NULL OR px_attr_name_value_pairs.COUNT = 0) THEN
9413       G_USER_ROW_IDENTIFIER := 1;
9414     ELSE
9415       G_USER_ROW_IDENTIFIER := px_attr_name_value_pairs(px_attr_name_value_pairs.FIRST).USER_ROW_IDENTIFIER;
9416     END IF;
9417 
9418     ---------------------------------------------------------------------------
9419     -- If G_BULK_PROCESSING_FLAG has not been set to true, then we're coming --
9420     -- from the UI and we haven't yet set up our Business Object session     --
9421     ---------------------------------------------------------------------------
9422     IF (NOT G_BULK_PROCESSING_FLAG) THEN
9423 
9424       Debug_Msg(l_api_name || ' before Set_Up_Business_Object_Session ', 2);
9425       Set_Up_Business_Object_Session(
9426           p_bulkload_flag                 => p_bulkload_flag
9427          ,p_entity_id                     => p_entity_id
9428          ,p_entity_index                  => p_entity_index
9429          ,p_entity_code                   => p_entity_code
9430          ,p_debug_level                   => p_debug_level
9431          ,p_init_error_handler_flag       => (p_debug_level > 0)
9432          ,p_object_name                   => p_object_name
9433          ,p_pk_column_name_value_pairs    => p_pk_column_name_value_pairs
9434          ,p_class_code_name_value_pairs   => p_class_code_name_value_pairs
9435          ,p_init_fnd_msg_list             => p_init_fnd_msg_list
9436          ,p_add_errors_to_fnd_stack       => p_add_errors_to_fnd_stack
9437          ,p_use_def_vals_on_insert_flag   => p_use_def_vals_on_insert_flag
9438          ,x_return_status                 => x_return_status
9439       );
9440       Debug_Msg(l_api_name || ' done Set_Up_Business_Object_Session: '||x_return_status, 2);
9441       ----------------------------------------------------------------------
9442       -- If an error was found, we've already added it to the error stack --
9443       ----------------------------------------------------------------------
9444       IF (x_return_status <> FND_API.G_RET_STS_SUCCESS) THEN
9445 
9446         RAISE FND_API.G_EXC_ERROR;
9447 
9448       END IF;
9449     END IF;
9450 
9451     IF (px_object_id IS NULL) THEN
9452       px_object_id := Get_Object_Id_From_Name(p_object_name);
9453     END IF;
9454 
9455     x_attr_group_metadata_obj :=
9456       EGO_USER_ATTRS_COMMON_PVT.Get_Attr_Group_Metadata(p_attr_group_id
9457                                                        ,p_application_id
9458                                                        ,p_attr_group_type
9459                                                        ,p_attr_group_name);
9460     Debug_Msg(l_api_name || ' before validations:  p_attr_group_id-'||p_attr_group_id||
9461                             ' p_application_id-'||p_application_id ||
9462                             ' p_attr_group_type-'||p_attr_group_type||
9463                             ' p_attr_group_name-'||p_attr_group_name);
9464 
9465     ------------------------------------------------------
9466     -- We check for the possibility that we didn't find --
9467     -- the metadata to correctly process this row       --
9468     ------------------------------------------------------
9469     IF (x_attr_group_metadata_obj IS NULL) THEN
9470 
9471       IF (p_application_id IS NOT NULL AND
9472           p_attr_group_type IS NOT NULL AND
9473           p_attr_group_name IS NOT NULL) THEN
9474 
9475         l_err_msg_name := 'EGO_EF_ATTR_GROUP_PK_NOT_FOUND';
9476 
9477         l_token_table(1).TOKEN_NAME := 'APP_ID';
9478         l_token_table(1).TOKEN_VALUE := p_application_id;
9479         l_token_table(2).TOKEN_NAME := 'AG_TYPE';
9480         l_token_table(2).TOKEN_VALUE := p_attr_group_type;
9481         l_token_table(3).TOKEN_NAME := 'AG_NAME';
9482         l_token_table(3).TOKEN_VALUE := p_attr_group_name;
9483 
9484       ELSE
9485 
9486         l_err_msg_name := 'EGO_EF_ATTR_GROUP_ID_NOT_FOUND';
9487 
9488         l_token_table(1).TOKEN_NAME := 'AG_ID';
9489         l_token_table(1).TOKEN_VALUE := p_attr_group_id;
9490 
9491       END IF;
9492 
9493       ERROR_HANDLER.Add_Error_Message(
9494         p_message_name      => l_err_msg_name
9495        ,p_application_id    => 'EGO'
9496        ,p_token_tbl         => l_token_table
9497        ,p_message_type      => FND_API.G_RET_STS_ERROR
9498        ,p_row_identifier    => G_USER_ROW_IDENTIFIER
9499        ,p_entity_id         => p_entity_id
9500        ,p_entity_index      => p_entity_index
9501        ,p_entity_code       => p_entity_code
9502        ,p_addto_fnd_stack   => G_ADD_ERRORS_TO_FND_STACK
9503       );
9504      Debug_Msg(l_api_name || 'before raising exception 0 ');
9505       RAISE FND_API.G_EXC_ERROR;
9506 
9507     ELSIF (NOT Do_All_Attrs_Exist(x_attr_group_metadata_obj
9508                                  ,px_attr_name_value_pairs
9509                                  ,p_entity_id
9510                                  ,p_entity_index
9511                                  ,p_entity_code)) THEN
9512 
9513       ----------------------------------------------------------------
9514       -- We've logged an error for every Attr that we couldn't find --
9515       ----------------------------------------------------------------
9516      Debug_Msg(l_api_name || 'before raising exception 1 ');
9517       RAISE FND_API.G_EXC_ERROR;
9518 
9519     END IF;
9520 
9521     x_ext_table_metadata_obj := EGO_USER_ATTRS_COMMON_PVT.Get_Ext_Table_Metadata(px_object_id);
9522     IF (x_ext_table_metadata_obj IS NULL) THEN
9523 
9524       l_token_table.DELETE();
9525       l_token_table(1).TOKEN_NAME := 'OBJECT_NAME';
9526       l_token_table(1).TOKEN_VALUE := p_object_name;
9527 
9528       ERROR_HANDLER.Add_Error_Message(
9529         p_message_name      => 'EGO_EF_EXT_TABLE_METADATA_ERR'
9530        ,p_application_id    => 'EGO'
9531        ,p_token_tbl         => l_token_table
9532        ,p_message_type      => FND_API.G_RET_STS_ERROR
9533        ,p_row_identifier    => G_USER_ROW_IDENTIFIER
9534        ,p_entity_id         => p_entity_id
9535        ,p_entity_index      => p_entity_index
9536        ,p_entity_code       => p_entity_code
9537        ,p_addto_fnd_stack   => G_ADD_ERRORS_TO_FND_STACK
9538       );
9539      Debug_Msg(l_api_name || 'before raising exception 2 ');
9540 
9541       RAISE FND_API.G_EXC_ERROR;
9542 
9543     END IF;
9544 
9545     -------------------------------------------------------------------------------
9546     -- If an Attribute in this Attribute Group has a "Table" Value Set that uses --
9547     -- bind values, we will have to sort the name/value pairs table so that the  --
9548     -- upcoming calls to Get_Int_Val_For_Disp_Val all behave as they should      --
9549     -------------------------------------------------------------------------------
9550     IF (x_attr_group_metadata_obj.SORT_ATTR_VALUES_FLAG = 'Y') THEN
9551 
9552       Sort_Attr_Values_Table(x_attr_group_metadata_obj
9553                             ,px_attr_name_value_pairs);
9554 
9555     END IF;
9556 Debug_Msg(l_api_name || 'before Generate_Attr_Int_Values ');
9557     --------------------------------------------------------------------------------------
9558     -- We now make sure we are dealing with only the internal values for all Attributes --
9559     -- (this is important to do before looking for the extension ID because we may need --
9560     -- Unique Key Attribute internal values to perform the extension ID search)         --
9561     --------------------------------------------------------------------------------------
9562     Generate_Attr_Int_Values(
9563         p_attr_group_metadata_obj      => x_attr_group_metadata_obj
9564        ,p_ext_table_metadata_obj       => x_ext_table_metadata_obj
9565        ,p_pk_column_name_value_pairs   => p_pk_column_name_value_pairs
9566        ,p_data_level_name_value_pairs  => p_data_level_name_value_pairs
9567        ,p_entity_id                    => p_entity_id
9568        ,p_entity_index                 => p_entity_index
9569        ,p_entity_code                  => p_entity_code
9570        ,px_attr_name_value_pairs       => px_attr_name_value_pairs
9571        ,x_return_status                => x_return_status);
9572 
9573 Debug_Msg(l_api_name || 'done Generate_Attr_Int_Values: '||x_return_status);
9574     ------------------------------------------------------------
9575     -- If errors were found in processing the display values, --
9576     -- we've already added them to the error stack            --
9577     ------------------------------------------------------------
9578     IF (x_return_status <> FND_API.G_RET_STS_SUCCESS) THEN
9579       RAISE FND_API.G_EXC_ERROR;
9580     END IF;
9581 
9582     --------------------------------------------------------------------
9583     -- Now we determine whether we're creating, updating or deleting, --
9584     -- what the Extension ID is in the latter two cases, and whether  --
9585     -- our data violates any Unique Key constraints                   --
9586     --------------------------------------------------------------------
9587     Get_Extension_Id_And_Mode(
9588       p_attr_group_metadata_obj       => x_attr_group_metadata_obj
9589      ,p_ext_table_metadata_obj        => x_ext_table_metadata_obj
9590      ,p_pk_column_name_value_pairs    => p_pk_column_name_value_pairs
9591      ,p_data_level                    => p_data_level
9592      ,p_data_level_name_value_pairs   => p_data_level_name_value_pairs
9593      ,p_attr_name_value_pairs         => px_attr_name_value_pairs
9594      ,p_extension_id                  => p_extension_id
9595      ,p_mode                          => p_mode
9596      ,p_change_obj                    => p_change_obj
9597      ,p_extra_pk_col_name_val_pairs   => p_extra_pk_col_name_val_pairs
9598      ,p_pending_b_table_name          => p_pending_b_table_name
9599      ,p_pending_vl_name               => p_pending_vl_name
9600      ,p_entity_id                     => p_entity_id
9601      ,p_entity_index                  => p_entity_index
9602      ,p_entity_code                   => p_entity_code
9603      ,x_extension_id                  => x_extension_id
9604      ,x_mode                          => x_mode
9605      ,x_return_status                 => x_return_status
9606     );
9607     -----------------------------------------------------
9608     -- If errors were found in the previous procedure, --
9609     -- we've already added them to the error stack     --
9610     -----------------------------------------------------
9611     IF (x_return_status <> FND_API.G_RET_STS_SUCCESS) THEN
9612       RAISE FND_API.G_EXC_ERROR;
9613     END IF;
9614 
9615     Debug_Msg(l_api_name || ' after checking, x_mode is '||x_mode);
9616     IF (UPPER(x_mode) = G_UPDATE_MODE OR UPPER(x_mode) = G_DELETE_MODE) THEN
9617       Debug_Msg(l_api_name || ' after checking, x_extension_id is '||x_extension_id);
9618     END IF;
9619 
9620     Debug_Msg(l_api_name || ' done', 2);
9621 
9622   EXCEPTION
9623     WHEN FND_API.G_EXC_ERROR THEN
9624       Debug_Msg(l_api_name || ' EXCEPTION FND_API.G_EXC_ERROR', 1);
9625       x_return_status := FND_API.G_RET_STS_ERROR;
9626 
9627     WHEN OTHERS THEN
9628       Debug_Msg(l_api_name || ' EXCEPTION OTHERS '||SQLERRM, 1);
9629       x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
9630       l_token_table.DELETE();
9631       l_token_table(1).TOKEN_NAME := 'PKG_NAME';
9632       l_token_table(1).TOKEN_VALUE := G_PKG_NAME;
9633       l_token_table(2).TOKEN_NAME := 'API_NAME';
9634       l_token_table(2).TOKEN_VALUE := l_api_name;
9635       l_token_table(3).TOKEN_NAME := 'SQL_ERR_MSG';
9636       l_token_table(3).TOKEN_VALUE := SQLERRM;
9637 
9638       ERROR_HANDLER.Add_Error_Message(
9639         p_message_name      => 'EGO_PLSQL_ERR'
9640        ,p_application_id    => 'EGO'
9641        ,p_token_tbl         => l_token_table
9642        ,p_message_type      => FND_API.G_RET_STS_ERROR
9643        ,p_row_identifier    => G_USER_ROW_IDENTIFIER
9644        ,p_entity_id         => p_entity_id
9645        ,p_entity_index      => p_entity_index
9646        ,p_entity_code       => p_entity_code
9647        ,p_addto_fnd_stack   => G_ADD_ERRORS_TO_FND_STACK
9648       );
9649 
9650 END Perform_Setup_Operations;
9651 
9652 ----------------------------------------------------------------------
9653 
9654 
9655 
9656                       -----------------------
9657                       -- Public Procedures --
9658                       -----------------------
9659 
9660 ----------------------------------------------------------------------
9661 
9662 PROCEDURE Process_User_Attrs_Data (
9663         p_api_version                   IN   NUMBER
9664        ,p_object_name                   IN   VARCHAR2
9665        ,p_attributes_row_table          IN   EGO_USER_ATTR_ROW_TABLE
9666        ,p_attributes_data_table         IN   EGO_USER_ATTR_DATA_TABLE
9667        ,p_pk_column_name_value_pairs    IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
9668        ,p_class_code_name_value_pairs   IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
9669        ,p_user_privileges_on_object     IN   EGO_VARCHAR_TBL_TYPE DEFAULT NULL
9670        ,p_change_info_table             IN   EGO_USER_ATTR_CHANGE_TABLE DEFAULT NULL
9671        ,p_pending_b_table_name          IN   VARCHAR2   DEFAULT  NULL
9672        ,p_pending_tl_table_name         IN   VARCHAR2   DEFAULT  NULL
9673        ,p_pending_vl_name               IN   VARCHAR2   DEFAULT  NULL
9674        ,p_entity_id                     IN   NUMBER     DEFAULT  NULL
9675        ,p_entity_index                  IN   NUMBER     DEFAULT  NULL
9676        ,p_entity_code                   IN   VARCHAR2   DEFAULT  NULL
9677        ,p_debug_level                   IN   NUMBER     DEFAULT  0
9678        ,p_validate_only                 IN   VARCHAR2   DEFAULT  FND_API.G_FALSE
9679        ,p_validate_hierarchy            IN   VARCHAR2   DEFAULT  FND_API.G_TRUE
9680        ,p_init_error_handler            IN   VARCHAR2   DEFAULT  FND_API.G_FALSE
9681        ,p_write_to_concurrent_log       IN   VARCHAR2   DEFAULT  FND_API.G_FALSE
9682        ,p_init_fnd_msg_list             IN   VARCHAR2   DEFAULT  FND_API.G_FALSE
9683        ,p_log_errors                    IN   VARCHAR2   DEFAULT  FND_API.G_FALSE
9684        ,p_add_errors_to_fnd_stack       IN   VARCHAR2   DEFAULT  FND_API.G_FALSE
9685        ,p_commit                        IN   VARCHAR2   DEFAULT  FND_API.G_FALSE
9686        ,p_raise_business_event          IN   BOOLEAN    DEFAULT  TRUE
9687        ,x_failed_row_id_list            OUT NOCOPY VARCHAR2
9688        ,x_return_status                 OUT NOCOPY VARCHAR2
9689        ,x_errorcode                     OUT NOCOPY NUMBER
9690        ,x_msg_count                     OUT NOCOPY NUMBER
9691        ,x_msg_data                      OUT NOCOPY VARCHAR2
9692 ) IS
9693     l_extension_id           NUMBER;
9694     l_mode                   VARCHAR2(10);
9695 
9696 BEGIN
9697 
9698     Process_User_Attrs_Data
9699     (
9700         p_api_version                   => p_api_version
9701        ,p_object_name                   => p_object_name
9702        ,p_attributes_row_table          => p_attributes_row_table
9703        ,p_attributes_data_table         => p_attributes_data_table
9704        ,p_pk_column_name_value_pairs    => p_pk_column_name_value_pairs
9705        ,p_class_code_name_value_pairs   => p_class_code_name_value_pairs
9706        ,p_user_privileges_on_object     => p_user_privileges_on_object
9707        ,p_entity_id                     => p_entity_id
9708        ,p_entity_index                  => p_entity_index
9709        ,p_entity_code                   => p_entity_code
9710        ,p_debug_level                   => p_debug_level
9711        ,p_validate_only                 => p_validate_only  --bug 5122295
9712        ,p_validate_hierarchy            => p_validate_hierarchy
9713        ,p_init_error_handler            => p_init_error_handler
9714        ,p_write_to_concurrent_log       => p_write_to_concurrent_log
9715        ,p_init_fnd_msg_list             => p_init_fnd_msg_list
9716        ,p_log_errors                    => p_log_errors
9717        ,p_add_errors_to_fnd_stack       => p_add_errors_to_fnd_stack
9718        ,p_commit                        => p_commit
9719        ,p_raise_business_event          => p_raise_business_event
9720        ,x_extension_id                  => l_extension_id
9721        ,x_mode                          => l_mode
9722        ,x_failed_row_id_list            => x_failed_row_id_list
9723        ,x_return_status                 => x_return_status
9724        ,x_errorcode                     => x_errorcode
9725        ,x_msg_count                     => x_msg_count
9726        ,x_msg_data                      => x_msg_data
9727     );
9728 
9729 END;
9730 -------------------------------------------------------------------------------
9731 
9732 PROCEDURE Process_User_Attrs_Data (
9733         p_api_version                   IN   NUMBER
9734        ,p_object_name                   IN   VARCHAR2
9735        ,p_attributes_row_table          IN   EGO_USER_ATTR_ROW_TABLE
9736        ,p_attributes_data_table         IN   EGO_USER_ATTR_DATA_TABLE
9737        ,p_pk_column_name_value_pairs    IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
9738        ,p_class_code_name_value_pairs   IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
9739        ,p_user_privileges_on_object     IN   EGO_VARCHAR_TBL_TYPE DEFAULT NULL
9740        ,p_change_info_table             IN   EGO_USER_ATTR_CHANGE_TABLE DEFAULT NULL
9741        ,p_pending_b_table_name          IN   VARCHAR2   DEFAULT  NULL
9742        ,p_pending_tl_table_name         IN   VARCHAR2   DEFAULT  NULL
9743        ,p_pending_vl_name               IN   VARCHAR2   DEFAULT  NULL
9744        ,p_entity_id                     IN   NUMBER     DEFAULT  NULL
9745        ,p_entity_index                  IN   NUMBER     DEFAULT  NULL
9746        ,p_entity_code                   IN   VARCHAR2   DEFAULT  NULL
9747        ,p_debug_level                   IN   NUMBER     DEFAULT  0
9748        ,p_validate_only                 IN   VARCHAR2   DEFAULT  FND_API.G_FALSE
9749        ,p_validate_hierarchy            IN   VARCHAR2   DEFAULT  FND_API.G_TRUE
9750        ,p_init_error_handler            IN   VARCHAR2   DEFAULT  FND_API.G_FALSE
9751        ,p_write_to_concurrent_log       IN   VARCHAR2   DEFAULT  FND_API.G_FALSE
9752        ,p_init_fnd_msg_list             IN   VARCHAR2   DEFAULT  FND_API.G_FALSE
9753        ,p_log_errors                    IN   VARCHAR2   DEFAULT  FND_API.G_FALSE
9754        ,p_add_errors_to_fnd_stack       IN   VARCHAR2   DEFAULT  FND_API.G_FALSE
9755        ,p_commit                        IN   VARCHAR2   DEFAULT  FND_API.G_FALSE
9756        ,p_raise_business_event          IN   BOOLEAN    DEFAULT  TRUE
9757        ,x_extension_id                  OUT NOCOPY NUMBER
9758        ,x_mode                          OUT NOCOPY VARCHAR2
9759        ,x_failed_row_id_list            OUT NOCOPY VARCHAR2
9760        ,x_return_status                 OUT NOCOPY VARCHAR2
9761        ,x_errorcode                     OUT NOCOPY NUMBER
9762        ,x_msg_count                     OUT NOCOPY NUMBER
9763        ,x_msg_data                      OUT NOCOPY VARCHAR2
9764 ) IS
9765 
9766     l_api_name               CONSTANT VARCHAR2(30) := 'Process_User_Attrs_Data';
9767 
9768     --we don't use l_api_version yet, but eventually we might:
9769     --if we change required parameters, version goes FROM n.x to (n+1).x
9770     --if we change optional parameters, version goes FROM x.n to x.(n+1)
9771     l_api_version            CONSTANT NUMBER := 1.0;
9772 
9773     l_default_user_row_id    NUMBER;
9774     l_sorted_attr_data_table LOCAL_USER_ATTR_DATA_TABLE;
9775     l_sorted_attr_row_table  LOCAL_USER_ATTR_ROW_TABLE;
9776     l_sorted_row_table_index NUMBER;
9777     l_current_row_element    EGO_USER_ATTR_ROW_OBJ;
9778     l_mode                   VARCHAR2(10);
9779     l_sorted_data_table_index NUMBER;
9780     l_got_all_attrs_for_this_row BOOLEAN := FALSE;
9781     l_current_data_element   EGO_USER_ATTR_DATA_OBJ;
9782     l_next_row_id            NUMBER;
9783     l_row_attrs_table        EGO_USER_ATTR_DATA_TABLE;
9784     l_data_level_name_value_pairs EGO_COL_NAME_VALUE_PAIR_ARRAY;
9785     l_current_row_change_obj EGO_USER_ATTR_CHANGE_OBJ;
9786     l_return_status          VARCHAR2(1);
9787     l_errorcode              NUMBER;
9788     l_msg_count              NUMBER;
9789     l_msg_data               VARCHAR2(1000);
9790     l_data_level_id          NUMBER;
9791     l_attr_group_metadata_obj EGO_ATTR_GROUP_METADATA_OBJ;
9792 
9793 l_dummy_row       EGO_USER_ATTR_ROW_OBJ;
9794   BEGIN
9795 
9796     Debug_Msg(l_api_name || ' starting', 1);
9797 
9798     -- Check for call compatibility
9799     IF NOT FND_API.Compatible_API_Call (l_api_version, p_api_version,
9800                                         l_api_name, G_PKG_NAME)
9801     THEN
9802       RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
9803     END IF;
9804 
9805     --------------------------------------------------------------------------------
9806     -- Start by dealing with caching, error-handling, and preliminary validations --
9807     --------------------------------------------------------------------------------
9808     IF (p_attributes_data_table IS NOT NULL AND
9809         p_attributes_data_table.COUNT > 0) THEN
9810       l_default_user_row_id := p_attributes_data_table(p_attributes_data_table.FIRST).USER_ROW_IDENTIFIER;
9811     ELSE
9812       l_default_user_row_id := 0;
9813     END IF;
9814 
9815     Set_Up_Business_Object_Session(
9816         p_bulkload_flag                 => TRUE
9817        ,p_user_privileges_on_object     => p_user_privileges_on_object
9818        ,p_entity_id                     => p_entity_id
9819        ,p_entity_index                  => p_entity_index
9820        ,p_entity_code                   => p_entity_code
9821        ,p_debug_level                   => p_debug_level
9822        ,p_init_error_handler_flag       => FND_API.To_Boolean(p_init_error_handler)
9823        ,p_object_name                   => p_object_name
9824        ,p_pk_column_name_value_pairs    => p_pk_column_name_value_pairs
9825        ,p_class_code_name_value_pairs   => p_class_code_name_value_pairs
9826        ,p_init_fnd_msg_list             => p_init_fnd_msg_list
9827        ,p_add_errors_to_fnd_stack       => p_add_errors_to_fnd_stack
9828        ,p_default_user_row_identifier   => l_default_user_row_id
9829        ,x_return_status                 => x_return_status
9830     );
9831 
9832     ----------------------------------------------------------------------
9833     -- If an error was found, we've already added it to the error stack --
9834     ----------------------------------------------------------------------
9835     IF (x_return_status <> FND_API.G_RET_STS_SUCCESS) THEN
9836 
9837       --------------------------------------------------
9838       -- Mark every row in this instance as a failure --
9839       --------------------------------------------------
9840       FOR r IN p_attributes_row_table.FIRST .. p_attributes_row_table.LAST
9841       LOOP
9842 
9843         x_failed_row_id_list := x_failed_row_id_list ||
9844                                 p_attributes_row_table(r).ROW_IDENTIFIER || ',';
9845 
9846       END LOOP;
9847 
9848       ------------------------------------------------------------------
9849       -- Trim the trailing ',' from x_failed_row_id_list if necessary --
9850       ------------------------------------------------------------------
9851       x_failed_row_id_list := RTRIM(x_failed_row_id_list, ',');
9852 
9853       RAISE FND_API.G_EXC_ERROR;
9854     END IF;
9855 
9856     ---------------------------------------------------------------
9857     -- If we pass the preliminary tests, we can process the data --
9858     ---------------------------------------------------------------
9859     l_sorted_attr_data_table := Build_Sorted_Data_Table(p_attributes_data_table);
9860     l_sorted_attr_row_table := Build_Sorted_Row_Table(p_attributes_row_table);
9861 
9862     l_sorted_row_table_index := l_sorted_attr_row_table.FIRST;
9863     WHILE (l_sorted_row_table_index <= l_sorted_attr_row_table.LAST)
9864     LOOP
9865 Debug_Msg('1 in the loop ');
9866 
9867       ----------------------------------------------
9868       -- Initialize local variables for each loop --
9869       ----------------------------------------------
9870       l_got_all_attrs_for_this_row := FALSE;
9871       l_return_status := NULL;
9872       l_errorcode := NULL;
9873       l_msg_count := 0;
9874       l_msg_data := NULL;
9875       l_current_row_element := l_sorted_attr_row_table(l_sorted_row_table_index);
9876       l_mode := UPPER(l_current_row_element.TRANSACTION_TYPE);
9877 
9878       -----------------------------------------------------------
9879       -- Either make a new table or clear out the existing one --
9880       -----------------------------------------------------------
9881       IF (l_row_attrs_table IS NULL) THEN
9882         l_row_attrs_table := EGO_USER_ATTR_DATA_TABLE();
9883       ELSE
9884         l_row_attrs_table.DELETE();
9885       END IF;
9886 
9887       --------------------------------------------------------------------------
9888       -- If it's our first time through, initialize l_sorted_data_table_index --
9889       -- (for subsequent loops we want it to retain its current value so we   --
9890       -- can continue to step through the data table bit by bit in each loop) --
9891       --------------------------------------------------------------------------
9892       IF (l_sorted_data_table_index IS NULL) THEN
9893         l_sorted_data_table_index := l_sorted_attr_data_table.FIRST;
9894       END IF;
9895 
9896       --------------------------------------------------------------------------
9897       -- Step through the table collecting all Attr Data objects for this row --
9898       --------------------------------------------------------------------------
9899       WHILE (l_sorted_data_table_index <= l_sorted_attr_data_table.LAST)
9900       LOOP
9901         EXIT WHEN (l_got_all_attrs_for_this_row);
9902 
9903         l_current_data_element := l_sorted_attr_data_table(l_sorted_data_table_index);
9904         IF (l_current_data_element.ROW_IDENTIFIER = l_current_row_element.ROW_IDENTIFIER) THEN
9905 
9906           ---------------------------------------------------
9907           -- Add the current Attr Data object to the table --
9908           ---------------------------------------------------
9909           l_row_attrs_table.EXTEND();
9910           l_row_attrs_table(l_row_attrs_table.LAST()) := l_current_data_element;
9911 
9912           ---------------------------------------
9913           -- Update the index for another loop --
9914           ---------------------------------------
9915           l_sorted_data_table_index := l_sorted_attr_data_table.NEXT(l_sorted_data_table_index);
9916 
9917         ELSE
9918 
9919           ------------------------------------------------------------
9920           -- In this case we don't want to update the index because --
9921           -- the current index already belongs to the next row      --
9922           ------------------------------------------------------------
9923           l_got_all_attrs_for_this_row := TRUE;
9924 
9925         END IF;
9926       END LOOP;
9927 
9928       ---------------------------------------------------------------
9929       -- Try to get the change info for this row (if there is any) --
9930       ---------------------------------------------------------------
9931       IF (p_change_info_table IS NOT NULL AND
9932           p_change_info_table.EXISTS(l_current_row_element.ROW_IDENTIFIER)) THEN
9933         l_current_row_change_obj := p_change_info_table(l_current_row_element.ROW_IDENTIFIER);
9934       ELSE
9935         l_current_row_change_obj := NULL;
9936       END IF;
9937 Debug_Msg('10 AGID-'||l_current_row_element.ATTR_GROUP_ID);
9938       ---------------------------------------------------------
9939       -- At this point we have all the Attr Data objects for --
9940       -- this row, and we'll be ready to call Process_Row as --
9941       -- soon as we create a Data Level array for the row    --
9942       ---------------------------------------------------------
9943 
9944       l_data_level_id := Get_Data_Level_Id( l_current_row_element.ATTR_GROUP_APP_ID
9945                                            ,l_current_row_element.ATTR_GROUP_TYPE
9946                                            ,l_current_row_element.DATA_LEVEL);
9947 Debug_Msg('11 ');
9948 
9949       l_data_level_name_value_pairs :=
9950              Build_Data_Level_Array(p_object_name    => p_object_name
9951                                    ,p_data_level_id  => l_data_level_id
9952                                    ,p_data_level_1   => l_current_row_element.DATA_LEVEL_1
9953                                    ,p_data_level_2   => l_current_row_element.DATA_LEVEL_2
9954                                    ,p_data_level_3   => l_current_row_element.DATA_LEVEL_3
9955                                    ,p_data_level_4   => l_current_row_element.DATA_LEVEL_4
9956                                    ,p_data_level_5   => l_current_row_element.DATA_LEVEL_5
9957                                     );
9958 Debug_Msg('12 ');
9959 
9960 
9961     Debug_Msg(l_api_name || ' calling Process_Row ', 1);
9962 Debug_Msg(l_api_name ||  ' l_current_row_element.ATTR_GROUP_ID '||l_current_row_element.ATTR_GROUP_ID);
9963 Debug_Msg(l_api_name ||  ' l_current_row_element.DATA_LEVEL '||l_current_row_element.DATA_LEVEL );
9964 IF l_data_level_name_value_pairs IS NOT NULL THEN
9965   FOR i IN l_data_level_name_value_pairs.FIRST .. l_data_level_name_value_pairs.LAST
9966   LOOP
9967      Debug_Msg(l_api_name || ' NAME: '|| l_data_level_name_value_pairs(i).NAME || ' VALUE: '||l_data_level_name_value_pairs(i).VALUE) ;
9968   END LOOP;
9969 END IF;
9970 IF l_row_attrs_table IS NOT NULL AND l_row_attrs_table.COUNT > 0 THEN
9971   FOR i in l_row_attrs_table.FIRST .. l_row_attrs_table.LAST
9972   LOOP
9973     Debug_Msg(l_api_name || ' DATA_LEVEL: '|| i);
9974 --    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);
9975   END LOOP;
9976 END IF;
9977 
9978       Process_Row(
9979         p_api_version                   => 1.0
9980        ,p_object_name                   => p_object_name
9981        ,p_attr_group_id                 => l_current_row_element.ATTR_GROUP_ID
9982        ,p_application_id                => l_current_row_element.ATTR_GROUP_APP_ID
9983        ,p_attr_group_type               => l_current_row_element.ATTR_GROUP_TYPE
9984        ,p_attr_group_name               => l_current_row_element.ATTR_GROUP_NAME
9985        ,p_pk_column_name_value_pairs    => p_pk_column_name_value_pairs
9986        ,p_class_code_name_value_pairs   => p_class_code_name_value_pairs
9987        ,p_data_level                    => l_current_row_element.DATA_LEVEL
9988        ,p_data_level_name_value_pairs   => l_data_level_name_value_pairs
9989        ,p_attr_name_value_pairs         => l_row_attrs_table
9990        ,p_validate_only                 => p_validate_only
9991        ,p_validate_hierarchy            => p_validate_hierarchy
9992        ,p_mode                          => l_mode
9993        ,p_change_obj                    => l_current_row_change_obj
9994        ,p_pending_b_table_name          => p_pending_b_table_name
9995        ,p_pending_tl_table_name         => p_pending_tl_table_name
9996        ,p_pending_vl_name               => p_pending_vl_name
9997        ,p_entity_id                     => p_entity_id
9998        ,p_entity_index                  => p_entity_index
9999        ,p_entity_code                   => p_entity_code
10000        ,p_raise_business_event          => p_raise_business_event
10001        ,x_extension_id                  => x_extension_id
10002        ,x_mode                          => x_mode
10003        ,x_return_status                 => l_return_status
10004        ,x_errorcode                     => l_errorcode
10005        ,x_msg_count                     => l_msg_count
10006        ,x_msg_data                      => l_msg_data
10007       );
10008 
10009       Debug_Msg(l_api_name || ' after processing row '||
10010                 l_current_row_element.ROW_IDENTIFIER||' in mode '||l_mode||
10011                 ', l_msg_data is '||l_msg_data||', l_return_status is '||
10012                 l_return_status||' and l_msg_count is '||l_msg_count, 1);
10013 
10014       -------------------------------------------------------
10015       -- Check whether this row was successfully processed --
10016       -------------------------------------------------------
10017       IF (l_return_status <> FND_API.G_RET_STS_SUCCESS) THEN
10018 
10019         ----------------------------------------------------------------------------
10020         -- Since this row failed, put its ROW_IDENTIFIER into the failed row list --
10021         ----------------------------------------------------------------------------
10022         x_failed_row_id_list := x_failed_row_id_list ||
10023                                 l_current_row_element.ROW_IDENTIFIER || ',';
10024 
10025         ------------------------------------------------
10026         -- We keep x_return_status updated to reflect --
10027         -- the most serious error we come across      --
10028         ------------------------------------------------
10029         IF (x_return_status IS NULL OR
10030             x_return_status = FND_API.G_RET_STS_SUCCESS OR
10031             (x_return_status = FND_API.G_RET_STS_ERROR AND
10032              l_return_status = FND_API.G_RET_STS_UNEXP_ERROR)) THEN
10033 
10034           x_return_status := l_return_status;
10035 
10036         END IF;
10037       END IF;
10038 
10039       l_sorted_row_table_index := l_sorted_attr_row_table.NEXT(l_sorted_row_table_index);
10040     END LOOP;
10041 
10042     ------------------------------------------------------------------
10043     -- Trim the trailing ',' from x_failed_row_id_list if necessary --
10044     ------------------------------------------------------------------
10045     x_failed_row_id_list := RTRIM(x_failed_row_id_list, ',');
10046 
10047     x_msg_count := ERROR_HANDLER.Get_Message_Count();
10048 
10049     IF (x_msg_count > 0) THEN
10050 
10051       RAISE FND_API.G_EXC_ERROR;
10052 
10053     END IF;
10054 
10055     Debug_Msg('In Process_User_Attrs_Data, done', 1);
10056 
10057     Close_Business_Object_Session(
10058       p_init_error_handler_flag     => FND_API.To_Boolean(p_init_error_handler)
10059      ,p_log_errors                  => FND_API.To_Boolean(p_log_errors)
10060      ,p_write_to_concurrent_log     => FND_API.To_Boolean(p_write_to_concurrent_log)
10061     );
10062 
10063     IF FND_API.To_Boolean(p_commit) THEN
10064       COMMIT WORK;
10065     END IF;
10066 
10067     IF (x_return_status IS NULL) THEN
10068       x_return_status := FND_API.G_RET_STS_SUCCESS;
10069     END IF;
10070 
10071   EXCEPTION
10072 
10073     ----------------------------------------------------------------------------
10074     -- We do not ROLLBACK in this procedure: standard behavior for Business   --
10075     -- Objects is for each row being processed to succeed or fail independent --
10076     -- of the status of other rows, so we let Process_Row ROLLBACK any errors --
10077     -- it encounters.  If callers want different behavior, they can establish --
10078     -- a SAVEPOINT prior to calling this procedure and ROLLBACK if we report  --
10079     -- any errors.                                                            --
10080     ----------------------------------------------------------------------------
10081     WHEN FND_API.G_EXC_ERROR THEN
10082       Debug_Msg(l_api_name || ' EXCEPTION FND_API.G_EXC_ERROR ', 1);
10083 
10084       -----------------------------------------------------------------------------
10085       -- Since we want to commit all successful rows, we will always call commit --
10086       -----------------------------------------------------------------------------
10087       IF FND_API.To_Boolean(p_commit) THEN
10088         COMMIT WORK;
10089       END IF;
10090 
10091       Close_Business_Object_Session(
10092         p_init_error_handler_flag     => FND_API.To_Boolean(p_init_error_handler)
10093        ,p_log_errors                  => FND_API.To_Boolean(p_log_errors)
10094        ,p_write_to_concurrent_log     => FND_API.To_Boolean(p_write_to_concurrent_log)
10095       );
10096 
10097       x_msg_count := ERROR_HANDLER.Get_Message_Count();
10098 
10099       IF (x_msg_count = 1) THEN
10100         DECLARE
10101           message_list  ERROR_HANDLER.Error_Tbl_Type;
10102         BEGIN
10103           ERROR_HANDLER.Get_Message_List(message_list);
10104           x_msg_data := message_list(message_list.FIRST).message_text;
10105         END;
10106       ELSE
10107         x_msg_data := NULL;
10108       END IF;
10109 
10110     WHEN OTHERS THEN
10111 
10112       Debug_Msg(l_api_name || ' EXCEPTION OTHERS '||SQLERRM, 1);
10113       -----------------------------------------------------------------------------
10114       -- Since we want to commit all successful rows, we will always call commit --
10115       -----------------------------------------------------------------------------
10116       IF FND_API.To_Boolean(p_commit) THEN
10117         COMMIT WORK;
10118       END IF;
10119 
10120       x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
10121 
10122       DECLARE
10123         l_token_table            ERROR_HANDLER.Token_Tbl_Type;
10124       BEGIN
10125         l_token_table(1).TOKEN_NAME := 'PKG_NAME';
10126         l_token_table(1).TOKEN_VALUE := G_PKG_NAME;
10127         l_token_table(2).TOKEN_NAME := 'API_NAME';
10128         l_token_table(2).TOKEN_VALUE := l_api_name;
10129         l_token_table(3).TOKEN_NAME := 'SQL_ERR_MSG';
10130         l_token_table(3).TOKEN_VALUE := SQLERRM;
10131 
10132         ERROR_HANDLER.Add_Error_Message(
10133           p_message_name      => 'EGO_PLSQL_ERR'
10134          ,p_application_id    => 'EGO'
10135          ,p_token_tbl         => l_token_table
10136          ,p_message_type      => FND_API.G_RET_STS_ERROR
10137          ,p_row_identifier    => G_USER_ROW_IDENTIFIER
10138          ,p_entity_id         => p_entity_id
10139          ,p_entity_index      => p_entity_index
10140          ,p_entity_code       => p_entity_code
10141          ,p_addto_fnd_stack   => G_ADD_ERRORS_TO_FND_STACK
10142         );
10143       END;
10144 
10145       Close_Business_Object_Session(
10146         p_init_error_handler_flag     => FND_API.To_Boolean(p_init_error_handler)
10147        ,p_log_errors                  => FND_API.To_Boolean(p_log_errors)
10148        ,p_write_to_concurrent_log     => FND_API.To_Boolean(p_write_to_concurrent_log)
10149       );
10150 
10151       x_msg_count := ERROR_HANDLER.Get_Message_Count();
10152 
10153       IF (x_msg_count = 1) THEN
10154         DECLARE
10155           message_list  ERROR_HANDLER.Error_Tbl_Type;
10156         BEGIN
10157           ERROR_HANDLER.Get_Message_List(message_list);
10158           x_msg_data := message_list(message_list.FIRST).message_text;
10159         END;
10160       ELSE
10161         x_msg_data := NULL;
10162       END IF;
10163 
10164 END Process_User_Attrs_Data;
10165 
10166 ----------------------------------------------------------------------
10167 
10168 PROCEDURE Get_User_Attrs_Data (
10169         p_api_version                   IN   NUMBER
10170        ,p_object_name                   IN   VARCHAR2
10171        ,p_pk_column_name_value_pairs    IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
10172        ,p_attr_group_request_table      IN   EGO_ATTR_GROUP_REQUEST_TABLE
10173        ,p_user_privileges_on_object     IN   EGO_VARCHAR_TBL_TYPE DEFAULT NULL
10174        ,p_entity_id                     IN   NUMBER     DEFAULT NULL
10175        ,p_entity_index                  IN   NUMBER     DEFAULT NULL
10176        ,p_entity_code                   IN   VARCHAR2   DEFAULT NULL
10177        ,p_debug_level                   IN   NUMBER     DEFAULT 0
10178        ,p_init_error_handler            IN   VARCHAR2   DEFAULT FND_API.G_FALSE
10179        ,p_init_fnd_msg_list             IN   VARCHAR2   DEFAULT FND_API.G_FALSE
10180        ,p_add_errors_to_fnd_stack       IN   VARCHAR2   DEFAULT FND_API.G_FALSE
10181        ,p_commit                        IN   VARCHAR2   DEFAULT FND_API.G_FALSE
10182        ,x_attributes_row_table          OUT NOCOPY EGO_USER_ATTR_ROW_TABLE
10183        ,x_attributes_data_table         OUT NOCOPY EGO_USER_ATTR_DATA_TABLE
10184        ,x_return_status                 OUT NOCOPY VARCHAR2
10185        ,x_errorcode                     OUT NOCOPY NUMBER
10186        ,x_msg_count                     OUT NOCOPY NUMBER
10187        ,x_msg_data                      OUT NOCOPY VARCHAR2
10188 ) IS
10189 
10190     l_api_name               CONSTANT VARCHAR2(30) := 'Get_User_Attrs_Data';
10191 
10192     --we don't use l_api_version yet, but eventually we might:
10193     --if we change required parameters, version goes FROM n.x to (n+1).x
10194     --if we change optional parameters, version goes FROM x.n to x.(n+1)
10195     l_api_version            CONSTANT NUMBER := 1.0;
10196 
10197     l_object_id                   NUMBER;
10198     l_ext_table_metadata_obj      EGO_EXT_TABLE_METADATA_OBJ;
10199     l_request_table_index         NUMBER;
10200     l_curr_ag_request_obj         EGO_ATTR_GROUP_REQUEST_OBJ;
10201     l_curr_ag_metadata_obj        EGO_ATTR_GROUP_METADATA_OBJ;
10202     l_can_view_this_attr_group    BOOLEAN;
10203     l_augmented_data_table        LOCAL_AUGMENTED_DATA_TABLE;
10204     l_requested_attr_names_table  LOCAL_VARCHAR_TABLE;
10205     l_attr_list_index             NUMBER;
10206     l_curr_attr_metadata_obj      EGO_ATTR_METADATA_OBJ;
10207     l_curr_augmented_attr_rec     LOCAL_USER_ATTR_DATA_REC;
10208     l_curr_aug_table_index        NUMBER;
10209     l_table_of_low_ind_for_AG_ID  LOCAL_NUMBER_TABLE;
10210     l_table_of_high_ind_for_AG_ID LOCAL_NUMBER_TABLE;
10211     l_ag_predicate_list           VARCHAR2(20000);
10212     l_curr_db_column_name         VARCHAR2(30);
10213     l_to_char_db_col_expression   VARCHAR2(90);
10214     l_db_column_list              VARCHAR2(32767);
10215     l_db_column_tables_index      NUMBER;
10216     l_db_column_name_table        LOCAL_VARCHAR_TABLE;
10217     l_db_column_query_table       LOCAL_BIG_VARCHAR_TABLE;
10218     l_start_index                 NUMBER;
10219     l_substring_length            NUMBER;
10220     l_temp_db_query_string        VARCHAR2(32767);
10221     l_int_to_disp_val_string      VARCHAR2(32767);
10222     l_data_level_name_value_pairs EGO_COL_NAME_VALUE_PAIR_ARRAY;
10223     l_pk_col_string               VARCHAR2(1000);
10224     l_data_level_string           VARCHAR2(1000);
10225     l_dynamic_sql                 VARCHAR2(32767);
10226     l_cursor_id                   NUMBER;
10227     l_dummy                       NUMBER;
10228     l_varchar_example             VARCHAR2(1000);
10229     l_number_example              NUMBER;
10230     l_date_example                DATE;
10231     l_curr_AG_ID                  NUMBER;
10232     l_low_aug_tab_ind_for_AG_ID   NUMBER;
10233     l_high_aug_tab_ind_for_AG_ID  NUMBER;
10234     l_need_to_build_a_row_obj     BOOLEAN := TRUE;
10235     l_extension_id                NUMBER;
10236     --ENHR12:added for passing the internal value of an
10237     --attribute along with the display value.
10238     l_dbcol_cntr                  NUMBER:=0;
10239     l_char_value                  VARCHAR2(100);
10240     --bug 5494760
10241     l_has_attrs                   VARCHAR2(1) :='N';
10242     l_curr_ag_vl_name             VARCHAR2(30);
10243     l_curr_ag_table_name          VARCHAR2(30);
10244 
10245 l_token_table               ERROR_HANDLER.Token_Tbl_Type;
10246 l_curr_data_level_metadata  EGO_DATA_LEVEL_METADATA_OBJ;
10247 l_curr_data_level_row_obj   EGO_DATA_LEVEL_ROW_OBJ;
10248 l_has_data_level_col            BOOLEAN  := FALSE;    -- TRUE is for R12C
10249 l_dl_view_privilege  fnd_form_functions.function_name%TYPE;
10250 
10251 
10252   BEGIN
10253 
10254     Debug_Msg(l_api_name||'  starting', 1);
10255     -- Check for call compatibility
10256     IF NOT FND_API.Compatible_API_Call (l_api_version, p_api_version,
10257                                         l_api_name, G_PKG_NAME)
10258     THEN
10259       RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
10260     END IF;
10261 
10262 Debug_Msg(l_api_name||'  call compatible', 3);
10263 
10264 
10265 Debug_Msg(l_api_name||' Set_Up_Business_Object_Session(', 3);
10266 Debug_Msg(l_api_name||'   p_bulkload_flag                 => TRUE', 3);
10267 Debug_Msg(l_api_name||'   p_user_privileges_on_object     => <unprintable>', 3);
10268 Debug_Msg(l_api_name||'   p_entity_id                     => ' || p_entity_id, 3);
10269 Debug_Msg(l_api_name||'   p_entity_index                  => ' || p_entity_index, 3);
10270 Debug_Msg(l_api_name||'   p_entity_code                   => ' || p_entity_code, 3);
10271 Debug_Msg(l_api_name||'   p_debug_level                   => ' || p_debug_level, 3);
10272 Debug_Msg(l_api_name||'   p_init_error_handler_flag       => ' || p_init_error_handler, 3);
10273 Debug_Msg(l_api_name||'   p_object_name                   => ' || p_object_name, 3);
10274 Debug_Msg(l_api_name||'   p_pk_column_name_value_pairs    => <unprintable>', 3);
10275 Debug_Msg(l_api_name||'   p_class_code_name_value_pairs   => NULL', 3);
10276 Debug_Msg(l_api_name||'   p_init_fnd_msg_list             => ' || p_init_fnd_msg_list, 3);
10277 Debug_Msg(l_api_name||'   p_add_errors_to_fnd_stack       => ' || p_add_errors_to_fnd_stack, 3);
10278 Debug_Msg(l_api_name||'   x_return_status                 => ' || x_return_status, 3);
10279 Debug_Msg(l_api_name||' );', 3);
10280     --------------------------------------------------------------------------------
10281     -- Start by dealing with caching, error-handling, and preliminary validations --
10282     --------------------------------------------------------------------------------
10283 
10284     Set_Up_Business_Object_Session(
10285         p_bulkload_flag                 => TRUE
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_init_error_handler_flag       => FND_API.To_Boolean(p_init_error_handler)
10292        ,p_object_name                   => p_object_name
10293        ,p_pk_column_name_value_pairs    => p_pk_column_name_value_pairs
10294        ,p_class_code_name_value_pairs   => NULL -- SSARNOBA - I'm not sure if this should be null
10295        ,p_init_fnd_msg_list             => p_init_fnd_msg_list
10296        ,p_add_errors_to_fnd_stack       => p_add_errors_to_fnd_stack
10297        ,x_return_status                 => x_return_status
10298     );
10299 Debug_Msg(l_api_name || ' after Set_Up_Business_Object_Session ', 3);
10300 
10301     ----------------------------------------------------------------------
10302     -- If an error was found, we've already added it to the error stack --
10303     ----------------------------------------------------------------------
10304     IF (x_return_status <> FND_API.G_RET_STS_SUCCESS) THEN
10305       RAISE FND_API.G_EXC_ERROR;
10306     END IF;
10307 
10308     -------------------------------------------------
10309     -- We could have a batch metadata retrieval procedure for the *_User_Attrs_Data calls;
10310     -- it would batch fetch all the metadata for the relevent AGs and then store them in
10311     -- the cache (well, at least fifty of them; if more than fifty, it would still work well)
10312     -------------------------------------------------
10313 
10314 Debug_Msg(l_api_name || ' p_attr_group_request_table.count = '||p_attr_group_request_table.count);
10315     IF (p_attr_group_request_table IS NOT NULL AND
10316         p_attr_group_request_table.COUNT > 0) THEN
10317 
10318       -------------------------------------------------------------
10319       -- First, get metadata for later use in building the query --
10320       -- (we know both of these calls will succeed because they  --
10321       -- were tested in Perform_Preliminary_Checks, above)       --
10322       -------------------------------------------------------------
10323       l_object_id := Get_Object_Id_From_Name(p_object_name);
10324       l_ext_table_metadata_obj := EGO_USER_ATTRS_COMMON_PVT.Get_Ext_Table_Metadata(l_object_id);
10325 
10326       --=======================================================================--
10327       -- Because there might be hundreds of Attribute Groups for which we need --
10328       -- to get data, we can't assume that we could store metadata for each of --
10329       -- them; so we do all processing that requires metadata at one time for  --
10330       -- each Attribute Group to avoid possibly having to refetch metadata for --
10331       -- any Attribute Group.                                                  --
10332       --=======================================================================--
10333       l_request_table_index := p_attr_group_request_table.FIRST;
10334       <<GUAD_ag_requests_loop>>
10335       WHILE (l_request_table_index <= p_attr_group_request_table.LAST)
10336       LOOP
10337         l_curr_ag_request_obj := p_attr_group_request_table(l_request_table_index);
10338 
10339 Debug_Msg(l_api_name || ' ');
10340 Debug_Msg(l_api_name || ' Attribute Group Request (       -- ' || l_request_table_index || '.');
10341 Debug_Msg(l_api_name || '   ATTR_GROUP_ID   =  ' || l_curr_ag_request_obj.ATTR_GROUP_ID);
10342 Debug_Msg(l_api_name || '   APPLICATION_ID  =  ' || l_curr_ag_request_obj.APPLICATION_ID);
10343 Debug_Msg(l_api_name || '   ATTR_GROUP_TYPE =  ' || l_curr_ag_request_obj.ATTR_GROUP_TYPE);
10344 Debug_Msg(l_api_name || '   ATTR_GROUP_NAME =  ' || l_curr_ag_request_obj.ATTR_GROUP_NAME);
10345 Debug_Msg(l_api_name || '   DATA_LEVEL      =  ' || l_curr_ag_request_obj.DATA_LEVEL);
10346 Debug_Msg(l_api_name || '   DATA_LEVEL_1    =  ' || l_curr_ag_request_obj.DATA_LEVEL_1);
10347 Debug_Msg(l_api_name || '   DATA_LEVEL_2    =  ' || l_curr_ag_request_obj.DATA_LEVEL_2);
10348 Debug_Msg(l_api_name || '   DATA_LEVEL_3    =  ' || l_curr_ag_request_obj.DATA_LEVEL_3);
10349 Debug_Msg(l_api_name || '   DATA_LEVEL_4    =  ' || l_curr_ag_request_obj.DATA_LEVEL_4);
10350 Debug_Msg(l_api_name || '   DATA_LEVEL_5    =  ' || l_curr_ag_request_obj.DATA_LEVEL_5);
10351 Debug_Msg(l_api_name || '   ATTR_NAME_LIST  =  ' || l_curr_ag_request_obj.ATTR_NAME_LIST);
10352 Debug_Msg(l_api_name || ' )  ');
10353 
10354         -- Get the metadata for this attribute group
10355         l_curr_ag_metadata_obj :=
10356           EGO_USER_ATTRS_COMMON_PVT.Get_Attr_Group_Metadata(l_curr_ag_request_obj.ATTR_GROUP_ID
10357                                                            ,l_curr_ag_request_obj.APPLICATION_ID
10358                                                            ,l_curr_ag_request_obj.ATTR_GROUP_TYPE
10359                                                            ,l_curr_ag_request_obj.ATTR_GROUP_NAME);
10360 
10361         -- Determine if the EXT table has a data level column
10362         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'));
10363 
10364 
10365         ----------------------------------------------------------------------
10366         -- Scan the list of enabled data levels, and see if the data level  --
10367         -- of the current attribute group is in this list                   --
10368         ----------------------------------------------------------------------
10369 
10370         l_curr_data_level_row_obj := NULL;
10371 
10372         IF l_has_data_level_col THEN
10373 
10374           IF (l_curr_ag_metadata_obj.ENABLED_DATA_LEVELS IS NOT NULL AND
10375               l_curr_ag_metadata_obj.ENABLED_DATA_LEVELS.COUNT <> 0) THEN
10376 
10377 Debug_Msg(l_api_name || ' passed data level name '|| l_curr_ag_request_obj.data_level);
10378 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);
10379 
10380             -- Loop 1.1
10381             FOR dl_index IN l_curr_ag_metadata_obj.ENABLED_DATA_LEVELS.FIRST ..
10382                             l_curr_ag_metadata_obj.ENABLED_DATA_LEVELS.LAST
10383             LOOP
10384 
10385 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 || ')');
10386 
10387               IF l_curr_ag_metadata_obj.ENABLED_DATA_LEVELS(dl_index).data_level_name = l_curr_ag_request_obj.data_level THEN
10388 
10389 Debug_Msg(l_api_name||' Creating data level row obj ');
10390 
10391                 l_curr_data_level_row_obj := l_curr_ag_metadata_obj.ENABLED_DATA_LEVELS(dl_index);
10392 
10393                 IF l_curr_data_level_row_obj IS NOT NULL THEN
10394 Debug_Msg(l_api_name || 'Data level metadata found');
10395                   l_curr_data_level_metadata := EGO_USER_ATTRS_COMMON_PVT.Get_Data_Level_Metadata(l_curr_data_level_row_obj.data_level_id);
10396                   EXIT; -- exit the loop as we found the DL metadata
10397                 END IF;
10398               END IF;
10399             END LOOP;
10400 
10401 Debug_Msg(l_api_name || ' ');
10402 Debug_Msg(l_api_name || ', Data Level Metadata (');
10403 Debug_Msg(l_api_name || ',   DATA_LEVEL_ID        = ' || l_curr_data_level_metadata.DATA_LEVEL_ID);
10404 Debug_Msg(l_api_name || ',   DATA_LEVEL_NAME      = ' || l_curr_data_level_metadata.DATA_LEVEL_NAME);
10405 Debug_Msg(l_api_name || ',   USER_DATA_LEVEL_NAME = ' || l_curr_data_level_metadata.USER_DATA_LEVEL_NAME);
10406 Debug_Msg(l_api_name || ',   PK1_COLUMN_NAME      = ' || l_curr_data_level_metadata.PK_COLUMN_NAME1);
10407 Debug_Msg(l_api_name || ',   PK2_COLUMN_NAME      = ' || l_curr_data_level_metadata.PK_COLUMN_NAME2);
10408 Debug_Msg(l_api_name || ',   PK3_COLUMN_NAME      = ' || l_curr_data_level_metadata.PK_COLUMN_NAME3);
10409 Debug_Msg(l_api_name || ',   PK4_COLUMN_NAME      = ' || l_curr_data_level_metadata.PK_COLUMN_NAME4);
10410 Debug_Msg(l_api_name || ',   PK5_COLUMN_NAME      = ' || l_curr_data_level_metadata.PK_COLUMN_NAME5);
10411 Debug_Msg(l_api_name || ',   PK1_COLUMN_TYPE      = ' || l_curr_data_level_metadata.PK_COLUMN_TYPE1);
10412 Debug_Msg(l_api_name || ',   PK2_COLUMN_TYPE      = ' || l_curr_data_level_metadata.PK_COLUMN_TYPE2);
10413 Debug_Msg(l_api_name || ',   PK3_COLUMN_TYPE      = ' || l_curr_data_level_metadata.PK_COLUMN_TYPE3);
10414 Debug_Msg(l_api_name || ',   PK4_COLUMN_TYPE      = ' || l_curr_data_level_metadata.PK_COLUMN_TYPE4);
10415 Debug_Msg(l_api_name || ',   PK5_COLUMN_TYPE      = ' || l_curr_data_level_metadata.PK_COLUMN_TYPE5);
10416 Debug_Msg(l_api_name || ',   DL_PROD_TABLE_NAME   = ' || l_curr_data_level_metadata.DL_PROD_TABLE_NAME);
10417 Debug_Msg(l_api_name || ', )');
10418 Debug_Msg(l_api_name || ' ');
10419           IF l_curr_data_level_row_obj IS NULL THEN
10420             -- the data level is not correct, flash error message.
10421 
10422 Debug_Msg(l_api_name || ' Data level not in list of enabled data levels');
10423 
10424             l_token_table(1).TOKEN_NAME := 'DL_NAME';
10425             l_token_table(1).TOKEN_VALUE := '';
10426             l_token_table(2).TOKEN_NAME := 'AG_NAME';
10427             l_token_table(2).TOKEN_VALUE := l_curr_ag_metadata_obj.attr_group_disp_name;
10428 
10429             -- The data level XXX is not associated with the attribute
10430             -- group XXX
10431             ERROR_HANDLER.Add_Error_Message(
10432               p_message_name      => 'EGO_EF_DL_AG_INVALID'
10433              ,p_application_id    => 'EGO'
10434              ,p_token_tbl         => l_token_table
10435              ,p_message_type      => FND_API.G_RET_STS_ERROR
10436              ,p_row_identifier    => G_USER_ROW_IDENTIFIER
10437              ,p_entity_id         => p_entity_id
10438              ,p_entity_index      => p_entity_index
10439              ,p_entity_code       => p_entity_code
10440              ,p_addto_fnd_stack   => G_ADD_ERRORS_TO_FND_STACK
10441             );
10442             l_token_table.DELETE();
10443             RAISE FND_API.G_EXC_ERROR;
10444           END IF;
10445 
10446           -- We've found the metadata for the data level of this attribute group
10447 
10448 Debug_Msg(l_api_name || ' ');
10449 Debug_Msg(l_api_name || ', Data Level Metadata (');
10450 Debug_Msg(l_api_name || ',   DATA_LEVEL_ID        = ' || l_curr_data_level_metadata.DATA_LEVEL_ID);
10451 Debug_Msg(l_api_name || ',   DATA_LEVEL_NAME      = ' || l_curr_data_level_metadata.DATA_LEVEL_NAME);
10452 Debug_Msg(l_api_name || ',   USER_DATA_LEVEL_NAME = ' || l_curr_data_level_metadata.USER_DATA_LEVEL_NAME);
10453 Debug_Msg(l_api_name || ',   PK1_COLUMN_NAME      = ' || l_curr_data_level_metadata.PK_COLUMN_NAME1);
10454 Debug_Msg(l_api_name || ',   PK2_COLUMN_NAME      = ' || l_curr_data_level_metadata.PK_COLUMN_NAME2);
10455 Debug_Msg(l_api_name || ',   PK3_COLUMN_NAME      = ' || l_curr_data_level_metadata.PK_COLUMN_NAME3);
10456 Debug_Msg(l_api_name || ',   PK4_COLUMN_NAME      = ' || l_curr_data_level_metadata.PK_COLUMN_NAME4);
10457 Debug_Msg(l_api_name || ',   PK5_COLUMN_NAME      = ' || l_curr_data_level_metadata.PK_COLUMN_NAME5);
10458 Debug_Msg(l_api_name || ',   PK1_COLUMN_TYPE      = ' || l_curr_data_level_metadata.PK_COLUMN_TYPE1);
10459 Debug_Msg(l_api_name || ',   PK2_COLUMN_TYPE      = ' || l_curr_data_level_metadata.PK_COLUMN_TYPE2);
10460 Debug_Msg(l_api_name || ',   PK3_COLUMN_TYPE      = ' || l_curr_data_level_metadata.PK_COLUMN_TYPE3);
10461 Debug_Msg(l_api_name || ',   PK4_COLUMN_TYPE      = ' || l_curr_data_level_metadata.PK_COLUMN_TYPE4);
10462 Debug_Msg(l_api_name || ',   PK5_COLUMN_TYPE      = ' || l_curr_data_level_metadata.PK_COLUMN_TYPE5);
10463 Debug_Msg(l_api_name || ',   DL_PROD_TABLE_NAME   = ' || l_curr_data_level_metadata.DL_PROD_TABLE_NAME);
10464 Debug_Msg(l_api_name || ', )');
10465 Debug_Msg(l_api_name || ' ');
10466           END IF;
10467         END IF;  -- has_data_level
10468 Debug_Msg(l_api_name || ' level 1 done ');
10469 
10470         -- bug 5494760.  Go ahead for processing the Attribute Group only if the
10471         -- attribute group has got some attibutes in it.we return ATTR_METADATA_TABLE
10472         -- as a null if there are no attributes in the attribute group that is passed in.
10473         IF  (l_curr_ag_metadata_obj.ATTR_METADATA_TABLE IS NOT NULL AND l_curr_ag_metadata_obj.ATTR_METADATA_TABLE.COUNT <> 0 ) THEN
10474           -- set the flag to 'Y' even if  there is atleast one attribute group
10475           -- which has attributes in it.
10476           l_has_attrs := 'Y';
10477           -- get the view name
10478           l_curr_ag_vl_name := l_curr_ag_metadata_obj.EXT_TABLE_VL_NAME;
10479           -- get the table name also
10480           l_curr_ag_table_name := l_curr_ag_metadata_obj.EXT_TABLE_B_NAME;
10481           --
10482           -- Here we use l_curr_ag_metadata_obj.ATTR_GROUP_ID as our row identifier for
10483           -- error-reporting purposes; make sure it's known and that it's consistent!
10484           --
10485           G_USER_ROW_IDENTIFIER := l_curr_ag_metadata_obj.ATTR_GROUP_ID;
10486 
10487           l_can_view_this_attr_group := TRUE;
10488 
10489           -----------------------------------------------------------
10490           -- If the Attr Group is secured (either explicitly or by --
10491           -- a default privilege for this Object) AND the caller   --
10492           -- passed a table of privileges, then we ensure that the --
10493           -- user has the required View privilege for this AG      --
10494           -----------------------------------------------------------
10495           IF (G_CURRENT_USER_PRIVILEGES IS NOT NULL) THEN
10496 
10497             Check_Privileges(
10498               p_attr_group_metadata_obj  => l_curr_ag_metadata_obj
10499              ,p_data_level_row_obj       => l_curr_data_level_row_obj
10500              ,p_ignore_edit_privilege    => TRUE
10501              ,p_entity_id                => p_entity_id
10502              ,p_entity_index             => p_entity_index
10503              ,p_entity_code              => p_entity_code
10504              ,x_return_status            => x_return_status
10505             );
10506 
10507             IF (x_return_status <> FND_API.G_RET_STS_SUCCESS) THEN
10508               l_can_view_this_attr_group := FALSE;
10509             END IF;
10510           END IF;
10511 
10512         IF (l_can_view_this_attr_group) THEN
10513 Debug_Msg(l_api_name || ' user can view the AG ');
10514           -------------------------------------------------------
10515           -- Build a Data Level array for this Attribute Group --
10516           -------------------------------------------------------
10517           IF l_curr_data_level_row_obj IS NULL THEN
10518 Debug_Msg(l_api_name || ' 100 ');
10519             -- r12 code
10520             l_data_level_name_value_pairs :=
10521                Build_Data_Level_Array(p_object_name    => p_object_name
10522                                      ,p_data_level_id  => NULL
10523                                      ,p_data_level_1   => l_curr_ag_request_obj.DATA_LEVEL_1
10524                                      ,p_data_level_2   => l_curr_ag_request_obj.DATA_LEVEL_2
10525                                      ,p_data_level_3   => l_curr_ag_request_obj.DATA_LEVEL_3
10526                                      ,p_data_level_4   => NULL
10527                                      ,p_data_level_5   => NULL
10528                                      );
10529           ELSE
10530 Debug_Msg(l_api_name || ' 200 ');
10531             -- r12C code
10532             l_data_level_name_value_pairs :=
10533                Build_Data_Level_Array(p_object_name    => p_object_name
10534                                      ,p_data_level_id  => l_curr_data_level_row_obj.data_level_id
10535                                      ,p_data_level_1   => l_curr_ag_request_obj.DATA_LEVEL_1
10536                                      ,p_data_level_2   => l_curr_ag_request_obj.DATA_LEVEL_2
10537                                      ,p_data_level_3   => l_curr_ag_request_obj.DATA_LEVEL_3
10538                                      ,p_data_level_4   => l_curr_ag_request_obj.DATA_LEVEL_4
10539                                      ,p_data_level_5   => l_curr_ag_request_obj.DATA_LEVEL_5
10540                                      );
10541 Debug_Msg(l_api_name || ', data level key values = (' || l_curr_ag_request_obj.DATA_LEVEL_1 || ',' ||
10542                                                          l_curr_ag_request_obj.DATA_LEVEL_2 || ',' ||
10543                                                          l_curr_ag_request_obj.DATA_LEVEL_3 || ',' ||
10544                                                          l_curr_ag_request_obj.DATA_LEVEL_4 || ',' ||
10545                                                          l_curr_ag_request_obj.DATA_LEVEL_5 || ')', 5);
10546 
10547 
10548           END IF;
10549 
10550 Debug_Msg(l_api_name || ' data level name value pairs built ');
10551 
10552 
10553           ----------------------------------------------------------------------------------
10554           -- Get a list of the names of all requested Attributes for this Attribute Group --
10555           -- (this procedure also checks to be sure each name exists in the metadata)     --
10556           ----------------------------------------------------------------------------------
10557           l_requested_attr_names_table := Get_Requested_Attr_Names(l_curr_ag_metadata_obj.ATTR_GROUP_ID
10558                                                                   ,l_curr_ag_request_obj.ATTR_GROUP_NAME
10559                                                                   ,l_curr_ag_request_obj.ATTR_NAME_LIST
10560                                                                   ,l_curr_ag_metadata_obj.attr_metadata_table
10561                                                                   ,p_entity_id
10562                                                                   ,p_entity_index
10563                                                                   ,p_entity_code);
10564 
10565 Debug_Msg(l_api_name || ' requested attr names table built ');
10566           ---------------------------------------------------------------------------
10567           -- See whether we put error messages onto the stack in the previous call --
10568           ---------------------------------------------------------------------------
10569           IF (l_requested_attr_names_table.EXISTS(-1)) THEN
10570             RAISE FND_API.G_EXC_ERROR;
10571           END IF;
10572           --===================================================================--
10573           -- Loop 1.2
10574           -- For every Attribute in our table of Attribute names, we find its  --
10575           -- metadata and build an augmented version of a Data record for it,  --
10576           -- which we then add to a table for later use in correlating a given --
10577           -- Database Column to the appropriate Attribute and then building an --
10578           -- Attr Data object for that Attr and its value.  We also record the --
10579           -- index bounds in the data table for any given AG ID in order to    --
10580           -- limit the search for the correct augmented data record given the  --
10581           -- current AG ID and Database Column that we are processing.         --
10582           --===================================================================--
10583           l_attr_list_index := l_requested_attr_names_table.FIRST;
10584 
10585           <<GUAD_attributes_loop>>
10586           WHILE (l_attr_list_index <= l_requested_attr_names_table.LAST)
10587           LOOP
10588 Debug_Msg(l_api_name || ' processing attr at  '||l_attr_list_index);
10589 
10590             ---------------------------------------------------
10591             -- We know this call will succeed because it was --
10592             -- tested in Get_Requested_Attr_Names, above     --
10593             ---------------------------------------------------
10594             l_curr_attr_metadata_obj := EGO_USER_ATTRS_COMMON_PVT.Find_Metadata_For_Attr(
10595                                           p_attr_metadata_table => l_curr_ag_metadata_obj.attr_metadata_table
10596                                          ,p_attr_name           => l_requested_attr_names_table(l_attr_list_index)
10597                                         );
10598 Debug_Msg(l_api_name || ' processing attr '|| l_attr_list_index || ' - ' ||l_curr_augmented_attr_rec.ATTR_NAME);
10599             l_curr_augmented_attr_rec.ATTR_GROUP_ID := l_curr_ag_metadata_obj.ATTR_GROUP_ID;
10600             l_curr_augmented_attr_rec.APPLICATION_ID := l_curr_ag_metadata_obj.APPLICATION_ID;
10601             l_curr_augmented_attr_rec.ATTR_GROUP_TYPE := l_curr_ag_metadata_obj.ATTR_GROUP_TYPE;
10602             l_curr_augmented_attr_rec.ATTR_GROUP_NAME := l_curr_ag_metadata_obj.ATTR_GROUP_NAME;
10603             l_curr_augmented_attr_rec.ATTR_NAME := l_curr_attr_metadata_obj.ATTR_NAME;
10604             l_curr_augmented_attr_rec.ATTR_DISP_NAME := l_curr_attr_metadata_obj.ATTR_DISP_NAME;
10605             l_curr_augmented_attr_rec.DATABASE_COLUMN := l_curr_attr_metadata_obj.DATABASE_COLUMN;
10606             --ENHR12:added for passing the internal value of an
10607             --attribute along with the display value.
10608             l_curr_augmented_attr_rec.DATA_TYPE_CODE:=l_curr_attr_metadata_obj.DATA_TYPE_CODE;
10609             ----------------------------------------------------
10610             -- Record the index at which we store this record --
10611             ----------------------------------------------------
10612             l_curr_aug_table_index := l_augmented_data_table.COUNT+1;
10613             l_augmented_data_table(l_curr_aug_table_index) := l_curr_augmented_attr_rec;
10614 
10615             -----------------------------------------------------------------
10616             -- If it's the first index for this AG ID, store it as such... --
10617             -----------------------------------------------------------------
10618             IF (NOT l_table_of_low_ind_for_AG_ID.EXISTS(l_curr_augmented_attr_rec.ATTR_GROUP_ID)) THEN
10619               l_table_of_low_ind_for_AG_ID(l_curr_augmented_attr_rec.ATTR_GROUP_ID) := l_curr_aug_table_index;
10620             END IF;
10621 
10622             ------------------------------------------------------
10623             -- ...and since it's always the last index (so far) --
10624             -- for this AG ID, store it as that as well.        --
10625             ------------------------------------------------------
10626             l_table_of_high_ind_for_AG_ID(l_curr_augmented_attr_rec.ATTR_GROUP_ID) := l_curr_aug_table_index;
10627 
10628             -----------------------------------------------------------------------------
10629             -- If the Database Column for this Attribute is one that has not yet been  --
10630             -- processed, put it into the l_db_column_name_table and put its name and  --
10631             -- its l_db_column_name_table index into the l_db_column_list. If this has --
10632             -- already been done for this column, get the index from l_db_column_list. --
10633             -----------------------------------------------------------------------------
10634             l_curr_db_column_name := l_curr_augmented_attr_rec.DATABASE_COLUMN;
10635 
10636             IF (l_db_column_list IS NULL OR
10637                 INSTR(l_db_column_list, l_curr_db_column_name||':') = 0) THEN
10638 
10639               l_db_column_tables_index := l_db_column_name_table.COUNT+1;
10640               l_db_column_name_table(l_db_column_tables_index) := l_curr_db_column_name;
10641               l_db_column_list := l_db_column_list || l_curr_db_column_name || ':'||l_db_column_tables_index||', ';
10642 
10643             ELSE
10644 
10645               l_start_index := INSTR(l_db_column_list, l_curr_db_column_name||':') + LENGTH(l_curr_db_column_name||':');
10646               l_substring_length := INSTR(l_db_column_list, ',', l_start_index) - l_start_index;
10647               l_db_column_tables_index := TO_NUMBER(SUBSTR(l_db_column_list, l_start_index, l_substring_length));
10648 
10649             END IF;
10650 
10651             ---------------------------------------------------------------
10652             -- By default we want to cast the database column values we  --
10653             -- retrieve to strings (for assignment in ATTR_DISP_VALUE);  --
10654             -- the exception to this is if an Attr has a Table Value Set --
10655             -- (in which case the Int -> Disp value query may assume the --
10656             -- data type of the database column to be a Date or Number)  --
10657             ---------------------------------------------------------------
10658             l_to_char_db_col_expression := EGO_USER_ATTRS_COMMON_PVT.Create_DB_Col_Alias_If_Needed(l_curr_attr_metadata_obj);
10659 
10660             IF (l_curr_attr_metadata_obj.INT_TO_DISP_VAL_QUERY IS NULL) THEN
10661 
10662               ----------------------------------------------------------------------
10663               -- If this Attribute does not have a Value Set that distinguishes   --
10664               -- between Internal and Display Values, we just make sure that a    --
10665               -- query for this Database Column name (as determined by the index) --
10666               -- is in the l_db_column_query_table (we don't want to overwrite a  --
10667               -- possibly more complicated query with our simple formatted one,   --
10668               -- which is why we only add it if one doesn't already exist).       --
10669               ----------------------------------------------------------------------
10670               IF (NOT l_db_column_query_table.EXISTS(l_db_column_tables_index)) THEN
10671 
10672                 --ENHR12:changed for passing the internal value of an
10673                 --attribute along with the display value.
10674                 --------------------------------------------------------------------------
10675                 -- Syalaman - Following If condition is added as part of fix for bug 5859465.
10676                 -- If l_to_char_db_col_expression has coloumn name starting with TO_CHAR,
10677                 -- i.e., for ex., TO_CHAR(N_EXT_ATTR1), then add N_EXT_ATTR1 as alias name
10678                 -- to the column.
10679                 --------------------------------------------------------------------------
10680                 IF (InStr(l_to_char_db_col_expression,'TO_CHAR') = 1) THEN
10681                   l_db_column_query_table(l_db_column_tables_index) := l_to_char_db_col_expression|| ' ' ||
10682                                                                       l_curr_db_column_name|| ','||
10683                                                                       l_to_char_db_col_expression||'  INTERNAL_NAME';
10684                 ELSE
10685                   l_db_column_query_table(l_db_column_tables_index) := l_to_char_db_col_expression|| ','||
10686                                                                       l_to_char_db_col_expression||'  INTERNAL_NAME';
10687                 END IF;
10688                 -- end of fix for bug 5859465.
10689 
10690               END IF;
10691 
10692             ELSE
10693 
10694               --------------------------------------------------------------------
10695               -- Since the Attribute has different Internal and Display Values, --
10696               -- we build or update a DECODE query for the Database Column (so  --
10697               -- that each AG's use of the column gets the correct Disp value)  --
10698               --------------------------------------------------------------------
10699               IF (l_curr_attr_metadata_obj.VALIDATION_CODE IN (
10700                   EGO_EXT_FWK_PUB.G_INDEPENDENT_VALIDATION_CODE,
10701                   EGO_EXT_FWK_PUB.G_TRANS_IND_VALIDATION_CODE)
10702                  ) THEN
10703 
10704                 l_int_to_disp_val_string := l_curr_attr_metadata_obj.INT_TO_DISP_VAL_QUERY;
10705 
10706               ELSIF (l_curr_attr_metadata_obj.VALIDATION_CODE =
10707                      EGO_EXT_FWK_PUB.G_TABLE_VALIDATION_CODE) THEN
10708 
10709                 ----------------------------------------------------------------
10710                 -- In this case we DON'T want to cast the result to a string, --
10711                 -- so we revert our expression to being the database column   --
10712                 ----------------------------------------------------------------
10713                 l_to_char_db_col_expression := l_curr_db_column_name;
10714 
10715                 ------------------------------------------------------------------
10716                 -- This call will tokenize the query if (and only if) necessary --
10717                 ------------------------------------------------------------------
10718                 l_int_to_disp_val_string := Tokenized_Val_Set_Query(
10719                        p_attr_metadata_obj             => l_curr_attr_metadata_obj
10720                       ,p_attr_group_metadata_obj       => l_curr_ag_metadata_obj
10721                       ,p_ext_table_metadata_obj        => l_ext_table_metadata_obj
10722                       ,p_pk_column_name_value_pairs    => p_pk_column_name_value_pairs
10723                       ,p_data_level_name_value_pairs   => l_data_level_name_value_pairs
10724                       ,p_entity_id                     => p_entity_id
10725                       ,p_entity_index                  => p_entity_index
10726                       ,p_entity_code                   => p_entity_code
10727                       ,p_attr_name_value_pairs         => NULL
10728                       ,p_is_disp_to_int_query          => FALSE
10729                       ,p_final_bind_value              => NULL
10730                       ,p_return_bound_sql              => TRUE
10731                      );
10732 
10733               END IF;
10734 
10735               ------------------------------------------------------------
10736               -- We now have the formatted database column name and the --
10737               -- Int -> Disp value conversion query; now we see whether --
10738               -- there is yet a DECODE query for this database column,  --
10739               -- and either create one or add to the existing one       --
10740               ------------------------------------------------------------
10741               IF ((NOT l_db_column_query_table.EXISTS(l_db_column_tables_index)) OR
10742                   l_db_column_query_table(l_db_column_tables_index) = l_to_char_db_col_expression||','||l_to_char_db_col_expression||'  INTERNAL_NAME') THEN
10743                 --ENHR12:changed for passing the internal value of the attribute
10744                 --along with the display value.
10745                 l_db_column_query_table(l_db_column_tables_index) := '' ||
10746                 'DECODE(ATTR_GROUP_ID,'||l_curr_attr_metadata_obj.ATTR_GROUP_ID||',('||
10747                 l_int_to_disp_val_string||l_to_char_db_col_expression||'),'||
10748                 l_to_char_db_col_expression||') '||l_curr_db_column_name||','||l_to_char_db_col_expression||'  INTERNAL_NAME';
10749 
10750               ELSE
10751 
10752                 ---------------------------------------------------
10753                 -- Otherwise, we get the current DECODE query... --
10754                 ---------------------------------------------------
10755                 l_temp_db_query_string := l_db_column_query_table(l_db_column_tables_index);
10756 
10757                 ---------------------------------------------
10758                 -- ...insert our new portion at index 22   --
10759                 -- (i.e., after 'DECODE(ATTR_GROUP_ID,'... --
10760                 ---------------------------------------------
10761                -- Syalaman - Added following if condition as part of fix for bug 5859465.
10762                 IF (SUBSTR(l_temp_db_query_string, 1, 21) = 'DECODE(ATTR_GROUP_ID,' ) THEN
10763 
10764                     l_temp_db_query_string := SUBSTR(l_temp_db_query_string, 1, 21) ||
10765                                               l_curr_attr_metadata_obj.ATTR_GROUP_ID||',('||
10766                                               l_int_to_disp_val_string||
10767                                               l_to_char_db_col_expression||'),'||
10768                                               SUBSTR(l_temp_db_query_string, 22);
10769 
10770                 ELSE
10771                   -- Syalaman - Fix for bug 5859465.
10772                   -- Fix made to take care Independent Value set Type
10773                   -- For Bug id 5859465
10774                   IF (l_curr_attr_metadata_obj.VALIDATION_CODE IN
10775                                     ( EGO_EXT_FWK_PUB.G_INDEPENDENT_VALIDATION_CODE,
10776                                       EGO_EXT_FWK_PUB.G_TRANS_IND_VALIDATION_CODE)) THEN
10777 
10778                     l_temp_db_query_string := 'DECODE(ATTR_GROUP_ID,'||
10779                                                     l_curr_attr_metadata_obj.ATTR_GROUP_ID||' ,('||
10780                                                     l_int_to_disp_val_string||
10781                                                     l_to_char_db_col_expression||'),'||
10782                                                     SubStr(l_temp_db_query_string,1,InStr(l_temp_db_query_string,',')-1) ||') ' ||
10783                                                     l_curr_db_column_name ||
10784                                                     SubStr(l_temp_db_query_string,InStr(l_temp_db_query_string,','));
10785                   ELSE
10786                     l_temp_db_query_string := 'DECODE(ATTR_GROUP_ID,'||
10787                                                     l_curr_attr_metadata_obj.ATTR_GROUP_ID||' ,('||
10788                                                     l_int_to_disp_val_string||
10789                                                     l_to_char_db_col_expression||'),'||
10790                                                     SubStr(l_temp_db_query_string,1,InStr(l_temp_db_query_string,' ')-1) ||') ' ||
10791                                                     l_curr_db_column_name ||
10792                                                     SubStr(l_temp_db_query_string,InStr(l_temp_db_query_string,','));
10793                   END IF;
10794                 END IF;
10795                 -- end of fix for bug 5859465.
10796 
10797                 -------------------------------------------------------------------------
10798                 -- ...and put the updated query back into the l_db_column_query_table. --
10799                 -------------------------------------------------------------------------
10800                 l_db_column_query_table(l_db_column_tables_index) := l_temp_db_query_string;
10801 
10802               END IF;
10803 
10804             END IF;
10805 
10806             l_attr_list_index := l_requested_attr_names_table.NEXT(l_attr_list_index);
10807           END LOOP attributes_loop;
10808 
10809           ---------------------------------------------------------------
10810           -- Make a string to use in the query; it will be of the form --
10811           -- 'DATA_LEVEL_1 = <value> AND ... DATA_LEVEL_N = <value>';  --
10812           -- we know this call will succeed because we built the array --
10813           -- of data level name/value pairs ourselves using metadata.  --
10814           ---------------------------------------------------------------
10815           IF l_has_data_level_col THEN
10816             l_data_level_string := EGO_USER_ATTRS_COMMON_PVT.Get_List_For_Table_Cols(
10817                       p_col_metadata_array    => l_ext_table_metadata_obj.data_level_metadata
10818                      ,p_col_name_value_pairs  => l_data_level_name_value_pairs
10819                      ,p_mode                  => 'EQUALS'
10820                      );
10821           ELSE
10822             l_data_level_string := EGO_USER_ATTRS_COMMON_PVT.Get_List_For_Table_Cols(
10823                       p_col_metadata_array    => l_ext_table_metadata_obj.data_level_metadata
10824                      ,p_col_name_value_pairs  => l_data_level_name_value_pairs
10825                      ,p_mode                  => 'EQUALS'
10826                      );
10827           END IF;
10828           Debug_Msg(l_api_name||' data level string '||l_data_level_string);
10829           ------------------------------------------------
10830           -- Build a predicate for each Attribute Group --
10831           -- and concatenate it into a master predicate --
10832           ------------------------------------------------
10833 
10834           --Bug Fix - 3828505
10835           -- Data-Level can be null so append it to the query only if it is not null;
10836           l_ag_predicate_list :=  '(ATTR_GROUP_ID = '||l_curr_ag_metadata_obj.ATTR_GROUP_ID;
10837 
10838           IF l_data_level_string IS NOT NULL THEN
10839             l_ag_predicate_list := l_ag_predicate_list || ' AND ' || l_data_level_string ;
10840           END IF;
10841 
10842           l_ag_predicate_list := l_ag_predicate_list || ') ';
10843           --Bug Fix - 3828505
10844         ELSE
10845           Debug_Msg(l_api_name || ' user can NOT view the AG ');
10846         END IF; -- the if check for l_can_view_this_attr_group
10847        END IF;--l_curr_ag_metadata_obj.ATTR_METADATA_TABLE IS NOT NULL--bug 5494760
10848 
10849        --bug 5494760
10850        --if there isn't a single attribute group which has attributes in it, return from
10851        --here itself instead of framing the query and executing it.
10852        IF (l_has_attrs <> 'Y') THEN
10853          Debug_Msg(l_api_name||'  there are no attribute groups in the list that has attributes in it.', 1);
10854          ------------------------------------------------------
10855          -- We log all errors we got as we close our session --
10856          ------------------------------------------------------
10857          Close_Business_Object_Session(
10858           p_init_error_handler_flag    => FND_API.To_Boolean(p_init_error_handler)
10859          ,p_log_errors                 => TRUE
10860          ,p_write_to_concurrent_log    => FALSE
10861          );
10862 
10863          x_return_status := FND_API.G_RET_STS_SUCCESS;
10864          RETURN ;
10865        END IF;
10866 
10867         --------------------------------------------------------------------
10868         -- It's possible that the user did not have sufficient privileges --
10869         -- to view even one of the requested Attr Groups; we need to see  --
10870         -- whether we built any Database Column query components at all   --
10871         --------------------------------------------------------------------
10872         IF (l_db_column_query_table.COUNT > 0) THEN
10873 
10874           --------------------------------------------------------------------------------
10875           -- Loop 1.3                                                                   --
10876           -- Now we build a query list with all of our Database Column query components --
10877           --------------------------------------------------------------------------------
10878           l_db_column_list := '';
10879           FOR i IN l_db_column_query_table.FIRST .. l_db_column_query_table.LAST
10880           LOOP
10881             l_db_column_list := l_db_column_list || l_db_column_query_table(i) || ',';
10882           END LOOP;
10883 
10884           -----------------------------------------------------------------------
10885           -- Trim the trailing bits from the Attr Group ID and DB Column lists --
10886           -----------------------------------------------------------------------
10887           l_db_column_list := RTRIM(l_db_column_list, ',');
10888 
10889           ----------------------------------------------------------------------
10890           -- We know this call will succeed because we checked the PK columns --
10891           -- against the metadata in Perform_Preliminary_Checks, above        --
10892           ----------------------------------------------------------------------
10893           l_pk_col_string := EGO_USER_ATTRS_COMMON_PVT.Get_List_For_Table_Cols(
10894                                l_ext_table_metadata_obj.pk_column_metadata
10895                               ,p_pk_column_name_value_pairs
10896                               ,'EQUALS');
10897          --bug 5494760.get the vl name or the table from the place where we have
10898          --set above.
10899           l_dynamic_sql := ' SELECT EXTENSION_ID, ATTR_GROUP_ID, '||l_db_column_list||
10900                              ' FROM ' ||NVL(l_curr_ag_vl_name,l_curr_ag_table_name)||
10901                             ' WHERE ' ||l_pk_col_string||
10902                               ' AND (' ||l_ag_predicate_list||')';
10903 --                            ' ORDER BY ATTR_GROUP_ID ';
10904 
10905           IF l_has_data_level_col THEN
10906 Debug_Msg(l_api_name || ', Data Level ID = ''' || l_curr_data_level_row_obj.data_level_id || '''', 5);
10907             l_dynamic_sql := l_dynamic_sql || ' AND DATA_LEVEL_ID = '|| l_curr_data_level_row_obj.data_level_id;
10908             IF l_curr_data_level_metadata.pk_column_name1 IS  NOT NULL THEN
10909               l_dynamic_sql := l_dynamic_sql || ' AND '||l_curr_data_level_metadata.pk_column_name1||' = '|| l_curr_ag_request_obj.data_level_1;
10910             END IF;
10911             IF l_curr_data_level_metadata.pk_column_name2 IS  NOT NULL THEN
10912               l_dynamic_sql := l_dynamic_sql || ' AND '||l_curr_data_level_metadata.pk_column_name2||' = '|| l_curr_ag_request_obj.data_level_2;
10913             END IF;
10914             IF l_curr_data_level_metadata.pk_column_name3 IS  NOT NULL THEN
10915               l_dynamic_sql := l_dynamic_sql || ' AND '||l_curr_data_level_metadata.pk_column_name3||' = '|| l_curr_ag_request_obj.data_level_3;
10916             END IF;
10917             IF l_curr_data_level_metadata.pk_column_name4 IS  NOT NULL THEN
10918               l_dynamic_sql := l_dynamic_sql || ' AND '||l_curr_data_level_metadata.pk_column_name4||' = '|| l_curr_ag_request_obj.data_level_4;
10919             END IF;
10920             IF l_curr_data_level_metadata.pk_column_name5 IS  NOT NULL THEN
10921               l_dynamic_sql := l_dynamic_sql || ' AND '||l_curr_data_level_metadata.pk_column_name5||' = '|| l_curr_ag_request_obj.data_level_5;
10922             END IF;
10923 
10924 Debug_Msg(l_api_name||'  l_dynamic_sql is as follows:', 3);
10925 Debug_Msg(l_api_name||l_dynamic_sql, 3);
10926           ELSE
10927 Debug_Msg(l_api_name||'  current attribute group has no data level', 3);
10928           END IF;
10929 
10930 
10931           Debug_SQL(l_api_name||l_dynamic_sql);
10932 
10933           ----------------------------------
10934           -- Open a cursor for processing --
10935           ----------------------------------
10936           l_cursor_id := DBMS_SQL.OPEN_CURSOR;
10937           -------------------------------------
10938           -- Parse our dynamic SQL statement --
10939           -------------------------------------
10940           DBMS_SQL.PARSE(l_cursor_id, l_dynamic_sql, DBMS_SQL.NATIVE);
10941           --------------------------------------------------------------------------
10942           -- Register the data types of the columns we are selecting in our query --
10943           -- (in the VARCHAR2 case, that includes stating the maximum size that a --
10944           -- value in the column might be; to be safe we will use 1000 bytes).    --
10945           -- First we register the EXTENSION_ID and ATTR_GROUP_ID...              --
10946           --------------------------------------------------------------------------
10947           DBMS_SQL.Define_Column(l_cursor_id, 1, l_extension_id);
10948           DBMS_SQL.Define_Column(l_cursor_id, 2, l_curr_AG_ID);
10949 
10950           -----------------------------------
10951           -- Loop 1.4
10952           -- ...then the Database Columns. --
10953           -----------------------------------
10954           FOR i IN l_db_column_name_table.FIRST .. l_db_column_name_table.LAST
10955           LOOP
10956 
10957 -- Assumption: TVS values will be castable to string (I know all else will be)
10958 
10959             --------------------------------------------------------------------
10960             -- We cast everything to string for assignment to ATTR_DISP_VALUE --
10961             --------------------------------------------------------------------
10962             -- Syalaman - Fix for bug 5859465
10963             DBMS_SQL.Define_Column(l_cursor_id, (i*2)+1, l_varchar_example, 1000);
10964 
10965             --ENHR12:changed for passing the internal value of the attribute
10966             --along with the display value.
10967             -- Syalaman - Fix for bug 5859465
10968             DBMS_SQL.Define_Column(l_cursor_id, (i*2)+2, l_varchar_example, 1000);
10969           END LOOP;
10970 
10971           -------------------------------
10972           -- Execute our dynamic query --
10973           -------------------------------
10974           l_dummy := DBMS_SQL.Execute(l_cursor_id);
10975           Debug_Msg(l_api_name||'  executed the query', 3);
10976 
10977           --===============================================================================--
10978           -- Loop 1.5                                                                      --
10979           -- As we loop through the result set rows (which are ordered by ATTR_GROUP_ID),  --
10980           -- we search through l_augmented_data_table (which is also ordered by AG ID).    --
10981           -- Since all augmented data elements for a given AG ID are in a certain index    --
10982           -- range in l_augmented_data_table, we can save time by searching for the record --
10983           -- for a particular AG ID and Database Column only in the subset of the data     --
10984           -- table holding records for that AG ID.  Earlier we recorded the lowest and     --
10985           -- highest index in the data table whose elements corresponded to a given AG ID; --
10986           -- we use those numbers to limit our search to the relevent subsets of the data  --
10987           -- table.  The variables we use for this search bounding are:                    --
10988           -- 1). l_curr_AG_ID, which holds the AG ID for the current result set row,       --
10989           -- 2). l_low_aug_tab_ind_for_AG_ID, which holds the lowest index in the data     --
10990           -- table for an Attribute record belonging to the current AG ID, and             --
10991           -- 3). l_high_aug_tab_ind_for_AG_ID, which holds the highest such index.         --
10992           --===============================================================================--
10993           <<GUAD_all_attributes_loop>>
10994           WHILE (DBMS_SQL.FETCH_ROWS(l_cursor_id) > 0)
10995           LOOP
10996 
10997             ----------------------------------------------------------------
10998             -- Get the EXTENSION_ID and ATTR_GROUP_ID for the current row --
10999             ----------------------------------------------------------------
11000             DBMS_SQL.COLUMN_VALUE(l_cursor_id, 1, l_extension_id);
11001             DBMS_SQL.COLUMN_VALUE(l_cursor_id, 2, l_curr_AG_ID);
11002 
11003             -----------------------------------------------------------------
11004             -- Reset the variable that tells us whether we need to build a --
11005             -- new row object for the out parameter x_attributes_row_table --
11006             -----------------------------------------------------------------
11007             l_need_to_build_a_row_obj := TRUE;
11008 
11009             -- Update the search bounds (they will only change with a new AG ID) --
11010 
11011             l_low_aug_tab_ind_for_AG_ID := l_table_of_low_ind_for_AG_ID(l_curr_AG_ID);
11012             l_high_aug_tab_ind_for_AG_ID := l_table_of_high_ind_for_AG_ID(l_curr_AG_ID);
11013 
11014             --==============================================================--
11015             -- Loop 1.5.1                                                   --
11016             --==============================================================--
11017 
11018             <<GUAD_column_name_loop>>
11019             FOR i IN l_db_column_name_table.FIRST .. l_db_column_name_table.LAST
11020             LOOP
11021               --checking this in case none of the column  for a given i and j match
11022               --and always the l_dbcol_cntr follows the pattern that it will be 1
11023               --less than the i here.
11024               IF(l_dbcol_cntr <i-1) THEN
11025                 l_dbcol_cntr:=i-1;
11026               END IF;
11027               ------------------------------------------------------
11028               -- Clear the record for a fresh start to every loop --
11029               ------------------------------------------------------
11030               l_curr_augmented_attr_rec.ATTR_GROUP_ID := NULL;
11031               l_curr_augmented_attr_rec.APPLICATION_ID := NULL;
11032               l_curr_augmented_attr_rec.ATTR_GROUP_TYPE := NULL;
11033               l_curr_augmented_attr_rec.ATTR_GROUP_NAME := NULL;
11034               l_curr_augmented_attr_rec.ATTR_NAME := NULL;
11035               l_curr_augmented_attr_rec.ATTR_DISP_NAME := NULL;
11036               l_curr_augmented_attr_rec.ATTR_DISP_VALUE := NULL;
11037               l_curr_augmented_attr_rec.ATTR_UNIT_OF_MEASURE := NULL;
11038               l_curr_augmented_attr_rec.DATABASE_COLUMN := NULL;
11039               --ENHR12:added for passing the internal value of the attribute
11040               --along with the display value.
11041               l_curr_augmented_attr_rec.ATTR_VALUE_STR := NULL;
11042               l_curr_augmented_attr_rec.ATTR_VALUE_DATE := NULL;
11043               l_curr_augmented_attr_rec.ATTR_VALUE_NUM := NULL;
11044               l_curr_augmented_attr_rec.DATA_TYPE_CODE := NULL;
11045 
11046 --
11047 --  TO DO: include ATTR_UNIT_OF_MEASURE in the data you pull from the extension table
11048 --
11049 
11050               --============================================================--
11051               -- Loop 1.5.1.1                                               --
11052               -- Search within the range of augmented Data records for this --
11053               -- AG ID                                                      --
11054               --============================================================--
11055               <<GUAD_augmented_data_recs_loop>>
11056               FOR j IN l_low_aug_tab_ind_for_AG_ID .. l_high_aug_tab_ind_for_AG_ID
11057               LOOP
11058                 EXIT WHEN (l_curr_augmented_attr_rec.ATTR_GROUP_ID IS NOT NULL);
11059                 --------------------------------------------------------
11060                 -- If the current Data record is associated with the  --
11061                 -- current Database Column, store the column's value  --
11062                 -- temporarily (we will build an Attr Data object for --
11063                 -- it in a few more lines).                           --
11064                 --------------------------------------------------------
11065                 IF (l_db_column_name_table(i) = l_augmented_data_table(j).DATABASE_COLUMN) THEN
11066                   l_curr_augmented_attr_rec := l_augmented_data_table(j);
11067 
11068                   --ENHR12:added for passing the internal value of the attribute
11069                   --along with the display value.
11070                   --setting the Display Value.
11071                   DBMS_SQL.COLUMN_VALUE(l_cursor_id, (i*2)+1, l_curr_augmented_attr_rec.ATTR_DISP_VALUE); -- Fix for bug 5859465
11072 
11073                   --setting the intrnal value of the Attribute depending on the DATA_TYPE_CODE
11074                   --if the attribute is of type Translatable(A) or Char(C)
11075                   IF ('C'=l_curr_augmented_attr_rec.DATA_TYPE_CODE OR 'A'=l_curr_augmented_attr_rec.DATA_TYPE_CODE) THEN
11076                      DBMS_SQL.COLUMN_VALUE(l_cursor_id, (i*2)+2, l_curr_augmented_attr_rec.ATTR_VALUE_STR); -- Fix for bug 5859465
11077                      l_curr_augmented_attr_rec.ATTR_VALUE_DATE:=null;
11078                      l_curr_augmented_attr_rec.ATTR_VALUE_NUM:=null;
11079                       --if the attribute is of type Date(X) or DateTime(Y)
11080                   ELSIF('X'=l_curr_augmented_attr_rec.DATA_TYPE_CODE OR 'Y'=l_curr_augmented_attr_rec.DATA_TYPE_CODE) THEN
11081                      DBMS_SQL.COLUMN_VALUE(l_cursor_id, (i*2)+2,l_char_value);  -- Fix for bug 5859465
11082                      l_curr_augmented_attr_rec.ATTR_VALUE_STR:=null;
11083                      l_curr_augmented_attr_rec.ATTR_VALUE_NUM:=null;
11084                      l_curr_augmented_attr_rec.ATTR_VALUE_DATE:=TO_DATE(l_char_value,'yyyy/mm/dd HH24:MI:SS');
11085                       --if the attribute is of type NUMBER(N)
11086                   ELSIF('N'=l_curr_augmented_attr_rec.DATA_TYPE_CODE) THEN
11087                     DBMS_SQL.COLUMN_VALUE(l_cursor_id, (i*2)+2, l_char_value);  -- Fix for bug 5859465
11088                     l_curr_augmented_attr_rec.ATTR_VALUE_STR:=null;
11089                     l_curr_augmented_attr_rec.ATTR_VALUE_DATE:=null;
11090                     l_curr_augmented_attr_rec.ATTR_VALUE_NUM:=TO_NUMBER(l_char_value);
11091                   END IF;
11092 
11093                   -----------------------------------------------------------
11094                   -- If this is the first Data record for the current row, --
11095                   -- we build a Row object and put it into the row table.  --
11096                   -----------------------------------------------------------
11097                   IF (l_need_to_build_a_row_obj) THEN
11098                     IF (x_attributes_row_table IS NULL) THEN
11099                       x_attributes_row_table := EGO_USER_ATTR_ROW_TABLE();
11100                     END IF;
11101                     x_attributes_row_table.EXTEND();
11102                     IF l_has_data_level_col THEN
11103                       x_attributes_row_table(x_attributes_row_table.LAST) :=
11104                         EGO_USER_ATTR_ROW_OBJ(
11105                           l_extension_id
11106                          ,l_curr_augmented_attr_rec.ATTR_GROUP_ID
11107                          ,l_curr_augmented_attr_rec.APPLICATION_ID
11108                          ,l_curr_augmented_attr_rec.ATTR_GROUP_TYPE
11109                          ,l_curr_augmented_attr_rec.ATTR_GROUP_NAME
11110                          ,l_curr_ag_request_obj.data_level        -- DATA_LEVEL
11111                          ,l_curr_ag_request_obj.data_level_1    -- DATA_LEVEL_1
11112                          ,l_curr_ag_request_obj.data_level_2    -- DATA_LEVEL_2
11113                          ,l_curr_ag_request_obj.data_level_3    -- DATA_LEVEL_3
11114                          ,l_curr_ag_request_obj.data_level_4    -- DATA_LEVEL_4
11115                          ,l_curr_ag_request_obj.data_level_5    -- DATA_LEVEL_5
11116                          ,null                              -- TRANSACTION_TYPE
11117                         );
11118                     ELSE
11119                       x_attributes_row_table(x_attributes_row_table.LAST) :=
11120                         EGO_USER_ATTR_ROW_OBJ(
11121                           l_extension_id
11122                          ,l_curr_augmented_attr_rec.ATTR_GROUP_ID
11123                          ,l_curr_augmented_attr_rec.APPLICATION_ID
11124                          ,l_curr_augmented_attr_rec.ATTR_GROUP_TYPE
11125                          ,l_curr_augmented_attr_rec.ATTR_GROUP_NAME
11126                          ,NULL                                    -- DATA_LEVEL
11127                          ,NULL                                  -- DATA_LEVEL_1
11128                          ,NULL                                  -- DATA_LEVEL_2
11129                          ,NULL                                  -- DATA_LEVEL_3
11130                          ,NULL                                  -- DATA_LEVEL_4
11131                          ,NULL                                  -- DATA_LEVEL_5
11132                          ,NULL                              -- TRANSACTION_TYPE
11133                         );
11134                     END IF;
11135                     l_need_to_build_a_row_obj := FALSE;
11136                   END IF;
11137 
11138                   -----------------------------------------------------
11139                   -- Once we have the value for this Data record, we --
11140                   -- put a Data object for it into the result table; --
11141                   -- the caller will later use ROW_IDENTIFIER (which --
11142                   -- in our case is l_extension_id) to find a row    --
11143                   -- object for any data object.                     --
11144                   -----------------------------------------------------
11145                   IF (x_attributes_data_table IS NULL) THEN
11146                     x_attributes_data_table := EGO_USER_ATTR_DATA_TABLE();
11147                   END IF;
11148 
11149                   x_attributes_data_table.EXTEND();
11150                   x_attributes_data_table(x_attributes_data_table.LAST) :=
11151                   --changed as a part of
11152                   --ENHR12:for passing the internal value of the attribute along
11153                   --with the display value.
11154                     EGO_USER_ATTR_DATA_OBJ(
11155                       l_extension_id
11156                      ,l_curr_augmented_attr_rec.ATTR_NAME
11157                      ,l_curr_augmented_attr_rec.ATTR_VALUE_STR-- ATTR_VALUE_STR
11158                      ,l_curr_augmented_attr_rec.ATTR_VALUE_NUM-- ATTR_VALUE_NUM
11159                      ,l_curr_augmented_attr_rec.ATTR_VALUE_DATE
11160                                                              -- ATTR_VALUE_DATE
11161                      ,l_curr_augmented_attr_rec.ATTR_DISP_VALUE
11162                      ,null                              -- ATTR_UNIT_OF_MEASURE
11163                      ,null                               -- USER_ROW_IDENTIFIER
11164                     );
11165 
11166 Debug_Msg(l_api_name || l_curr_augmented_attr_rec.ATTR_NAME || ' = ' || l_curr_augmented_attr_rec.ATTR_VALUE_STR   );
11167 
11168                 END IF;
11169               END LOOP GUAD_augmented_data_recs_loop;
11170             END LOOP GUAD_column_name_loop;
11171           END LOOP GUAD_all_attributes_loop;
11172 
11173           -----------------------------------------
11174           -- Close the cursor when we're through --
11175           -----------------------------------------
11176           IF (l_cursor_id IS NOT NULL) THEN
11177             DBMS_SQL.Close_Cursor(l_cursor_id);
11178             l_cursor_id := NULL;
11179           END IF;
11180         ELSE
11181 Debug_Msg(l_api_name||' l_db_column_query_table.COUNT = ' || l_db_column_query_table.COUNT, 1);
11182         END IF;  -- l_db_column_query_table.COUNT
11183 
11184         l_dbcol_cntr := 0;
11185         l_db_column_name_table.DELETE;
11186         l_db_column_query_table.DELETE;
11187         l_request_table_index := p_attr_group_request_table.NEXT(l_request_table_index);
11188       END LOOP GUAD_ag_requests_loop;
11189 
11190     END IF;
11191 
11192     Debug_Msg(l_api_name||'  done', 1);
11193 
11194     ------------------------------------------------------
11195     -- We log all errors we got as we close our session --
11196     ------------------------------------------------------
11197     Close_Business_Object_Session(
11198       p_init_error_handler_flag       => FND_API.To_Boolean(p_init_error_handler)
11199      ,p_log_errors                    => TRUE
11200      ,p_write_to_concurrent_log       => FALSE
11201     );
11202 
11203     x_return_status := FND_API.G_RET_STS_SUCCESS;
11204 
11205   EXCEPTION
11206 
11207     WHEN FND_API.G_EXC_ERROR THEN
11208       Debug_Msg(l_api_name || ' FND_API.G_EXC_ERROR '||SQLERRM);
11209       -----------------------------------------
11210       -- Close the cursor if it's still open --
11211       -----------------------------------------
11212       IF (l_cursor_id IS NOT NULL) THEN
11213         DBMS_SQL.Close_Cursor(l_cursor_id);
11214         l_cursor_id := NULL;
11215       END IF;
11216 
11217       ------------------------------------------------------
11218       -- We log all errors we got as we close our session --
11219       ------------------------------------------------------
11220       Close_Business_Object_Session(
11221         p_init_error_handler_flag       => FND_API.To_Boolean(p_init_error_handler)
11222        ,p_log_errors                    => TRUE
11223        ,p_write_to_concurrent_log       => FALSE
11224       );
11225 
11226       x_return_status := FND_API.G_RET_STS_ERROR;
11227 
11228       x_msg_count := ERROR_HANDLER.Get_Message_Count();
11229       IF (x_msg_count = 1) THEN
11230         DECLARE
11231           message_list  ERROR_HANDLER.Error_Tbl_Type;
11232         BEGIN
11233           ERROR_HANDLER.Get_Message_List(message_list);
11234           x_msg_data := message_list(message_list.FIRST).message_text;
11235         END;
11236       ELSE
11237         x_msg_data := NULL;
11238       END IF;
11239 
11240     WHEN OTHERS THEN
11241 
11242       Debug_Msg(l_api_name || ' EXCEPTION OTHERS '||SQLERRM);
11243       -----------------------------------------
11244       -- Close the cursor if it's still open --
11245       -----------------------------------------
11246       IF (l_cursor_id IS NOT NULL) THEN
11247         DBMS_SQL.Close_Cursor(l_cursor_id);
11248         l_cursor_id := NULL;
11249       END IF;
11250       ------------------------------------------------------
11251       -- We log all errors we got as we close our session --
11252       ------------------------------------------------------
11253       Close_Business_Object_Session(
11254         p_init_error_handler_flag       => FND_API.To_Boolean(p_init_error_handler)
11255        ,p_log_errors                    => TRUE
11256        ,p_write_to_concurrent_log       => FALSE
11257       );
11258 
11259       x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
11260       l_token_table(1).TOKEN_NAME := 'PKG_NAME';
11261       l_token_table(1).TOKEN_VALUE := G_PKG_NAME;
11262       l_token_table(2).TOKEN_NAME := 'API_NAME';
11263       l_token_table(2).TOKEN_VALUE := l_api_name;
11264       l_token_table(3).TOKEN_NAME := 'SQL_ERR_MSG';
11265       l_token_table(3).TOKEN_VALUE := SQLERRM;
11266 
11267       ERROR_HANDLER.Add_Error_Message(
11268         p_message_name              => 'EGO_PLSQL_ERR'
11269        ,p_application_id            => 'EGO'
11270        ,p_token_tbl                 => l_token_table
11271        ,p_message_type              => FND_API.G_RET_STS_ERROR
11272        ,p_row_identifier            => G_USER_ROW_IDENTIFIER
11273        ,p_entity_id                 => p_entity_id
11274        ,p_entity_index              => p_entity_index
11275        ,p_entity_code               => p_entity_code
11276        ,p_addto_fnd_stack           => G_ADD_ERRORS_TO_FND_STACK
11277       );
11278       l_token_table.DELETE();
11279       x_msg_count := ERROR_HANDLER.Get_Message_Count();
11280 
11281       IF (x_msg_count = 1) THEN
11282         DECLARE
11283           message_list  ERROR_HANDLER.Error_Tbl_Type;
11284         BEGIN
11285           ERROR_HANDLER.Get_Message_List(message_list);
11286           IF message_list IS NOT NULL AND message_list.count > 0 THEN
11287             x_msg_data := message_list(message_list.FIRST).message_text;
11288           ELSE
11289             x_msg_data := 'Where from did I come here?? ';
11290           END IF;
11291         END;
11292       ELSE
11293         x_msg_data := NULL;
11294       END IF;
11295 
11296 END Get_User_Attrs_Data;
11297 
11298 ----------------------------------------------------------------------
11299 
11300 PROCEDURE Process_Row (
11301         p_api_version                   IN   NUMBER
11302        ,p_object_id                     IN   NUMBER     DEFAULT NULL
11303        ,p_object_name                   IN   VARCHAR2   DEFAULT NULL
11304        ,p_attr_group_id                 IN   NUMBER     DEFAULT NULL
11305        ,p_application_id                IN   NUMBER     DEFAULT NULL
11306        ,p_attr_group_type               IN   VARCHAR2   DEFAULT NULL
11307        ,p_attr_group_name               IN   VARCHAR2   DEFAULT NULL
11308        ,p_validate_hierarchy            IN   VARCHAR2   DEFAULT FND_API.G_TRUE--Added for bugFix:5275391
11309        ,p_pk_column_name_value_pairs    IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
11310        ,p_class_code_name_value_pairs   IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
11311        ,p_data_level                    IN   VARCHAR2   DEFAULT NULL --R12C
11312        ,p_data_level_name_value_pairs   IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
11313        ,p_extension_id                  IN   NUMBER     DEFAULT NULL
11314        ,p_attr_name_value_pairs         IN   EGO_USER_ATTR_DATA_TABLE
11315        ,p_entity_id                     IN   NUMBER     DEFAULT NULL
11316        ,p_entity_index                  IN   NUMBER     DEFAULT NULL
11317        ,p_entity_code                   IN   VARCHAR2   DEFAULT NULL
11318        ,p_validate_only                 IN   VARCHAR2   DEFAULT FND_API.G_FALSE
11319        ,p_language_to_process           IN   VARCHAR2   DEFAULT NULL
11320        ,p_mode                          IN   VARCHAR2   DEFAULT G_SYNC_MODE
11321        ,p_change_obj                    IN   EGO_USER_ATTR_CHANGE_OBJ DEFAULT NULL
11322        ,p_pending_b_table_name          IN   VARCHAR2   DEFAULT NULL
11323        ,p_pending_tl_table_name         IN   VARCHAR2   DEFAULT NULL
11324        ,p_pending_vl_name               IN   VARCHAR2   DEFAULT NULL
11325        ,p_init_fnd_msg_list             IN   VARCHAR2   DEFAULT FND_API.G_FALSE
11326        ,p_add_errors_to_fnd_stack       IN   VARCHAR2   DEFAULT FND_API.G_FALSE
11327        ,p_commit                        IN   VARCHAR2   DEFAULT FND_API.G_FALSE
11328        ,p_raise_business_event          IN   BOOLEAN DEFAULT TRUE
11329        ,x_return_status                 OUT NOCOPY VARCHAR2
11330        ,x_errorcode                     OUT NOCOPY NUMBER
11331        ,x_msg_count                     OUT NOCOPY NUMBER
11332        ,x_msg_data                      OUT NOCOPY VARCHAR2
11333 ) IS
11334     l_extension_id           NUMBER;
11335     l_mode                   VARCHAR2(10);
11336 
11337   BEGIN
11338 
11339       Process_Row(
11340         p_api_version                   => p_api_version
11341        ,p_object_name                   => p_object_name
11342        ,p_attr_group_id                 => p_attr_group_id
11343        ,p_application_id                => p_application_id
11344        ,p_attr_group_type               => p_attr_group_type
11345        ,p_attr_group_name               => p_attr_group_name
11346        ,p_validate_hierarchy            => p_validate_hierarchy
11347        ,p_pk_column_name_value_pairs    => p_pk_column_name_value_pairs
11348        ,p_class_code_name_value_pairs   => p_class_code_name_value_pairs
11349        ,p_data_level                    => p_data_level
11350        ,p_data_level_name_value_pairs   => p_data_level_name_value_pairs
11351        ,p_extension_id                  => p_extension_id
11352        ,p_attr_name_value_pairs         => p_attr_name_value_pairs
11353        ,p_validate_only                 => p_validate_only
11354        ,p_mode                          => p_mode
11355        ,p_change_obj                    => p_change_obj
11356        ,p_pending_b_table_name          => p_pending_b_table_name
11357        ,p_pending_tl_table_name         => p_pending_tl_table_name
11358        ,p_pending_vl_name               => p_pending_vl_name
11359        ,p_entity_id                     => p_entity_id
11360        ,p_entity_index                  => p_entity_index
11361        ,p_entity_code                   => p_entity_code
11362        ,p_raise_business_event                   => p_raise_business_event
11363        ,x_extension_id                  => l_extension_id
11364        ,x_mode                          => l_mode
11365        ,x_return_status                 => x_return_status
11366        ,x_errorcode                     => x_errorcode
11367        ,x_msg_count                     => x_msg_count
11368        ,x_msg_data                      => x_msg_data
11369       );
11370 
11371 END Process_Row;
11372 
11373 ------------------------------------------------------------------------------------------
11374 
11375 PROCEDURE Process_Row (
11376         p_api_version                   IN   NUMBER
11377        ,p_object_id                     IN   NUMBER     DEFAULT NULL
11378        ,p_object_name                   IN   VARCHAR2   DEFAULT NULL
11379        ,p_attr_group_id                 IN   NUMBER     DEFAULT NULL
11380        ,p_application_id                IN   NUMBER     DEFAULT NULL
11381        ,p_attr_group_type               IN   VARCHAR2   DEFAULT NULL
11382        ,p_attr_group_name               IN   VARCHAR2   DEFAULT NULL
11383        ,p_validate_hierarchy            IN   VARCHAR2   DEFAULT FND_API.G_TRUE--Added for bugFix:5275391
11384        ,p_pk_column_name_value_pairs    IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
11385        ,p_class_code_name_value_pairs   IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
11386        ,p_data_level                    IN   VARCHAR2   DEFAULT NULL --R12C
11387        ,p_data_level_name_value_pairs   IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
11388        ,p_extension_id                  IN   NUMBER     DEFAULT NULL
11389        ,p_attr_name_value_pairs         IN   EGO_USER_ATTR_DATA_TABLE
11390        ,p_entity_id                     IN   NUMBER     DEFAULT NULL
11391        ,p_entity_index                  IN   NUMBER     DEFAULT NULL
11392        ,p_entity_code                   IN   VARCHAR2   DEFAULT NULL
11393        ,p_validate_only                 IN   VARCHAR2   DEFAULT FND_API.G_FALSE
11394        ,p_language_to_process           IN   VARCHAR2   DEFAULT NULL
11395        ,p_mode                          IN   VARCHAR2   DEFAULT G_SYNC_MODE
11396        ,p_change_obj                    IN   EGO_USER_ATTR_CHANGE_OBJ DEFAULT NULL
11397        ,p_pending_b_table_name          IN   VARCHAR2   DEFAULT NULL
11398        ,p_pending_tl_table_name         IN   VARCHAR2   DEFAULT NULL
11399        ,p_pending_vl_name               IN   VARCHAR2   DEFAULT NULL
11400        ,p_init_fnd_msg_list             IN   VARCHAR2   DEFAULT FND_API.G_FALSE
11401        ,p_add_errors_to_fnd_stack       IN   VARCHAR2   DEFAULT FND_API.G_FALSE
11402        ,p_commit                        IN   VARCHAR2   DEFAULT FND_API.G_FALSE
11403        ,p_raise_business_event          IN   BOOLEAN DEFAULT TRUE
11404        ,x_extension_id                  OUT NOCOPY NUMBER
11405        ,x_mode                          OUT NOCOPY VARCHAR2
11406        ,x_return_status                 OUT NOCOPY VARCHAR2
11407        ,x_errorcode                     OUT NOCOPY NUMBER
11408        ,x_msg_count                     OUT NOCOPY NUMBER
11409        ,x_msg_data                      OUT NOCOPY VARCHAR2
11410 ) IS
11411 
11412     l_api_name               CONSTANT VARCHAR2(30) := 'Process_Row';
11413 
11414     --we don't use l_api_version yet, but eventually we might:
11415     --if we change required parameters, version goes FROM n.x to (n+1).x
11416     --if we change optional parameters, version goes FROM x.n to x.(n+1)
11417     l_api_version            CONSTANT NUMBER := 1.0;
11418 
11419     l_object_id              NUMBER;
11420     l_attr_name_value_pairs   EGO_USER_ATTR_DATA_TABLE;
11421     l_attr_group_metadata_obj EGO_ATTR_GROUP_METADATA_OBJ;
11422     l_ext_table_metadata_obj EGO_EXT_TABLE_METADATA_OBJ;
11423     l_extension_id           NUMBER;
11424     l_mode                   VARCHAR2(10);
11425 
11426 
11427   BEGIN
11428 
11429     Debug_Msg(l_api_name || ' starting ',1);
11430 
11431     -- SAVEPOINT Process_Row_PUB;
11432     -- (See EXCEPTION notes for why this is commented out)
11433 
11434     -- Check for call compatibility
11435     IF NOT FND_API.Compatible_API_Call (l_api_version, p_api_version,
11436                                         l_api_name, G_PKG_NAME)
11437     THEN
11438       RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
11439     END IF;
11440 
11441     l_object_id := p_object_id;
11442     l_attr_name_value_pairs := p_attr_name_value_pairs;
11443 
11444     Debug_Msg(l_api_name || ' calling  Perform_Setup_Operations ',1);
11445     Perform_Setup_Operations(
11446         p_object_name                   => p_object_name
11447        ,p_attr_group_id                 => p_attr_group_id
11448        ,p_application_id                => p_application_id
11449        ,p_attr_group_type               => p_attr_group_type
11450        ,p_attr_group_name               => p_attr_group_name
11451        ,p_pk_column_name_value_pairs    => p_pk_column_name_value_pairs
11452        ,p_class_code_name_value_pairs   => p_class_code_name_value_pairs
11453        ,p_data_level                    => p_data_level
11454        ,p_data_level_name_value_pairs   => p_data_level_name_value_pairs
11455        ,p_extension_id                  => p_extension_id
11456        ,p_entity_id                     => p_entity_id
11457        ,p_entity_index                  => p_entity_index
11458        ,p_entity_code                   => p_entity_code
11459        ,p_mode                          => p_mode
11460        ,p_change_obj                    => p_change_obj
11461        ,p_pending_b_table_name          => p_pending_b_table_name
11462        ,p_pending_vl_name               => p_pending_vl_name
11463        ,p_init_fnd_msg_list             => p_init_fnd_msg_list
11464        ,p_add_errors_to_fnd_stack       => p_add_errors_to_fnd_stack
11465        ,px_object_id                    => l_object_id
11466        ,px_attr_name_value_pairs        => l_attr_name_value_pairs
11467        ,x_attr_group_metadata_obj       => l_attr_group_metadata_obj
11468        ,x_ext_table_metadata_obj        => l_ext_table_metadata_obj
11469        ,x_extension_id                  => l_extension_id
11470        ,x_mode                          => l_mode
11471        ,x_return_status                 => x_return_status
11472     );
11473     IF (x_return_status <> FND_API.G_RET_STS_SUCCESS) THEN
11474       RAISE FND_API.G_EXC_ERROR;
11475     END IF;
11476 
11477     IF l_extension_id IS NOT NULL THEN
11478       x_extension_id := l_extension_id;
11479     END IF;
11480 
11481     IF l_mode IS NOT NULL THEN
11482       x_mode := l_mode;
11483     END IF;
11484 
11485     ------------------------------------------------------------
11486     -- If the Attr Group is secured (either explicitly or by  --
11487     -- default privileges for this Object) AND the caller has --
11488     -- passed a table of privileges, then we ensure that the  --
11489     -- user has the required privileges for this Attr Group   --
11490     ------------------------------------------------------------
11491     IF ((l_attr_group_metadata_obj.VIEW_PRIVILEGE IS NOT NULL OR
11492          l_attr_group_metadata_obj.EDIT_PRIVILEGE IS NOT NULL) AND
11493         G_CURRENT_USER_PRIVILEGES IS NOT NULL) THEN
11494 
11495     Debug_Msg(l_api_name || ' calling Check_Privileges ',1);
11496       Check_Privileges(
11497         p_attr_group_metadata_obj  => l_attr_group_metadata_obj
11498        ,p_data_level_row_obj       => NULL
11499        ,p_entity_id                => p_entity_id
11500        ,p_entity_index             => p_entity_index
11501        ,p_entity_code              => p_entity_code
11502        ,x_return_status            => x_return_status
11503       );
11504 
11505       IF (x_return_status <> FND_API.G_RET_STS_SUCCESS) THEN
11506         RAISE FND_API.G_EXC_ERROR;
11507       END IF;
11508     END IF;
11509 
11510     IF (l_mode IS NULL OR
11511         l_mode <> G_DELETE_MODE) THEN
11512 
11513     Debug_Msg(l_api_name || ' calling Validate_Row_Pvt ',1);
11514       Validate_Row_Pvt(
11515         p_api_version                   => p_api_version
11516        ,p_object_id                     => l_object_id
11517        ,p_validate_hierarchy            => p_validate_hierarchy
11518        ,p_attr_group_metadata_obj       => l_attr_group_metadata_obj
11519        ,p_ext_table_metadata_obj        => l_ext_table_metadata_obj
11520        ,p_pk_column_name_value_pairs    => p_pk_column_name_value_pairs
11521        ,p_class_code_name_value_pairs   => p_class_code_name_value_pairs
11522        ,p_data_level                    => p_data_level
11523        ,p_data_level_name_value_pairs   => p_data_level_name_value_pairs
11524        ,p_extension_id                  => l_extension_id
11525        ,p_entity_id                     => p_entity_id
11526        ,p_entity_index                  => p_entity_index
11527        ,p_entity_code                   => p_entity_code
11528        ,p_mode                          => l_mode
11529        ,px_attr_name_value_pairs        => l_attr_name_value_pairs
11530        ,x_return_status                 => x_return_status
11531       );
11532       IF (x_return_status <> FND_API.G_RET_STS_SUCCESS) THEN
11533         RAISE FND_API.G_EXC_ERROR;
11534       END IF;
11535     END IF;
11536 
11537 
11538     IF( p_validate_only = FND_API.G_FALSE) THEN
11539 
11540       Debug_Msg(l_api_name||' done with Validate_Row_Pvt and about to call Perform_DML_On_Row_Pvt', 2);
11541 
11542       Perform_DML_On_Row_Pvt(
11543           p_api_version                   => p_api_version
11544          ,p_object_id                     => l_object_id
11545          ,p_attr_group_metadata_obj       => l_attr_group_metadata_obj
11546          ,p_ext_table_metadata_obj        => l_ext_table_metadata_obj
11547          ,p_pk_column_name_value_pairs    => p_pk_column_name_value_pairs
11548          ,p_class_code_name_value_pairs   => p_class_code_name_value_pairs
11549          ,p_data_level                    => p_data_level
11550          ,p_data_level_name_value_pairs   => p_data_level_name_value_pairs
11551          ,p_extension_id                  => l_extension_id
11552          ,p_attr_name_value_pairs         => l_attr_name_value_pairs
11553          ,p_language_to_process           => p_language_to_process
11554          ,p_mode                          => l_mode
11555          ,p_change_obj                    => p_change_obj
11556          ,p_pending_b_table_name          => p_pending_b_table_name
11557          ,p_pending_tl_table_name         => p_pending_tl_table_name
11558          ,p_entity_id                     => p_entity_id
11559          ,p_entity_index                  => p_entity_index
11560          ,p_entity_code                   => p_entity_code
11561          ,p_commit                        => FND_API.G_FALSE
11562          ,p_raise_business_event          => p_raise_business_event
11563          ,x_extension_id                  => x_extension_id
11564          ,x_return_status                 => x_return_status
11565       );
11566       IF (x_return_status <> FND_API.G_RET_STS_SUCCESS) THEN
11567         RAISE FND_API.G_EXC_ERROR;
11568       END IF;
11569 
11570       Debug_Msg('In Process_Row, done', 1);
11571 
11572     END IF;
11573 
11574     IF FND_API.To_Boolean(p_commit) THEN
11575       COMMIT WORK;
11576     END IF;
11577 
11578     x_return_status := FND_API.G_RET_STS_SUCCESS;
11579 
11580   EXCEPTION
11581     ----------------------------------------------------------------------------
11582     -- We don't do a ROLLBACK in this exception block; all exceptions will    --
11583     -- be either from nested API calls failing, in which case those APIs      --
11584     -- will have done ROLLBACKs already, or from some errors in this API      --
11585     -- itself, which doesn't do any DML operations and so has nothing to      --
11586     -- roll back.  (Also, when I was building this package and had a ROLLBACK --
11587     -- call in this exception block, I kept getting the following error:      --
11588     --                                                                        --
11589     --       'ORA-01086: savepoint 'PROCESS_ROW_PUB' never established'       --
11590     --                                                                        --
11591     -- so I took out the ROLLBACK call, which wasn't necessary anyway.)       --
11592     ----------------------------------------------------------------------------
11593 
11594     WHEN FND_API.G_EXC_ERROR THEN
11595       Debug_Msg(l_api_name || ' EXCEPTION FND_API.G_EXC_ERROR');
11596 
11597       IF FND_API.To_Boolean(p_commit) THEN
11598         COMMIT WORK;
11599       END IF;
11600       x_msg_count := ERROR_HANDLER.Get_Message_Count();
11601       IF (x_msg_count = 1) THEN
11602         DECLARE
11603           message_list  ERROR_HANDLER.Error_Tbl_Type;
11604         BEGIN
11605           ERROR_HANDLER.Get_Message_List(message_list);
11606           x_msg_data := message_list(message_list.FIRST).message_text;
11607         END;
11608       ELSE
11609         x_msg_data := NULL;
11610       END IF;
11611 
11612     WHEN OTHERS THEN
11613       Debug_Msg(l_api_name || ' EXCEPTION OTHERS '||SQLERRM);
11614       x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
11615       DECLARE
11616         l_token_table            ERROR_HANDLER.Token_Tbl_Type;
11617       BEGIN
11618         l_token_table(1).TOKEN_NAME := 'PKG_NAME';
11619         l_token_table(1).TOKEN_VALUE := G_PKG_NAME;
11620         l_token_table(2).TOKEN_NAME := 'API_NAME';
11621         l_token_table(2).TOKEN_VALUE := l_api_name;
11622         l_token_table(3).TOKEN_NAME := 'SQL_ERR_MSG';
11623         l_token_table(3).TOKEN_VALUE := SQLERRM;
11624 
11625         ERROR_HANDLER.Add_Error_Message(
11626           p_message_name      => 'EGO_PLSQL_ERR'
11627          ,p_application_id    => 'EGO'
11628          ,p_token_tbl         => l_token_table
11629          ,p_message_type      => FND_API.G_RET_STS_ERROR
11630          ,p_row_identifier    => G_USER_ROW_IDENTIFIER
11631          ,p_entity_id         => p_entity_id
11632          ,p_entity_index      => p_entity_index
11633          ,p_entity_code       => p_entity_code
11634          ,p_addto_fnd_stack   => G_ADD_ERRORS_TO_FND_STACK
11635         );
11636       END;
11637 
11638       x_msg_count := ERROR_HANDLER.Get_Message_Count();
11639 
11640       IF (x_msg_count = 1) THEN
11641         DECLARE
11642           message_list  ERROR_HANDLER.Error_Tbl_Type;
11643         BEGIN
11644           ERROR_HANDLER.Get_Message_List(message_list);
11645           x_msg_data := message_list(message_list.FIRST).message_text;
11646         END;
11647       ELSE
11648         x_msg_data := NULL;
11649       END IF;
11650 
11651 END Process_Row;
11652 
11653 ----------------------------------------------------------------------
11654 
11655 -- This version just performs some preliminary setup operations and
11656 -- and then calls the "private" signature, Validate_Row_Pvt
11657 
11658 PROCEDURE Validate_Row (
11659         p_api_version                   IN   NUMBER
11660        ,p_object_id                     IN   NUMBER     DEFAULT NULL
11661        ,p_object_name                   IN   VARCHAR2   DEFAULT NULL
11662        ,p_attr_group_id                 IN   NUMBER     DEFAULT NULL
11663        ,p_application_id                IN   NUMBER     DEFAULT NULL
11664        ,p_attr_group_type               IN   VARCHAR2   DEFAULT NULL
11665        ,p_attr_group_name               IN   VARCHAR2   DEFAULT NULL
11666        ,p_pk_column_name_value_pairs    IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
11667        ,p_class_code_name_value_pairs   IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
11668        ,p_data_level                    IN   VARCHAR2   DEFAULT NULL --R12C
11669        ,p_data_level_name_value_pairs   IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
11670        ,p_extension_id                  IN   NUMBER     DEFAULT NULL
11671        ,p_attr_name_value_pairs         IN   EGO_USER_ATTR_DATA_TABLE
11672        ,p_entity_id                     IN   NUMBER     DEFAULT NULL
11673        ,p_entity_index                  IN   NUMBER     DEFAULT NULL
11674        ,p_entity_code                   IN   VARCHAR2   DEFAULT NULL
11675        ,p_mode                          IN   VARCHAR2   DEFAULT G_SYNC_MODE
11676        ,p_log_errors                    IN   VARCHAR2   DEFAULT FND_API.G_FALSE
11677        ,p_init_fnd_msg_list             IN   VARCHAR2   DEFAULT FND_API.G_FALSE
11678        ,p_write_to_concurrent_log       IN   VARCHAR2   DEFAULT FND_API.G_FALSE
11679        ,p_add_errors_to_fnd_stack       IN   VARCHAR2   DEFAULT FND_API.G_FALSE
11680        ,p_commit                        IN   VARCHAR2   DEFAULT FND_API.G_FALSE
11681        ,x_return_status                 OUT NOCOPY VARCHAR2
11682        ,x_errorcode                     OUT NOCOPY NUMBER
11683        ,x_msg_count                     OUT NOCOPY NUMBER
11684        ,x_msg_data                      OUT NOCOPY VARCHAR2
11685 ) IS
11686 
11687     l_api_name               CONSTANT VARCHAR2(30) := 'Validate_Row';
11688 
11689     --we don't use l_api_version yet, but eventually we might:
11690     --if we change required parameters, version goes FROM n.x to (n+1).x
11691     --if we change optional parameters, version goes FROM x.n to x.(n+1)
11692     l_api_version            CONSTANT NUMBER := 1.0;
11693 
11694     l_object_id              NUMBER;
11695     l_attr_name_value_pairs   EGO_USER_ATTR_DATA_TABLE;
11696     l_attr_group_metadata_obj EGO_ATTR_GROUP_METADATA_OBJ;
11697     l_ext_table_metadata_obj EGO_EXT_TABLE_METADATA_OBJ;
11698     l_extension_id           NUMBER;
11699     l_mode                   VARCHAR2(10);
11700 
11701   BEGIN
11702 
11703     Debug_Msg(l_api_name||' starting ', 1);
11704 
11705     IF FND_API.To_Boolean(p_commit) THEN
11706       SAVEPOINT Validate_Row_PUB;
11707     END IF;
11708 
11709     -- Check for call compatibility
11710     IF NOT FND_API.Compatible_API_Call (l_api_version, p_api_version,
11711                                         l_api_name, G_PKG_NAME)
11712     THEN
11713       RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
11714     END IF;
11715 
11716 -----------------------------------
11717 
11718     l_object_id := p_object_id;
11719     l_attr_name_value_pairs := p_attr_name_value_pairs;
11720 
11721     Perform_Setup_Operations(
11722         p_object_name                   => p_object_name
11723        ,p_attr_group_id                 => p_attr_group_id
11724        ,p_application_id                => p_application_id
11725        ,p_attr_group_type               => p_attr_group_type
11726        ,p_attr_group_name               => p_attr_group_name
11727        ,p_pk_column_name_value_pairs    => p_pk_column_name_value_pairs
11728        ,p_class_code_name_value_pairs   => p_class_code_name_value_pairs
11729        ,p_data_level                    => p_data_level
11730        ,p_data_level_name_value_pairs   => p_data_level_name_value_pairs
11731        ,p_extension_id                  => p_extension_id
11732        ,p_entity_id                     => p_entity_id
11733        ,p_entity_index                  => p_entity_index
11734        ,p_entity_code                   => p_entity_code
11735        ,p_mode                          => p_mode
11736        ,p_init_fnd_msg_list             => p_init_fnd_msg_list
11737        ,p_add_errors_to_fnd_stack       => p_add_errors_to_fnd_stack
11738        ,px_object_id                    => l_object_id
11739        ,px_attr_name_value_pairs        => l_attr_name_value_pairs
11740        ,x_attr_group_metadata_obj       => l_attr_group_metadata_obj
11741        ,x_ext_table_metadata_obj        => l_ext_table_metadata_obj
11742        ,x_extension_id                  => l_extension_id
11743        ,x_mode                          => l_mode
11744        ,x_return_status                 => x_return_status
11745     );
11746     IF (x_return_status <> FND_API.G_RET_STS_SUCCESS) THEN
11747       RAISE FND_API.G_EXC_ERROR;
11748     END IF;
11749 
11750     Debug_Msg(l_api_name||' calling Validate_Row_Pvt ', 1);
11751     Validate_Row_Pvt(
11752         p_api_version                   => p_api_version
11753        ,p_object_id                     => l_object_id
11754        ,p_attr_group_metadata_obj       => l_attr_group_metadata_obj
11755        ,p_ext_table_metadata_obj        => l_ext_table_metadata_obj
11756        ,p_pk_column_name_value_pairs    => p_pk_column_name_value_pairs
11757        ,p_class_code_name_value_pairs   => p_class_code_name_value_pairs
11758        ,p_data_level                    => p_data_level
11759        ,p_data_level_name_value_pairs   => p_data_level_name_value_pairs
11760        ,p_extension_id                  => l_extension_id
11761        ,p_entity_id                     => p_entity_id
11762        ,p_entity_index                  => p_entity_index
11763        ,p_entity_code                   => p_entity_code
11764        ,p_mode                          => l_mode
11765        ,px_attr_name_value_pairs        => l_attr_name_value_pairs
11766        ,x_return_status                 => x_return_status
11767     );
11768     IF (x_return_status <> FND_API.G_RET_STS_SUCCESS) THEN
11769       RAISE FND_API.G_EXC_ERROR;
11770     END IF;
11771 
11772     Close_Business_Object_Session(
11773       p_init_error_handler_flag       => FALSE
11774      ,p_log_errors                    => FND_API.To_Boolean(p_log_errors)
11775      ,p_write_to_concurrent_log       => FND_API.To_Boolean(p_write_to_concurrent_log)
11776     );
11777 
11778     IF FND_API.To_Boolean(p_commit) THEN
11779       COMMIT WORK;
11780     END IF;
11781 
11782     x_return_status := FND_API.G_RET_STS_SUCCESS;
11783     Debug_Msg(l_api_name||' ending ', 1);
11784 
11785   EXCEPTION
11786     WHEN FND_API.G_EXC_ERROR THEN
11787       Debug_Msg(l_api_name || ' EXCEPTION FND_API.G_EXC_ERROR');
11788       IF FND_API.To_Boolean(p_commit) THEN
11789         ROLLBACK TO Validate_Row_PUB;
11790       END IF;
11791       Close_Business_Object_Session(
11792         p_init_error_handler_flag     => FALSE
11793        ,p_log_errors                  => FND_API.To_Boolean(p_log_errors)
11794        ,p_write_to_concurrent_log     => FND_API.To_Boolean(p_write_to_concurrent_log)
11795       );
11796 
11797       x_msg_count := ERROR_HANDLER.Get_Message_Count();
11798       IF (x_msg_count = 1) THEN
11799         DECLARE
11800           message_list  ERROR_HANDLER.Error_Tbl_Type;
11801         BEGIN
11802           ERROR_HANDLER.Get_Message_List(message_list);
11803           x_msg_data := message_list(message_list.FIRST).message_text;
11804         END;
11805       ELSE
11806         x_msg_data := NULL;
11807       END IF;
11808 
11809     WHEN OTHERS THEN
11810       Debug_Msg(l_api_name || ' EXCEPTION OTHERS '||SQLERRM);
11811       IF FND_API.To_Boolean(p_commit) THEN
11812         ROLLBACK TO Validate_Row_PUB;
11813       END IF;
11814       x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
11815 
11816       DECLARE
11817         l_token_table            ERROR_HANDLER.Token_Tbl_Type;
11818       BEGIN
11819         l_token_table(1).TOKEN_NAME := 'PKG_NAME';
11820         l_token_table(1).TOKEN_VALUE := G_PKG_NAME;
11821         l_token_table(2).TOKEN_NAME := 'API_NAME';
11822         l_token_table(2).TOKEN_VALUE := l_api_name;
11823         l_token_table(3).TOKEN_NAME := 'SQL_ERR_MSG';
11824         l_token_table(3).TOKEN_VALUE := SQLERRM;
11825 
11826         ERROR_HANDLER.Add_Error_Message(
11827           p_message_name      => 'EGO_PLSQL_ERR'
11828          ,p_application_id    => 'EGO'
11829          ,p_token_tbl         => l_token_table
11830          ,p_message_type      => FND_API.G_RET_STS_ERROR
11831          ,p_row_identifier    => G_USER_ROW_IDENTIFIER
11832          ,p_entity_id         => p_entity_id
11833          ,p_entity_index      => p_entity_index
11834          ,p_entity_code       => p_entity_code
11835          ,p_addto_fnd_stack   => G_ADD_ERRORS_TO_FND_STACK
11836         );
11837       END;
11838 
11839       Close_Business_Object_Session(
11840         p_init_error_handler_flag     => FALSE
11841        ,p_log_errors                  => FND_API.To_Boolean(p_log_errors)
11842        ,p_write_to_concurrent_log     => FND_API.To_Boolean(p_write_to_concurrent_log)
11843       );
11844 
11845       x_msg_count := ERROR_HANDLER.Get_Message_Count();
11846 
11847       IF (x_msg_count = 1) THEN
11848         DECLARE
11849           message_list  ERROR_HANDLER.Error_Tbl_Type;
11850         BEGIN
11851           ERROR_HANDLER.Get_Message_List(message_list);
11852           x_msg_data := message_list(message_list.FIRST).message_text;
11853         END;
11854       ELSE
11855         x_msg_data := NULL;
11856       END IF;
11857 
11858 END Validate_Row;
11859 
11860 
11861 ----------------------------------------------------------------------
11862 
11863 -- The API returns the complete DML for a given attribute group
11864 -- with the corresponding binds. In case the DML is to be done
11865 -- on a table other than the one seeded for the given attr group
11866 -- type the table names can be passed as p_alternate_ext_*_table_name
11867 ----------------------------------------------------------------------
11868 
11869 PROCEDURE Generate_DML_For_Row (
11870         p_api_version                      IN   NUMBER
11871        ,p_object_id                        IN   NUMBER     DEFAULT NULL
11872        ,p_object_name                      IN   VARCHAR2   DEFAULT NULL
11873        ,p_attr_group_id                    IN   NUMBER     DEFAULT NULL
11874        ,p_application_id                   IN   NUMBER     DEFAULT NULL
11875        ,p_attr_group_type                  IN   VARCHAR2   DEFAULT NULL
11876        ,p_attr_group_name                  IN   VARCHAR2   DEFAULT NULL
11877        ,p_pk_column_name_value_pairs       IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
11878        ,p_class_code_name_value_pairs      IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
11879        ,p_data_level                       IN   VARCHAR2   DEFAULT NULL --R12C
11880        ,p_data_level_name_value_pairs      IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
11881        ,p_extension_id                     IN   NUMBER     DEFAULT NULL
11882        ,p_attr_name_value_pairs            IN   EGO_USER_ATTR_DATA_TABLE
11883        ,p_mode                             IN   VARCHAR2   DEFAULT G_SYNC_MODE
11884        ,p_extra_pk_col_name_val_pairs      IN   EGO_COL_NAME_VALUE_PAIR_ARRAY DEFAULT NULL
11885        ,p_extra_attr_name_value_pairs      IN   EGO_COL_NAME_VALUE_PAIR_ARRAY DEFAULT NULL
11886        ,p_alternate_ext_b_table_name       IN   VARCHAR2   DEFAULT NULL
11887        ,p_alternate_ext_tl_table_name      IN   VARCHAR2   DEFAULT NULL
11888        ,p_alternate_ext_vl_name            IN   VARCHAR2   DEFAULT NULL
11889        ,p_execute_dml                      IN   VARCHAR2   DEFAULT FND_API.G_FALSE
11890        ,p_entity_id                        IN   NUMBER     DEFAULT NULL
11891        ,p_entity_index                     IN   NUMBER     DEFAULT NULL
11892        ,p_entity_code                      IN   VARCHAR2   DEFAULT NULL
11893        ,p_debug_level                      IN   NUMBER     DEFAULT 0
11894        ,p_use_def_vals_on_insert           IN   VARCHAR2   DEFAULT FND_API.G_FALSE
11895        ,p_log_errors                       IN   VARCHAR2   DEFAULT FND_API.G_FALSE
11896        ,p_init_fnd_msg_list                IN   VARCHAR2   DEFAULT FND_API.G_FALSE
11897        ,p_write_to_concurrent_log          IN   VARCHAR2   DEFAULT FND_API.G_FALSE
11898        ,p_add_errors_to_fnd_stack          IN   VARCHAR2   DEFAULT FND_API.G_FALSE
11899        ,p_commit                           IN   VARCHAR2   DEFAULT FND_API.G_FALSE
11900        ,p_bulkload_flag                    IN   VARCHAR2   DEFAULT FND_API.G_FALSE
11901        ,p_raise_business_event             IN   BOOLEAN DEFAULT TRUE
11902        ,x_return_status                    OUT NOCOPY VARCHAR2
11903        ,x_errorcode                        OUT NOCOPY NUMBER
11904        ,x_msg_count                        OUT NOCOPY NUMBER
11905        ,x_msg_data                         OUT NOCOPY VARCHAR2
11906        ,x_b_dml_for_ag                     OUT NOCOPY VARCHAR2
11907        ,x_tl_dml_for_ag                    OUT NOCOPY VARCHAR2
11908        ,x_b_bind_count                     OUT NOCOPY NUMBER
11909        ,x_tl_bind_count                    OUT NOCOPY NUMBER
11910        ,x_b_bind_attr_table                OUT NOCOPY EGO_USER_ATTR_DATA_TABLE
11911        ,x_tl_bind_attr_table               OUT NOCOPY EGO_USER_ATTR_DATA_TABLE
11912  ) IS
11913 
11914     l_api_name               CONSTANT VARCHAR2(30) := 'Generate_DML_For_Row';
11915 
11916     --we don't use l_api_version yet, but eventually we might:
11917     --if we change required parameters, version goes FROM n.x to (n+1).x
11918     --if we change optional parameters, version goes FROM x.n to x.(n+1)
11919     l_api_version            CONSTANT NUMBER := 1.0;
11920 
11921     l_object_id              NUMBER;
11922     l_attr_name_value_pairs   EGO_USER_ATTR_DATA_TABLE;
11923     l_attr_group_metadata_obj EGO_ATTR_GROUP_METADATA_OBJ;
11924     l_ext_table_metadata_obj EGO_EXT_TABLE_METADATA_OBJ;
11925     l_extension_id           NUMBER;
11926     l_mode                   VARCHAR2(10);
11927     l_dml                    VARCHAR2(32767);
11928     l_b_dml_bind_list        EGO_USER_ATTR_DATA_TABLE;
11929     l_tl_dml_bind_list       EGO_USER_ATTR_DATA_TABLE;
11930     l_bind_name              VARCHAR2(100);
11931 
11932   BEGIN
11933 
11934     Debug_Msg(l_api_name||' starting ', 1);
11935     -- Check for call compatibility
11936     IF NOT FND_API.Compatible_API_Call (l_api_version, p_api_version,
11937                                         l_api_name, G_PKG_NAME)
11938     THEN
11939       RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
11940     END IF;
11941 
11942     IF (FND_API.To_Boolean(p_init_fnd_msg_list)) THEN
11943       ERROR_HANDLER.Initialize();
11944     END IF;
11945 
11946     G_B_TABLE_DML   := '';
11947     G_TL_TABLE_DML  := '';
11948     G_BIND_INDEX    := 0;
11949     G_TL_BIND_INDEX := 0;
11950     G_B_BIND_INDEX  := 0;
11951 
11952    FOR i IN 1 .. 100 LOOP
11953 
11954     G_BIND_IDENTIFIER_TBL(i) := NULL;
11955     G_BIND_DATATYPE_TBL(i) := NULL;
11956     G_BIND_TEXT_TBL(i) := NULL;
11957     G_BIND_DATE_TBL(i) := NULL;
11958     G_BIND_NUMBER_TBL(i) := NULL;
11959 
11960     G_B_BIND_IDENTIFIER_TBL(i) := NULL;
11961     G_B_BIND_DATATYPE_TBL(i) := NULL;
11962     G_B_BIND_TEXT_TBL(i) := NULL;
11963     G_B_BIND_DATE_TBL(i) := NULL;
11964     G_B_BIND_NUMBER_TBL(i) := NULL;
11965 
11966     G_TL_BIND_IDENTIFIER_TBL(i) := NULL;
11967     G_TL_BIND_DATATYPE_TBL(i) := NULL;
11968     G_TL_BIND_TEXT_TBL(i) := NULL;
11969     G_TL_BIND_DATE_TBL(i) := NULL;
11970     G_TL_BIND_NUMBER_TBL(i) := NULL;
11971 
11972    END LOOP;
11973 
11974     G_SYNC_TO_UPDATE := 'N';
11975     l_object_id := p_object_id;
11976     l_attr_name_value_pairs := p_attr_name_value_pairs;
11977 
11978     Perform_Setup_Operations(
11979         p_object_name                   => p_object_name
11980        ,p_attr_group_id                 => p_attr_group_id
11981        ,p_application_id                => p_application_id
11982        ,p_attr_group_type               => p_attr_group_type
11983        ,p_attr_group_name               => p_attr_group_name
11984        ,p_pk_column_name_value_pairs    => p_pk_column_name_value_pairs
11985        ,p_class_code_name_value_pairs   => p_class_code_name_value_pairs
11986        ,p_data_level                    => p_data_level
11987        ,p_data_level_name_value_pairs   => p_data_level_name_value_pairs
11988        ,p_extension_id                  => p_extension_id
11989        ,p_entity_id                     => p_entity_id
11990        ,p_entity_index                  => p_entity_index
11991        ,p_entity_code                   => p_entity_code
11992        ,p_init_fnd_msg_list             => p_init_fnd_msg_list
11993        ,p_mode                          => p_mode
11994        ,p_extra_pk_col_name_val_pairs   => p_extra_pk_col_name_val_pairs
11995        ,p_pending_b_table_name          => p_alternate_ext_b_table_name
11996        ,p_pending_vl_name               => p_alternate_ext_vl_name
11997        ,p_add_errors_to_fnd_stack       => p_add_errors_to_fnd_stack
11998        ,p_use_def_vals_on_insert_flag   => FND_API.To_Boolean(p_use_def_vals_on_insert)
11999        ,p_debug_level                   => p_debug_level
12000        ,p_bulkload_flag                 => FND_API.To_Boolean(p_bulkload_flag)
12001        ,px_object_id                    => l_object_id
12002        ,px_attr_name_value_pairs        => l_attr_name_value_pairs
12003        ,x_attr_group_metadata_obj       => l_attr_group_metadata_obj
12004        ,x_ext_table_metadata_obj        => l_ext_table_metadata_obj
12005        ,x_extension_id                  => l_extension_id
12006        ,x_mode                          => l_mode
12007        ,x_return_status                 => x_return_status
12008     );
12009 
12010     IF (x_return_status <> FND_API.G_RET_STS_SUCCESS) THEN
12011       RAISE FND_API.G_EXC_ERROR;
12012     END IF;
12013 
12014     Debug_Msg(l_api_name||' calling  Perform_DML_On_Row_Pvt', 1);
12015     Perform_DML_On_Row_Pvt(
12016         p_api_version                   => p_api_version
12017        ,p_object_id                     => l_object_id
12018        ,p_attr_group_metadata_obj       => l_attr_group_metadata_obj
12019        ,p_ext_table_metadata_obj        => l_ext_table_metadata_obj
12020        ,p_pk_column_name_value_pairs    => p_pk_column_name_value_pairs
12021        ,p_class_code_name_value_pairs   => p_class_code_name_value_pairs
12022        ,p_data_level                    => p_data_level
12023        ,p_data_level_name_value_pairs   => p_data_level_name_value_pairs
12024        ,p_extension_id                  => p_extension_id
12025        ,p_attr_name_value_pairs         => l_attr_name_value_pairs
12026        ,p_mode                          => l_mode
12027        ,p_extra_pk_col_name_val_pairs   => p_extra_pk_col_name_val_pairs
12028        ,p_extra_attr_name_value_pairs   => p_extra_attr_name_value_pairs
12029        ,p_pending_b_table_name          => p_alternate_ext_b_table_name
12030        ,p_pending_tl_table_name         => p_alternate_ext_tl_table_name
12031        ,p_execute_dml                   => p_execute_dml
12032        ,p_entity_id                     => p_entity_id
12033        ,p_entity_index                  => p_entity_index
12034        ,p_entity_code                   => p_entity_code
12035        ,p_commit                        => FND_API.G_FALSE
12036        ,p_raise_business_event          => p_raise_business_event
12037        ,p_bulkload_flag                 => FND_API.To_Boolean(p_bulkload_flag)
12038        ,x_extension_id                  => l_extension_id
12039        ,x_return_status                 => x_return_status
12040     );
12041     IF (x_return_status <> FND_API.G_RET_STS_SUCCESS) THEN
12042       RAISE FND_API.G_EXC_ERROR;
12043     END IF;
12044 
12045     x_b_dml_for_ag      := G_B_TABLE_DML;
12046     x_tl_dml_for_ag     := G_TL_TABLE_DML;
12047     x_b_bind_count      := G_B_BIND_INDEX;
12048     x_tl_bind_count     := G_TL_BIND_INDEX;
12049 
12050     l_b_dml_bind_list   := EGO_USER_ATTR_DATA_TABLE();
12051     l_tl_dml_bind_list  := EGO_USER_ATTR_DATA_TABLE();
12052 
12053     FOR i in 1 .. G_B_BIND_INDEX
12054     LOOP
12055 
12056       l_bind_name := ':FND_BIND'||TO_CHAR(i);
12057       l_b_dml_bind_list.EXTEND();
12058       IF(G_B_BIND_DATATYPE_TBL(i) = 'D') THEN
12059         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);
12060       ELSIF (G_B_BIND_DATATYPE_TBL(i) = 'N') THEN
12061         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);
12062       ELSE
12063         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);
12064       END IF;
12065     END LOOP;
12066 
12067 
12068     FOR j in 1 .. G_TL_BIND_INDEX
12069     LOOP
12070 
12071       l_bind_name := ':FND_BIND'||TO_CHAR(j);
12072       l_tl_dml_bind_list.EXTEND();
12073       IF(G_TL_BIND_DATATYPE_TBL(j) = 'D') THEN
12074         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);
12075       ELSIF (G_TL_BIND_DATATYPE_TBL(j) = 'N') THEN
12076         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);
12077       ELSE
12078         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);
12079       END IF;
12080     END LOOP;
12081 
12082     x_b_bind_attr_table  := l_b_dml_bind_list;
12083     x_tl_bind_attr_table := l_tl_dml_bind_list;
12084 
12085     Close_Business_Object_Session(
12086       p_init_error_handler_flag       => (p_debug_level > 0)
12087      ,p_log_errors                    => FND_API.To_Boolean(p_log_errors)
12088      ,p_write_to_concurrent_log       => FND_API.To_Boolean(p_write_to_concurrent_log)
12089     );
12090 
12091     IF FND_API.To_Boolean(p_commit) THEN
12092       COMMIT WORK;
12093     END IF;
12094 
12095     x_return_status := FND_API.G_RET_STS_SUCCESS;
12096 
12097     Debug_Msg(l_api_name||' ending ', 1);
12098 
12099   EXCEPTION
12100 
12101     WHEN FND_API.G_EXC_ERROR THEN
12102       Debug_Msg(l_api_name || ' EXCEPTION FND_API.G_EXC_ERROR');
12103 
12104       Close_Business_Object_Session(
12105         p_init_error_handler_flag     => (p_debug_level > 0)
12106        ,p_log_errors                  => FND_API.To_Boolean(p_log_errors)
12107        ,p_write_to_concurrent_log     => FND_API.To_Boolean(p_write_to_concurrent_log)
12108       );
12109 
12110       x_msg_count := ERROR_HANDLER.Get_Message_Count();
12111       IF (x_msg_count = 1) THEN
12112         DECLARE
12113           message_list  ERROR_HANDLER.Error_Tbl_Type;
12114         BEGIN
12115           ERROR_HANDLER.Get_Message_List(message_list);
12116           x_msg_data := message_list(message_list.FIRST).message_text;
12117         END;
12118       ELSE
12119         x_msg_data := NULL;
12120       END IF;
12121 
12122     WHEN OTHERS THEN
12123       Debug_Msg(l_api_name || ' EXCEPTION OTHERS '||SQLERRM);
12124       x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
12125       DECLARE
12126         l_token_table            ERROR_HANDLER.Token_Tbl_Type;
12127       BEGIN
12128         l_token_table(1).TOKEN_NAME := 'PKG_NAME';
12129         l_token_table(1).TOKEN_VALUE := G_PKG_NAME;
12130         l_token_table(2).TOKEN_NAME := 'API_NAME';
12131         l_token_table(2).TOKEN_VALUE := l_api_name;
12132         l_token_table(3).TOKEN_NAME := 'SQL_ERR_MSG';
12133         l_token_table(3).TOKEN_VALUE := SQLERRM;
12134 
12135         ERROR_HANDLER.Add_Error_Message(
12136           p_message_name      => 'EGO_PLSQL_ERR'
12137          ,p_application_id    => 'EGO'
12138          ,p_token_tbl         => l_token_table
12139          ,p_message_type      => FND_API.G_RET_STS_ERROR
12140          ,p_row_identifier    => G_USER_ROW_IDENTIFIER
12141          ,p_entity_id         => p_entity_id
12142          ,p_entity_index      => p_entity_index
12143          ,p_entity_code       => p_entity_code
12144          ,p_addto_fnd_stack   => G_ADD_ERRORS_TO_FND_STACK
12145         );
12146       END;
12147 
12148       Close_Business_Object_Session(
12149         p_init_error_handler_flag     => (p_debug_level > 0)
12150        ,p_log_errors                  => FND_API.To_Boolean(p_log_errors)
12151        ,p_write_to_concurrent_log     => FND_API.To_Boolean(p_write_to_concurrent_log)
12152       );
12153 
12154       x_msg_count := ERROR_HANDLER.Get_Message_Count();
12155 
12156       IF (x_msg_count = 1) THEN
12157         DECLARE
12158           message_list  ERROR_HANDLER.Error_Tbl_Type;
12159         BEGIN
12160           ERROR_HANDLER.Get_Message_List(message_list);
12161           x_msg_data := message_list(message_list.FIRST).message_text;
12162         END;
12163       ELSE
12164         x_msg_data := NULL;
12165       END IF;
12166 
12167 END Generate_DML_For_Row;
12168 
12169 ----------------------------------------------------------------------
12170 
12171 
12172 
12173 ----------------------------------------------------------------------
12174 -- This API returns the extension id of the attr group row          --
12175 ----------------------------------------------------------------------
12176 
12177 FUNCTION Get_Extension_Id (
12178         p_object_name                      IN   VARCHAR2
12179        ,p_attr_group_id                    IN   NUMBER     DEFAULT NULL
12180        ,p_application_id                   IN   NUMBER
12181        ,p_attr_group_type                  IN   VARCHAR2
12182        ,p_attr_group_name                  IN   VARCHAR2   DEFAULT NULL
12183        ,p_pk_column_name_value_pairs       IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
12184        ,p_data_level                       IN   VARCHAR2   DEFAULT NULL --R12C
12185        ,p_data_level_name_value_pairs      IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
12186        ,p_attr_name_value_pairs            IN   EGO_USER_ATTR_DATA_TABLE
12187        ,p_extra_pk_col_name_val_pairs      IN   EGO_COL_NAME_VALUE_PAIR_ARRAY DEFAULT NULL
12188        ,p_extra_attr_name_value_pairs      IN   EGO_COL_NAME_VALUE_PAIR_ARRAY DEFAULT NULL
12189        ,p_alternate_ext_b_table_name       IN   VARCHAR2   DEFAULT NULL
12190        ,p_alternate_ext_tl_table_name      IN   VARCHAR2   DEFAULT NULL
12191        ,p_alternate_ext_vl_name            IN   VARCHAR2   DEFAULT NULL
12192        ) RETURN NUMBER
12193  IS
12194 
12195     l_attr_name_value_pairs   EGO_USER_ATTR_DATA_TABLE;
12196     l_attr_group_metadata_obj EGO_ATTR_GROUP_METADATA_OBJ;
12197     l_ext_table_metadata_obj  EGO_EXT_TABLE_METADATA_OBJ;
12198     l_ext_id                  NUMBER;
12199     l_object_id               NUMBER;
12200 
12201  BEGIN
12202 
12203     l_attr_group_metadata_obj := EGO_USER_ATTRS_COMMON_PVT.Get_Attr_Group_Metadata(p_attr_group_id
12204                                                                                   ,p_application_id
12205                                                                                   ,p_attr_group_type
12206                                                                                   ,p_attr_group_name);
12207     BEGIN
12208       SELECT OBJECT_ID INTO l_object_id
12209         FROM FND_OBJECTS
12210        WHERE OBJ_NAME = p_object_name;
12211     EXCEPTION
12212       WHEN OTHERS THEN
12213        NULL;
12214     END;
12215 
12216     l_ext_table_metadata_obj :=  EGO_USER_ATTRS_COMMON_PVT.Get_Ext_Table_Metadata(l_object_id);
12217 
12218     l_ext_id := Get_Extension_Id_For_Row(
12219                                           p_attr_group_metadata_obj     => l_attr_group_metadata_obj
12220                                          ,p_ext_table_metadata_obj      => l_ext_table_metadata_obj
12221                                          ,p_pk_column_name_value_pairs  => p_pk_column_name_value_pairs
12222                                          ,p_data_level                  => p_data_level
12223                                          ,p_data_level_name_value_pairs => p_data_level_name_value_pairs
12224                                          ,p_attr_name_value_pairs       => p_attr_name_value_pairs
12225                                          ,p_extra_pk_col_name_val_pairs => p_extra_pk_col_name_val_pairs
12226                                          ,p_pending_b_table_name        => p_alternate_ext_b_table_name
12227                                          ,p_pending_vl_name             => p_alternate_ext_vl_name
12228                                         );
12229     RETURN l_ext_id;
12230 
12231  END Get_Extension_Id;
12232 
12233 
12234 
12235 --gnanda end
12236 
12237 
12238 
12239 
12240 
12241 
12242 ----------------------------------------------------------------------
12243 
12244 -- This version just performs some preliminary setup operations and
12245 -- and then calls the "private" signature, Perform_DML_On_Row_Pvt
12246 
12247 PROCEDURE Perform_DML_On_Row (
12248         p_api_version                   IN   NUMBER
12249        ,p_object_id                     IN   NUMBER     DEFAULT NULL
12250        ,p_object_name                   IN   VARCHAR2   DEFAULT NULL
12251        ,p_attr_group_id                 IN   NUMBER     DEFAULT NULL
12252        ,p_application_id                IN   NUMBER     DEFAULT NULL
12253        ,p_attr_group_type               IN   VARCHAR2   DEFAULT NULL
12254        ,p_attr_group_name               IN   VARCHAR2   DEFAULT NULL
12255        ,p_pk_column_name_value_pairs    IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
12256        ,p_class_code_name_value_pairs   IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
12257        ,p_data_level                    IN   VARCHAR2   DEFAULT NULL --R12C
12258        ,p_data_level_name_value_pairs   IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
12259        ,p_extension_id                  IN   NUMBER     DEFAULT NULL
12260        ,p_attr_name_value_pairs         IN   EGO_USER_ATTR_DATA_TABLE
12261        ,p_mode                          IN   VARCHAR2   DEFAULT G_SYNC_MODE
12262        ,p_change_obj                    IN   EGO_USER_ATTR_CHANGE_OBJ DEFAULT NULL
12263        ,p_pending_b_table_name          IN   VARCHAR2   DEFAULT NULL
12264        ,p_pending_tl_table_name         IN   VARCHAR2   DEFAULT NULL
12265        ,p_pending_vl_name               IN   VARCHAR2   DEFAULT NULL
12266        ,p_entity_id                     IN   NUMBER     DEFAULT NULL
12267        ,p_entity_index                  IN   NUMBER     DEFAULT NULL
12268        ,p_entity_code                   IN   VARCHAR2   DEFAULT NULL
12269        ,p_debug_level                   IN   NUMBER     DEFAULT 0
12270        ,p_use_def_vals_on_insert        IN   VARCHAR2   DEFAULT FND_API.G_FALSE
12271        ,p_log_errors                    IN   VARCHAR2   DEFAULT FND_API.G_FALSE
12272        ,p_init_fnd_msg_list             IN   VARCHAR2   DEFAULT FND_API.G_FALSE
12273        ,p_write_to_concurrent_log       IN   VARCHAR2   DEFAULT FND_API.G_FALSE
12274        ,p_add_errors_to_fnd_stack       IN   VARCHAR2   DEFAULT FND_API.G_FALSE
12275        ,p_commit                        IN   VARCHAR2   DEFAULT FND_API.G_FALSE
12276        ,p_bulkload_flag                 IN   VARCHAR2   DEFAULT FND_API.G_FALSE
12277        ,x_return_status                 OUT NOCOPY VARCHAR2
12278        ,x_errorcode                     OUT NOCOPY NUMBER
12279        ,x_msg_count                     OUT NOCOPY NUMBER
12280        ,x_msg_data                      OUT NOCOPY VARCHAR2
12281 ) IS
12282     l_extension_id           NUMBER;
12283     l_mode                   VARCHAR2(10);
12284   BEGIN
12285 
12286     Perform_DML_On_Row(
12287         p_api_version                   => p_api_version
12288        ,p_object_id                     => p_object_id
12289        ,p_object_name                   => p_object_name
12290        ,p_attr_group_id                 => p_attr_group_id
12291        ,p_application_id                => p_application_id
12292        ,p_attr_group_type               => p_attr_group_type
12293        ,p_attr_group_name               => p_attr_group_name
12294        ,p_pk_column_name_value_pairs    => p_pk_column_name_value_pairs
12295        ,p_class_code_name_value_pairs   => p_class_code_name_value_pairs
12296        ,p_data_level                    => p_data_level --R12C
12297        ,p_data_level_name_value_pairs   => p_data_level_name_value_pairs
12298        ,p_extension_id                  => p_extension_id
12299        ,p_attr_name_value_pairs         => p_attr_name_value_pairs
12300        ,p_mode                          => p_mode
12301        ,p_change_obj                    => p_change_obj
12302        ,p_pending_b_table_name          => p_pending_b_table_name
12303        ,p_pending_tl_table_name         => p_pending_tl_table_name
12304        ,p_pending_vl_name               => p_pending_vl_name
12305        ,p_entity_id                     => p_entity_id
12306        ,p_entity_index                  => p_entity_index
12307        ,p_entity_code                   => p_entity_code
12308        ,p_debug_level                   => p_debug_level
12309        ,p_use_def_vals_on_insert        => p_use_def_vals_on_insert
12310        ,p_log_errors                    => p_log_errors
12311        ,p_init_fnd_msg_list             => p_init_fnd_msg_list
12312        ,p_write_to_concurrent_log       => p_write_to_concurrent_log
12313        ,p_add_errors_to_fnd_stack       => p_add_errors_to_fnd_stack
12314        ,p_commit                        => p_commit
12315        ,p_bulkload_flag                 => p_bulkload_flag
12316        ,x_extension_id                  => l_extension_id
12317        ,x_mode                          => l_mode
12318        ,x_return_status                 => x_return_status
12319        ,x_errorcode                     => x_errorcode
12320        ,x_msg_count                     => x_msg_count
12321        ,x_msg_data                      => x_msg_data
12322     );
12323 
12324 END Perform_DML_On_Row;
12325 
12326 ----------------------------------------------------------------------
12327 
12328 /* Overload method with additional parameters x_extension_id, x_mode */
12329 
12330 PROCEDURE Perform_DML_On_Row (
12331         p_api_version                   IN   NUMBER
12332        ,p_object_id                     IN   NUMBER     DEFAULT NULL
12333        ,p_object_name                   IN   VARCHAR2   DEFAULT NULL
12334        ,p_attr_group_id                 IN   NUMBER     DEFAULT NULL
12335        ,p_application_id                IN   NUMBER     DEFAULT NULL
12336        ,p_attr_group_type               IN   VARCHAR2   DEFAULT NULL
12337        ,p_attr_group_name               IN   VARCHAR2   DEFAULT NULL
12338        ,p_pk_column_name_value_pairs    IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
12339        ,p_class_code_name_value_pairs   IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
12340        ,p_data_level                    IN   VARCHAR2   DEFAULT NULL --R12C
12341        ,p_data_level_name_value_pairs   IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
12342        ,p_extension_id                  IN   NUMBER     DEFAULT NULL
12343        ,p_attr_name_value_pairs         IN   EGO_USER_ATTR_DATA_TABLE
12344        ,p_mode                          IN   VARCHAR2   DEFAULT G_SYNC_MODE
12345        ,p_change_obj                    IN   EGO_USER_ATTR_CHANGE_OBJ DEFAULT NULL
12346        ,p_pending_b_table_name          IN   VARCHAR2   DEFAULT NULL
12347        ,p_pending_tl_table_name         IN   VARCHAR2   DEFAULT NULL
12348        ,p_pending_vl_name               IN   VARCHAR2   DEFAULT NULL
12349        ,p_entity_id                     IN   NUMBER     DEFAULT NULL
12350        ,p_entity_index                  IN   NUMBER     DEFAULT NULL
12351        ,p_entity_code                   IN   VARCHAR2   DEFAULT NULL
12352        ,p_debug_level                   IN   NUMBER     DEFAULT 0
12353        ,p_use_def_vals_on_insert        IN   VARCHAR2   DEFAULT FND_API.G_FALSE
12354        ,p_log_errors                    IN   VARCHAR2   DEFAULT FND_API.G_FALSE
12355        ,p_init_fnd_msg_list             IN   VARCHAR2   DEFAULT FND_API.G_FALSE
12356        ,p_write_to_concurrent_log       IN   VARCHAR2   DEFAULT FND_API.G_FALSE
12357        ,p_add_errors_to_fnd_stack       IN   VARCHAR2   DEFAULT FND_API.G_FALSE
12358        ,p_commit                        IN   VARCHAR2   DEFAULT FND_API.G_FALSE
12359        ,p_bulkload_flag                 IN   VARCHAR2   DEFAULT FND_API.G_FALSE
12360        ,x_extension_id                  OUT NOCOPY NUMBER
12361        ,x_mode                          OUT NOCOPY VARCHAR2
12362        ,x_return_status                 OUT NOCOPY VARCHAR2
12363        ,x_errorcode                     OUT NOCOPY NUMBER
12364        ,x_msg_count                     OUT NOCOPY NUMBER
12365        ,x_msg_data                      OUT NOCOPY VARCHAR2
12366 ) IS
12367 
12368     l_api_name               CONSTANT VARCHAR2(30) := 'Perform_DML_On_Row';
12369 
12370     --we don't use l_api_version yet, but eventually we might:
12371     --if we change required parameters, version goes FROM n.x to (n+1).x
12372     --if we change optional parameters, version goes FROM x.n to x.(n+1)
12373     l_api_version            CONSTANT NUMBER := 1.0;
12374 
12375     l_object_id              NUMBER;
12376     l_attr_name_value_pairs   EGO_USER_ATTR_DATA_TABLE;
12377     l_attr_group_metadata_obj EGO_ATTR_GROUP_METADATA_OBJ;
12378     l_ext_table_metadata_obj EGO_EXT_TABLE_METADATA_OBJ;
12379     l_extension_id           NUMBER;
12380     l_mode                   VARCHAR2(10);
12381 
12382 
12383   BEGIN
12384 
12385     Debug_Msg(l_api_name||' starting with data_level = '||p_data_level, 1);
12386 
12387     IF FND_API.To_Boolean(p_commit) THEN
12388       SAVEPOINT Perform_DML_On_Row_PUB;
12389     END IF;
12390 
12391     -- Check for call compatibility
12392     IF NOT FND_API.Compatible_API_Call (l_api_version, p_api_version,
12393                                         l_api_name, G_PKG_NAME)
12394     THEN
12395       RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
12396     END IF;
12397 
12398     IF (FND_API.To_Boolean(p_init_fnd_msg_list)) THEN
12399       ERROR_HANDLER.Initialize();
12400     END IF;
12401     G_SYNC_TO_UPDATE := 'N';
12402     l_object_id := p_object_id;
12403     l_attr_name_value_pairs := p_attr_name_value_pairs;
12404 
12405     Perform_Setup_Operations(
12406         p_object_name                   => p_object_name
12407        ,p_attr_group_id                 => p_attr_group_id
12408        ,p_application_id                => p_application_id
12409        ,p_attr_group_type               => p_attr_group_type
12410        ,p_attr_group_name               => p_attr_group_name
12411        ,p_pk_column_name_value_pairs    => p_pk_column_name_value_pairs
12412        ,p_class_code_name_value_pairs   => p_class_code_name_value_pairs
12413        ,p_data_level                    => p_data_level
12414        ,p_data_level_name_value_pairs   => p_data_level_name_value_pairs
12415        ,p_extension_id                  => p_extension_id
12416        ,p_entity_id                     => p_entity_id
12417        ,p_entity_index                  => p_entity_index
12418        ,p_entity_code                   => p_entity_code
12419        ,p_init_fnd_msg_list             => p_init_fnd_msg_list
12420        ,p_mode                          => p_mode
12421        ,p_change_obj                    => p_change_obj
12422        ,p_pending_b_table_name          => p_pending_b_table_name
12423        ,p_pending_vl_name               => p_pending_vl_name
12424        ,p_add_errors_to_fnd_stack       => p_add_errors_to_fnd_stack
12425        ,p_use_def_vals_on_insert_flag   => FND_API.To_Boolean(p_use_def_vals_on_insert)
12426        ,p_debug_level                   => p_debug_level
12427        ,p_bulkload_flag                 => FND_API.To_Boolean(p_bulkload_flag)
12428        ,px_object_id                    => l_object_id
12429        ,px_attr_name_value_pairs        => l_attr_name_value_pairs
12430        ,x_attr_group_metadata_obj       => l_attr_group_metadata_obj
12431        ,x_ext_table_metadata_obj        => l_ext_table_metadata_obj
12432        ,x_extension_id                  => x_extension_id
12433        ,x_mode                          => x_mode
12434        ,x_return_status                 => x_return_status
12435     );
12436     IF p_mode = 'SYNC'  --doing it for GTIN Attribute Group
12437        AND (l_mode = 'UPDATE'
12438             AND p_attr_group_type in ('EGO_ITEM_GTIN_ATTRS','EGO_ITEM_GTIN_MULTI_ATTRS'))
12439     THEN
12440       G_SYNC_TO_UPDATE := 'Y' ;
12441     END IF;
12442     IF (x_return_status <> FND_API.G_RET_STS_SUCCESS) THEN
12443       RAISE FND_API.G_EXC_ERROR;
12444     END IF;
12445 
12446     l_extension_id := x_extension_id;
12447     l_mode         := x_mode;
12448 
12449     Debug_Msg(l_api_name||' calling Perform_DML_On_Row_Pvt', 1);
12450 
12451     Perform_DML_On_Row_Pvt(
12452         p_api_version                   => p_api_version
12453        ,p_object_id                     => l_object_id
12454        ,p_attr_group_metadata_obj       => l_attr_group_metadata_obj
12455        ,p_ext_table_metadata_obj        => l_ext_table_metadata_obj
12456        ,p_pk_column_name_value_pairs    => p_pk_column_name_value_pairs
12457        ,p_class_code_name_value_pairs   => p_class_code_name_value_pairs
12458        ,p_data_level                    => p_data_level
12459        ,p_data_level_name_value_pairs   => p_data_level_name_value_pairs
12460        ,p_extension_id                  => l_extension_id
12461        ,p_attr_name_value_pairs         => l_attr_name_value_pairs
12462        ,p_mode                          => l_mode
12463        ,p_change_obj                    => p_change_obj
12464        ,p_pending_b_table_name          => p_pending_b_table_name
12465        ,p_pending_tl_table_name         => p_pending_tl_table_name
12466        ,p_entity_id                     => p_entity_id
12467        ,p_entity_index                  => p_entity_index
12468        ,p_entity_code                   => p_entity_code
12469        ,p_commit                        => FND_API.G_FALSE
12470        ,p_bulkload_flag                 => FND_API.To_Boolean(p_bulkload_flag)
12471        ,x_extension_id                  => x_extension_id
12472        ,x_return_status                 => x_return_status
12473     );
12474     IF (x_return_status <> FND_API.G_RET_STS_SUCCESS) THEN
12475       RAISE FND_API.G_EXC_ERROR;
12476     END IF;
12477 
12478     Close_Business_Object_Session(
12479       p_init_error_handler_flag       => (p_debug_level > 0)
12480      ,p_log_errors                    => FND_API.To_Boolean(p_log_errors)
12481      ,p_write_to_concurrent_log       => FND_API.To_Boolean(p_write_to_concurrent_log)
12482     );
12483 
12484     IF FND_API.To_Boolean(p_commit) THEN
12485       COMMIT WORK;
12486     END IF;
12487 
12488     x_return_status := FND_API.G_RET_STS_SUCCESS;
12489 
12490   EXCEPTION
12491     WHEN FND_API.G_EXC_ERROR THEN
12492       Debug_Msg(l_api_name || ' EXCEPTION FND_API.G_EXC_ERROR');
12493       IF FND_API.To_Boolean(p_commit) THEN
12494         ROLLBACK TO Perform_DML_On_Row_PUB;
12495       END IF;
12496       Close_Business_Object_Session(
12497         p_init_error_handler_flag     => (p_debug_level > 0)
12498        ,p_log_errors                  => FND_API.To_Boolean(p_log_errors)
12499        ,p_write_to_concurrent_log     => FND_API.To_Boolean(p_write_to_concurrent_log)
12500       );
12501 
12502       x_msg_count := ERROR_HANDLER.Get_Message_Count();
12503       IF (x_msg_count = 1) THEN
12504         DECLARE
12505           message_list  ERROR_HANDLER.Error_Tbl_Type;
12506         BEGIN
12507           ERROR_HANDLER.Get_Message_List(message_list);
12508           x_msg_data := message_list(message_list.FIRST).message_text;
12509         END;
12510       ELSE
12511         x_msg_data := NULL;
12512       END IF;
12513 
12514     WHEN OTHERS THEN
12515       Debug_Msg(l_api_name || ' EXCEPTION OTHERS '||SQLERRM);
12516       IF FND_API.To_Boolean(p_commit) THEN
12517         ROLLBACK TO Perform_DML_On_Row_PUB;
12518       END IF;
12519       x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
12520 
12521       DECLARE
12522         l_token_table            ERROR_HANDLER.Token_Tbl_Type;
12523       BEGIN
12524         l_token_table(1).TOKEN_NAME := 'PKG_NAME';
12525         l_token_table(1).TOKEN_VALUE := G_PKG_NAME;
12526         l_token_table(2).TOKEN_NAME := 'API_NAME';
12527         l_token_table(2).TOKEN_VALUE := l_api_name;
12528         l_token_table(3).TOKEN_NAME := 'SQL_ERR_MSG';
12529         l_token_table(3).TOKEN_VALUE := SQLERRM;
12530 
12531         ERROR_HANDLER.Add_Error_Message(
12532           p_message_name      => 'EGO_PLSQL_ERR'
12533          ,p_application_id    => 'EGO'
12534          ,p_token_tbl         => l_token_table
12535          ,p_message_type      => FND_API.G_RET_STS_ERROR
12536          ,p_row_identifier    => G_USER_ROW_IDENTIFIER
12537          ,p_entity_id         => p_entity_id
12538          ,p_entity_index      => p_entity_index
12539          ,p_entity_code       => p_entity_code
12540          ,p_addto_fnd_stack   => G_ADD_ERRORS_TO_FND_STACK
12541         );
12542       END;
12543 
12544       Close_Business_Object_Session(
12545         p_init_error_handler_flag     => (p_debug_level > 0)
12546        ,p_log_errors                  => FND_API.To_Boolean(p_log_errors)
12547        ,p_write_to_concurrent_log     => FND_API.To_Boolean(p_write_to_concurrent_log)
12548       );
12549 
12550       x_msg_count := ERROR_HANDLER.Get_Message_Count();
12551 
12552       IF (x_msg_count = 1) THEN
12553         DECLARE
12554           message_list  ERROR_HANDLER.Error_Tbl_Type;
12555         BEGIN
12556           ERROR_HANDLER.Get_Message_List(message_list);
12557           x_msg_data := message_list(message_list.FIRST).message_text;
12558         END;
12559       ELSE
12560         x_msg_data := NULL;
12561       END IF;
12562 
12563 END Perform_DML_On_Row;
12564 
12565 ----------------------------------------------------------------------
12566 -- Public
12567 ----------------------------------------------------------------------
12568 
12569 PROCEDURE Perform_DML_From_Template (
12570         p_api_version                   IN   NUMBER
12571        ,p_template_id                   IN   NUMBER
12572        ,p_object_name                   IN   VARCHAR2
12573        ,p_pk_column_name_value_pairs    IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
12574        ,p_class_code_name_value_pairs   IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
12575        ,p_data_level                    IN   VARCHAR2 DEFAULT NULL
12576        ,p_data_level_name_value_pairs   IN   EGO_COL_NAME_VALUE_PAIR_ARRAY DEFAULT NULL
12577        ,p_attr_group_ids_to_exclude     IN   EGO_NUMBER_TBL_TYPE           DEFAULT NULL
12578        ,p_debug_level                   IN   NUMBER     DEFAULT 0
12579        ,p_init_fnd_msg_list             IN   VARCHAR2   DEFAULT FND_API.G_FALSE
12580        ,p_add_errors_to_fnd_stack       IN   VARCHAR2   DEFAULT FND_API.G_FALSE
12581        ,p_commit                        IN   VARCHAR2   DEFAULT FND_API.G_FALSE
12582        ,x_return_status                 OUT NOCOPY VARCHAR2
12583        ,x_errorcode                     OUT NOCOPY NUMBER
12584        ,x_msg_count                     OUT NOCOPY NUMBER
12585        ,x_msg_data                      OUT NOCOPY VARCHAR2
12586 ) IS
12587 
12588     l_api_name               CONSTANT VARCHAR2(30) := 'Perform_DML_From_Template';
12589 
12590     --we don't use l_api_version yet, but eventually we might:
12591     --if we change required parameters, version goes FROM n.x to (n+1).x
12592     --if we change optional parameters, version goes FROM x.n to x.(n+1)
12593     l_api_version            CONSTANT NUMBER := 1.0;
12594 
12595     l_object_id              NUMBER;
12596     l_ext_table_metadata_obj EGO_EXT_TABLE_METADATA_OBJ;
12597     l_class_code_hierarchy   VARCHAR2(16000);
12598     l_last_loop_index        NUMBER;
12599     l_this_loop_index        NUMBER;
12600     l_decode_index           NUMBER;
12601     l_cc_hierarchy_for_decode VARCHAR2(16100);
12602     l_dynamic_sql            VARCHAR2(30000);
12603     l_prev_loop_ag_id        NUMBER;
12604     l_prev_loop_row_number   NUMBER;
12605     l_at_start_of_ag         BOOLEAN;
12606     l_at_start_of_row        BOOLEAN;
12607     l_row_index              NUMBER := 0;
12608     l_attr_group_metadata_obj EGO_ATTR_GROUP_METADATA_OBJ;
12609     l_attr_metadata_obj      EGO_ATTR_METADATA_OBJ;
12610     l_token_table            ERROR_HANDLER.Token_Tbl_Type;
12611     l_attr_name_value_pairs  EGO_USER_ATTR_DATA_TABLE;
12612     l_extension_id           NUMBER;
12613     l_mode                   VARCHAR2(10);
12614     l_attr_group_ids_to_exclude VARCHAR2(16000);
12615     l_attr_group_id          NUMBER;
12616     l_cursor_id              NUMBER;
12617     l_rows_fetched           NUMBER;
12618     l_cc_data_type           VARCHAR2(8);
12619     l_next_cc                VARCHAR2(150);
12620     l_cc_begin_pos           NUMBER;
12621     l_is_last_cc             BOOLEAN;
12622     --Start Bug 5211171
12623     l_rev_level              VARCHAR2(1000);
12624     l_decode_query           VARCHAR2(32767);
12625     --End Bug 5211171
12626     l_data_level_id          NUMBER;
12627     l_Perform_DML_On_Template_Row     VARCHAR2(1);
12628 
12629     TYPE TEMPL_ATTR_REC IS RECORD (
12630         ATTRIBUTE_GROUP_ID          EGO_TEMPL_ATTRIBUTES.ATTRIBUTE_GROUP_ID%TYPE
12631        ,ATTRIBUTE_ID                EGO_TEMPL_ATTRIBUTES.ATTRIBUTE_ID%TYPE
12632        ,ROW_NUMBER                  EGO_TEMPL_ATTRIBUTES.ROW_NUMBER%TYPE
12633        ,ATTRIBUTE_STRING_VALUE      EGO_TEMPL_ATTRIBUTES.ATTRIBUTE_STRING_VALUE%TYPE
12634        ,ATTRIBUTE_NUMBER_VALUE      EGO_TEMPL_ATTRIBUTES.ATTRIBUTE_NUMBER_VALUE%TYPE
12635        ,ATTRIBUTE_UOM_CODE          EGO_TEMPL_ATTRIBUTES.ATTRIBUTE_UOM_CODE%TYPE
12636        ,ATTRIBUTE_DATE_VALUE        EGO_TEMPL_ATTRIBUTES.ATTRIBUTE_DATE_VALUE%TYPE
12637        ,ATTRIBUTE_TRANSLATED_VALUE  EGO_TEMPL_ATTRIBUTES.ATTRIBUTE_TRANSLATED_VALUE%TYPE
12638                                   );
12639     l_templ_attr_rec         TEMPL_ATTR_REC;
12640 
12641   BEGIN
12642     Debug_Msg(l_api_name||' starting ', 1);
12643 
12644     IF FND_API.To_Boolean(p_commit) THEN
12645       SAVEPOINT Perform_DML_From_Template;
12646     END IF;
12647 
12648     -- Check for call compatibility
12649     IF NOT FND_API.Compatible_API_Call (l_api_version, p_api_version,
12650                                         l_api_name, G_PKG_NAME)
12651     THEN
12652       RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
12653     END IF;
12654 
12655     ------------------------------------------------------------------
12656     -- Initialize the Business Object (flags, error-handling, etc.) --
12657     ------------------------------------------------------------------
12658     Set_Up_Business_Object_Session(
12659         p_bulkload_flag                => FALSE
12660        ,p_debug_level                  => p_debug_level
12661        ,p_init_error_handler_flag      => TRUE
12662        ,p_object_name                  => p_object_name
12663        ,p_pk_column_name_value_pairs   => p_pk_column_name_value_pairs
12664        ,p_class_code_name_value_pairs  => p_class_code_name_value_pairs
12665        ,p_init_fnd_msg_list            => p_init_fnd_msg_list
12666        ,p_add_errors_to_fnd_stack      => p_add_errors_to_fnd_stack
12667        ,p_default_user_row_identifier  => l_row_index
12668        ,x_return_status                => x_return_status
12669     );
12670     IF (x_return_status <> FND_API.G_RET_STS_SUCCESS) THEN
12671       RAISE FND_API.G_EXC_ERROR;
12672     END IF;
12673 
12674     ----------------------------------------------
12675     -- Get the Object ID and Ext Table metadata --
12676     ----------------------------------------------
12677     l_object_id := Get_Object_Id_From_Name(p_object_name);
12678 
12679     l_ext_table_metadata_obj := EGO_USER_ATTRS_COMMON_PVT.Get_Ext_Table_Metadata(l_object_id);
12680 
12681     -----------------------------------------------------------------
12682     -- Build a DECODE string for the Classification Code Hierarchy --
12683     -----------------------------------------------------------------
12684     WHILE (INSTR(l_class_code_hierarchy, ',', (l_last_loop_index + 1)) > 0)
12685     LOOP
12686 
12687       l_this_loop_index := INSTR(l_class_code_hierarchy, ',', (l_last_loop_index + 1));
12688       l_cc_hierarchy_for_decode := l_cc_hierarchy_for_decode ||
12689                                    SUBSTR(l_class_code_hierarchy
12690                                          ,l_last_loop_index
12691                                          ,(l_this_loop_index - l_last_loop_index)) ||
12692                                    ', ' || l_decode_index;
12693 
12694       l_decode_index := l_decode_index + 1;
12695       l_last_loop_index := l_this_loop_index;
12696 
12697     END LOOP;
12698 
12699     l_cc_hierarchy_for_decode := l_cc_hierarchy_for_decode ||
12700           SUBSTR(l_class_code_hierarchy,l_last_loop_index) ||
12701           ', ' || l_decode_index;
12702 
12703     Debug_Msg(l_api_name||' l_cc_hierarchy_for_decode '|| l_cc_hierarchy_for_decode, 1);
12704     -----------------------------------------------------------------
12705     -- Build a list of attribute group ids to exclude from the     --
12706     -- query useful for applying a template while ignoring         --
12707     -- attribute groups under change control (part of bug 3781216) --
12708     -----------------------------------------------------------------
12709     l_attr_group_ids_to_exclude := '';
12710     IF (p_attr_group_ids_to_exclude IS NOT NULL AND
12711         p_attr_group_ids_to_exclude.COUNT > 0) THEN
12712 
12713       l_attr_group_ids_to_exclude := ' AND ETA_OUTER.ATTRIBUTE_GROUP_ID NOT IN ( ';
12714 
12715       FOR i IN p_attr_group_ids_to_exclude.FIRST .. p_attr_group_ids_to_exclude.LAST
12716       LOOP
12717         l_attr_group_id := p_attr_group_ids_to_exclude(i);
12718         l_attr_group_ids_to_exclude := l_attr_group_ids_to_exclude || l_attr_group_id || ',';
12719       END LOOP;
12720 
12721       -- Get rid of trailing comma
12722       l_attr_group_ids_to_exclude := RTRIM(l_attr_group_ids_to_exclude, ',') || ' ) ';
12723 
12724     END IF;
12725 
12726     -----------------------------------------------------------------
12727     -- Build a Dynamic SQL query to get all Attributes for which   --
12728     -- the passed-in Template has enabled values in the current    --
12729     -- Classification Code hierarchy (the query returns the lowest --
12730     -- level values, thus implementing Template value inheritance  --
12731     -- and overriding)                                             --
12732     -----------------------------------------------------------------
12733     l_cursor_id := DBMS_SQL.Open_Cursor;
12734     Init();
12735     FND_DSQL.Add_Text(
12736       'SELECT ETA_OUTER.ATTRIBUTE_GROUP_ID,' ||
12737             ' ETA_OUTER.ATTRIBUTE_ID,' ||
12738             ' ETA_OUTER.ROW_NUMBER,' ||
12739             ' ETA_OUTER.ATTRIBUTE_STRING_VALUE,' ||
12740             ' ETA_OUTER.ATTRIBUTE_NUMBER_VALUE,' ||
12741             ' ETA_OUTER.ATTRIBUTE_UOM_CODE,' ||
12742             ' ETA_OUTER.ATTRIBUTE_DATE_VALUE,' ||
12743             ' ETA_OUTER.ATTRIBUTE_TRANSLATED_VALUE' ||
12744        ' FROM EGO_TEMPL_ATTRIBUTES   ETA_OUTER'
12745                      );
12746     IF p_data_level IS NOT NULL THEN
12747       FND_DSQL.Add_Text(
12748            ' , EGO_DATA_LEVEL_B DL ' ||
12749       ' WHERE DL.data_level_name = '
12750                        );
12751       Add_Bind(p_value => p_data_level);
12752       FND_DSQL.Add_Text(
12753         ' AND DL.data_level_id = ETA_OUTER.data_level_id '
12754                        );
12755     ELSE
12756       FND_DSQL.Add_Text(' WHERE 1 = 1');
12757     END IF;
12758     FND_DSQL.Add_Text(' AND ETA_OUTER.TEMPLATE_ID = ');
12759     Add_Bind(p_value => p_template_id);
12760     FND_DSQL.Add_Text(' AND ETA_OUTER.CLASSIFICATION_CODE IN (');
12761 
12762     -- we assume here that the calling procedure has passed in some class codes
12763     l_class_code_hierarchy := EGO_USER_ATTRS_COMMON_PVT.Get_List_For_Table_Cols(
12764                                 l_ext_table_metadata_obj.class_code_metadata
12765                                ,p_class_code_name_value_pairs
12766                                ,'VALUES_ALL_CC'
12767                                ,TRUE
12768                               );
12769     Debug_Msg(l_api_name||' l_class_code_hierarchy '|| l_class_code_hierarchy, 1);
12770 
12771     FND_DSQL.Add_Text(')' ||
12772         ' AND ETA_OUTER.ENABLED_FLAG = ''Y''' ||
12773         l_attr_group_ids_to_exclude||
12774         ' AND (ETA_OUTER.TEMPLATE_ID' ||
12775             ' ,ETA_OUTER.ATTRIBUTE_GROUP_ID' ||
12776             ' ,ETA_OUTER.ATTRIBUTE_ID' ||
12777             ' ,ETA_OUTER.ROW_NUMBER' ||
12778             ' ,DECODE(ETA_OUTER.CLASSIFICATION_CODE, ');
12779 
12780     l_cc_data_type := l_ext_table_metadata_obj.class_code_metadata(l_ext_table_metadata_obj.class_code_metadata.FIRST).DATA_TYPE;
12781     -----------------------------------------------------------------
12782     -- Build a DECODE string for the Classification Code Hierarchy --
12783     -----------------------------------------------------------------
12784     l_last_loop_index := 1;
12785     l_decode_index := 0;
12786     l_is_last_cc := FALSE;
12787     LOOP
12788 
12789       l_this_loop_index := INSTR(l_class_code_hierarchy, ',', l_last_loop_index);
12790 
12791       IF (l_this_loop_index = 0) THEN
12792         l_this_loop_index := LENGTH(l_class_code_hierarchy) + 1;
12793         l_is_last_cc := TRUE;
12794       END IF;
12795       l_next_cc := SUBSTR(l_class_code_hierarchy
12796                               ,l_last_loop_index
12797                               ,(l_this_loop_index - l_last_loop_index));
12798       IF (l_cc_data_type = 'NUMBER' OR l_cc_data_type = 'INTEGER') THEN
12799         Add_Bind(p_value => TO_NUMBER(l_next_cc));
12800       ELSIF (l_cc_data_type = 'VARCHAR' OR l_cc_data_type = 'VARCHAR2') THEN
12801         l_cc_begin_pos := INSTR(l_next_cc, '''') + 1;
12802         Add_Bind(p_value => SUBSTR(l_next_cc,
12803                                  l_cc_begin_pos,
12804                                  INSTR(l_next_cc, '''', -1) - l_cc_begin_pos));
12805       END IF;
12806       FND_DSQL.Add_Text(', ' || l_decode_index);
12807 
12808       EXIT WHEN (l_is_last_cc);
12809 
12810       FND_DSQL.Add_Text(', ');
12811       l_decode_index := l_decode_index + 1;
12812       l_last_loop_index := l_this_loop_index + 1;
12813 
12814     END LOOP;
12815 
12816     FND_DSQL.Add_Text('))' ||
12817             ' IN (SELECT ETA.TEMPLATE_ID' ||
12818                       ' ,ETA.ATTRIBUTE_GROUP_ID' ||
12819                       ' ,ETA.ATTRIBUTE_ID' ||
12820                       ' ,ETA.ROW_NUMBER' ||
12821                       ' ,MIN(DECODE(ETA.CLASSIFICATION_CODE, ');
12822 
12823     -----------------------------------------------------------------
12824     -- Build a DECODE string for the Classification Code Hierarchy --
12825     -----------------------------------------------------------------
12826     l_last_loop_index := 1;
12827     l_decode_index := 0;
12828     l_is_last_cc := FALSE;
12829     LOOP
12830 
12831       l_this_loop_index := INSTR(l_class_code_hierarchy, ',', l_last_loop_index);
12832 
12833       IF(l_this_loop_index = 0) THEN
12834         l_this_loop_index := LENGTH(l_class_code_hierarchy) + 1;
12835         l_is_last_cc := TRUE;
12836       END IF;
12837       l_next_cc := SUBSTR(l_class_code_hierarchy
12838                          ,l_last_loop_index
12839                          ,(l_this_loop_index - l_last_loop_index)
12840                          );
12841       IF (l_cc_data_type = 'NUMBER' OR l_cc_data_type = 'INTEGER') THEN
12842         Add_Bind(p_value => TO_NUMBER(l_next_cc));
12843       ELSIF (l_cc_data_type = 'VARCHAR' OR l_cc_data_type = 'VARCHAR2') THEN
12844         l_cc_begin_pos := INSTR(l_next_cc, '''') + 1;
12845         Add_Bind(p_value => SUBSTR(l_next_cc,
12846                                    l_cc_begin_pos,
12847                                    INSTR(l_next_cc, '''', -1) - l_cc_begin_pos));
12848       END IF;
12849       FND_DSQL.Add_Text(', ' || l_decode_index);
12850 
12851       EXIT WHEN (l_is_last_cc);
12852 
12853       FND_DSQL.Add_Text(', ');
12854       l_decode_index := l_decode_index + 1;
12855       l_last_loop_index := l_this_loop_index + 1;
12856 
12857     END LOOP;
12858 
12859     FND_DSQL.Add_Text(')) STEPS_ABOVE_CURR' ||
12860                   ' FROM EGO_TEMPL_ATTRIBUTES ETA' ||
12861                  ' WHERE ETA.TEMPLATE_ID = ');
12862     Add_Bind(p_value => p_template_id);
12863     FND_DSQL.Add_Text(
12864                    ' AND ETA.CLASSIFICATION_CODE IN (');
12865 
12866     l_class_code_hierarchy := EGO_USER_ATTRS_COMMON_PVT.Get_List_For_Table_Cols(
12867                                     l_ext_table_metadata_obj.class_code_metadata
12868                                    ,p_class_code_name_value_pairs
12869                                    ,'VALUES_ALL_CC'
12870                                    ,TRUE
12871                               );
12872 
12873     FND_DSQL.Add_Text(')' ||
12874                  ' GROUP BY ETA.TEMPLATE_ID, ETA.ATTRIBUTE_GROUP_ID, ETA.ATTRIBUTE_ID, ETA.ROW_NUMBER)' ||
12875       ' ORDER BY ETA_OUTER.ATTRIBUTE_GROUP_ID, ETA_OUTER.ROW_NUMBER');
12876 
12877     -----------------------------------------------------------------------------------
12878     -- Parse and execute the query, and associate the output columns with our record --
12879     -----------------------------------------------------------------------------------
12880     Debug_Msg(l_api_name||' complete query '|| FND_DSQL.Get_Text(), 1);
12881     Debug_Msg(l_api_name||' using binds template_id: '||p_template_id||' , '||
12882               ' class code: '||l_class_code_hierarchy
12883               , 1);
12884 
12885     DBMS_SQL.Parse(l_cursor_id, FND_DSQL.Get_Text(), DBMS_SQL.Native);
12886     FND_DSQL.Set_Cursor(l_cursor_id);
12887     FND_DSQL.Do_Binds();
12888     DBMS_SQL.Define_Column(l_cursor_id, 1, l_templ_attr_rec.ATTRIBUTE_GROUP_ID);
12889     DBMS_SQL.Define_Column(l_cursor_id, 2, l_templ_attr_rec.ATTRIBUTE_ID);
12890     DBMS_SQL.Define_Column(l_cursor_id, 3, l_templ_attr_rec.ROW_NUMBER);
12891     DBMS_SQL.Define_Column(l_cursor_id, 4, l_templ_attr_rec.ATTRIBUTE_STRING_VALUE, 150);
12892     DBMS_SQL.Define_Column(l_cursor_id, 5, l_templ_attr_rec.ATTRIBUTE_NUMBER_VALUE);
12893     DBMS_SQL.Define_Column(l_cursor_id, 6, l_templ_attr_rec.ATTRIBUTE_UOM_CODE, 3);
12894     DBMS_SQL.Define_Column(l_cursor_id, 7, l_templ_attr_rec.ATTRIBUTE_DATE_VALUE);
12895     DBMS_SQL.Define_Column(l_cursor_id, 8, l_templ_attr_rec.ATTRIBUTE_TRANSLATED_VALUE, 1000);
12896     l_rows_fetched := DBMS_SQL.Execute(l_cursor_id);
12897 
12898     WHILE (DBMS_SQL.Fetch_Rows(l_cursor_id) > 0)
12899     LOOP
12900 
12901       DBMS_SQL.Column_Value(l_cursor_id, 1, l_templ_attr_rec.ATTRIBUTE_GROUP_ID);
12902       DBMS_SQL.Column_Value(l_cursor_id, 2, l_templ_attr_rec.ATTRIBUTE_ID);
12903       DBMS_SQL.Column_Value(l_cursor_id, 3, l_templ_attr_rec.ROW_NUMBER);
12904       DBMS_SQL.Column_Value(l_cursor_id, 4, l_templ_attr_rec.ATTRIBUTE_STRING_VALUE);
12905       DBMS_SQL.Column_Value(l_cursor_id, 5, l_templ_attr_rec.ATTRIBUTE_NUMBER_VALUE);
12906       DBMS_SQL.Column_Value(l_cursor_id, 6, l_templ_attr_rec.ATTRIBUTE_UOM_CODE);
12907       DBMS_SQL.Column_Value(l_cursor_id, 7, l_templ_attr_rec.ATTRIBUTE_DATE_VALUE);
12908       DBMS_SQL.Column_Value(l_cursor_id, 8, l_templ_attr_rec.ATTRIBUTE_TRANSLATED_VALUE);
12909 
12910       Debug_Msg(l_api_name ||' processing AG '||l_templ_attr_rec.ATTRIBUTE_GROUP_ID,1);
12911       -----------------------------------------------------------------------
12912       -- Find out whether we're at the beginning of an Attr Group or a row --
12913       -----------------------------------------------------------------------
12914       l_at_start_of_ag := (l_prev_loop_ag_id IS NULL OR
12915                            l_templ_attr_rec.ATTRIBUTE_GROUP_ID <> l_prev_loop_ag_id);
12916 
12917       ----------------------------------------------------------
12918       -- If we switched Attr Groups, we switched rows as well --
12919       ----------------------------------------------------------
12920       l_at_start_of_row := (l_at_start_of_ag OR
12921                             l_prev_loop_row_number IS NULL OR
12922                             l_templ_attr_rec.ROW_NUMBER <> l_prev_loop_row_number);
12923 
12924       -------------------------------------------------------------
12925       -- If we are at the start of the first row, initialize our --
12926       -- name/value pair array.  Otherwise, we want to process   --
12927       -- the data we've collected over the previous few loops    --
12928       -------------------------------------------------------------
12929       IF (l_at_start_of_row) THEN
12930 
12931         l_row_index := l_row_index + 1;
12932 
12933         IF (l_prev_loop_row_number IS NULL) THEN
12934           l_attr_name_value_pairs := EGO_USER_ATTR_DATA_TABLE();
12935         ELSE
12936 
12937           --Start Bug 5211171
12938 /***
12939 
12940           Debug_Msg(l_api_name||' ATTR_GROUP_ID '||l_attr_group_metadata_obj.ATTR_GROUP_ID, 1);
12941           Debug_Msg(l_api_name||' CLASS_CODE_HIERARCHY OBTAINED '||l_class_code_hierarchy, 1);
12942           Debug_Msg(l_api_name||' OBJECT_NAME '||p_object_name, 1);
12943           Debug_Msg(l_api_name||' OBJECT_ID '||l_object_id, 1);
12944 
12945           l_decode_query := 'SELECT DECODE(ATTRIBUTE2, 1, ATTRIBUTE3, 2, ATTRIBUTE5,3, ATTRIBUTE7,''NONE'') ';
12946           l_decode_query := l_decode_query||' FROM FND_LOOKUP_VALUES ';
12947           l_decode_query := l_decode_query||' WHERE LOOKUP_TYPE = ''EGO_EF_DATA_LEVEL'' ';
12948           l_decode_query := l_decode_query||' AND LANGUAGE = USERENV(''LANG'') ';
12949           l_decode_query := l_decode_query||' AND LOOKUP_CODE = (SELECT DATA_LEVEL ';
12950           l_decode_query := l_decode_query||' FROM EGO_OBJ_AG_ASSOCS_B ';
12951           l_decode_query := l_decode_query||' WHERE OBJECT_ID  = '||l_object_id;
12952           l_decode_query := l_decode_query||' AND ATTR_GROUP_ID = '||l_attr_group_metadata_obj.ATTR_GROUP_ID;
12953           l_decode_query := l_decode_query||' AND ROWNUM = 1 ';
12954           l_decode_query := l_decode_query||' AND CLASSIFICATION_CODE IN ('||l_class_code_hierarchy;
12955           l_decode_query := l_decode_query||'))';
12956 
12957           EXECUTE IMMEDIATE l_decode_query INTO l_rev_level;
12958           Debug_Msg(l_api_name||' DECODE QUERY  :'||l_decode_query, 1);
12959 
12960           Debug_Msg(l_api_name||' OBTAINED REVISION LEVEL,'||l_rev_level, 1);
12961 
12962           IF ( (l_rev_level = 'NONE' AND p_data_level_name_value_pairs IS NULL)
12963                OR
12964                (l_rev_level <> 'NONE' AND p_data_level_name_value_pairs IS NOT NULL )
12965              ) THEN
12966 
12967 ***/
12968 
12969           Is_Name_Value_Pairs_Valid
12970              ( p_attr_group_id               => l_attr_group_metadata_obj.attr_group_id
12971               ,p_data_level_name             => p_data_level
12972               ,p_class_code_hierarchy        => l_class_code_hierarchy
12973               ,p_data_level_name_value_pairs => p_data_level_name_value_pairs
12974               ,x_data_level_id               => l_data_level_id
12975               ,x_name_value_pair_valid       => l_Perform_DML_On_Template_Row
12976              );
12977 
12978           IF FND_API.TO_BOOLEAN(l_Perform_DML_On_Template_Row) THEN
12979             Debug_Msg(l_api_name ||' CALLING Perform_DML_On_Template_Row in the loop ',1);
12980             Perform_DML_On_Template_Row(
12981                   p_object_id                    => l_object_id
12982                   ,p_attr_group_metadata_obj     => l_attr_group_metadata_obj
12983                   ,p_ext_table_metadata_obj      => l_ext_table_metadata_obj
12984                   ,p_pk_column_name_value_pairs  => p_pk_column_name_value_pairs
12985                   ,p_class_code_name_value_pairs => p_class_code_name_value_pairs
12986                   ,p_data_level                  => p_data_level
12987                   ,p_data_level_name_value_pairs => p_data_level_name_value_pairs
12988                   ,px_attr_name_value_pairs      => l_attr_name_value_pairs
12989                   ,p_commit                      => FND_API.G_FALSE -- we don't commit until the end
12990                   );
12991           ELSE
12992             Debug_Msg(l_api_name ||' no need to call Perform_DML_On_Template_Row in the loop ',1);
12993           END IF;
12994          --End Bug 5211171
12995 
12996           ----------------------------------------------
12997           -- After processing this row, clear out the --
12998           -- name/value pairs array for the next row  --
12999           ----------------------------------------------
13000           l_attr_name_value_pairs.DELETE();
13001         END IF;
13002 
13003         ----------------------------------------------------------
13004         -- If we switched Attr Groups as well as rows, we fetch --
13005         -- l_attr_group_metadata_obj for the new Attr Group     --
13006         ----------------------------------------------------------
13007         IF (l_at_start_of_ag) THEN
13008 
13009           l_attr_group_metadata_obj := EGO_USER_ATTRS_COMMON_PVT.Get_Attr_Group_Metadata(
13010                                          p_attr_group_id => l_templ_attr_rec.ATTRIBUTE_GROUP_ID
13011                                        );
13012 
13013           IF (l_attr_group_metadata_obj IS NULL) THEN
13014 
13015             l_token_table(1).TOKEN_NAME := 'AG_ID';
13016             l_token_table(1).TOKEN_VALUE := l_templ_attr_rec.ATTRIBUTE_GROUP_ID;
13017 
13018             ERROR_HANDLER.Add_Error_Message(
13019               p_message_name      => 'EGO_EF_ATTR_GROUP_ID_NOT_FOUND'
13020              ,p_application_id    => 'EGO'
13021              ,p_token_tbl         => l_token_table
13022              ,p_message_type      => FND_API.G_RET_STS_ERROR
13023              ,p_row_identifier    => l_row_index + 1 --we haven't incremented yet
13024              ,p_addto_fnd_stack   => G_ADD_ERRORS_TO_FND_STACK
13025             );
13026 
13027             RAISE FND_API.G_EXC_ERROR;
13028           END IF;
13029         END IF;
13030       END IF;
13031 
13032       l_attr_metadata_obj := EGO_USER_ATTRS_COMMON_PVT.Find_Metadata_For_Attr(
13033                                p_attr_metadata_table => l_attr_group_metadata_obj.attr_metadata_table
13034                               ,p_attr_id             => l_templ_attr_rec.ATTRIBUTE_ID
13035                              );
13036 
13037       IF (l_attr_metadata_obj IS NULL OR
13038           l_attr_metadata_obj.ATTR_NAME IS NULL) THEN
13039 
13040         l_token_table(1).TOKEN_NAME := 'ATTR_ID';
13041         l_token_table(1).TOKEN_VALUE := l_templ_attr_rec.ATTRIBUTE_ID;
13042 
13043         ERROR_HANDLER.Add_Error_Message(
13044           p_message_name      => 'EGO_EF_ATTR_ID_NOT_FOUND'
13045          ,p_application_id    => 'EGO'
13046          ,p_token_tbl         => l_token_table
13047          ,p_message_type      => FND_API.G_RET_STS_ERROR
13048          ,p_row_identifier    => l_row_index + 1 --we haven't incremented yet
13049          ,p_addto_fnd_stack   => G_ADD_ERRORS_TO_FND_STACK
13050         );
13051 
13052         RAISE FND_API.G_EXC_ERROR;
13053       END IF;
13054 
13055       ------------------------------------------------------------------
13056       -- Whether or not we're at the start of a row, we've fetched a  --
13057       -- record, so we load its values into the name/value pair array --
13058       -- NOTE: we will have display values instead of internal values --
13059       -- for Attributes with Value Sets that use bind values, in such --
13060       -- cases, we store the Template record value in ATTR_DISP_VALUE --
13061       -- instead of ATTR_VALUE_STR, and we will later convert it into --
13062       -- its corresponding internal value before validating the row   --
13063       ------------------------------------------------------------------
13064       l_attr_name_value_pairs.EXTEND();
13065       IF (l_attr_metadata_obj.VS_BIND_VALUES_CODE IS NOT NULL AND
13066           l_attr_metadata_obj.VS_BIND_VALUES_CODE <> 'N') THEN
13067 
13068         l_attr_name_value_pairs(l_attr_name_value_pairs.LAST) :=
13069           EGO_USER_ATTR_DATA_OBJ(
13070             l_row_index
13071            ,l_attr_metadata_obj.ATTR_NAME
13072            ,null -- ATTR_VALUE_STR
13073            ,l_templ_attr_rec.ATTRIBUTE_NUMBER_VALUE
13074            ,l_templ_attr_rec.ATTRIBUTE_DATE_VALUE
13075            ,NVL(l_templ_attr_rec.ATTRIBUTE_STRING_VALUE,l_templ_attr_rec.ATTRIBUTE_TRANSLATED_VALUE)
13076            ,l_templ_attr_rec.ATTRIBUTE_UOM_CODE
13077            ,l_row_index
13078           );
13079 
13080       ELSE
13081 
13082         l_attr_name_value_pairs(l_attr_name_value_pairs.LAST) :=
13083           EGO_USER_ATTR_DATA_OBJ(
13084             l_row_index
13085            ,l_attr_metadata_obj.ATTR_NAME
13086            ,NVL(l_templ_attr_rec.ATTRIBUTE_STRING_VALUE,l_templ_attr_rec.ATTRIBUTE_TRANSLATED_VALUE)
13087            ,l_templ_attr_rec.ATTRIBUTE_NUMBER_VALUE
13088            ,l_templ_attr_rec.ATTRIBUTE_DATE_VALUE
13089            ,null -- ATTR_DISP_VALUE
13090            ,l_templ_attr_rec.ATTRIBUTE_UOM_CODE
13091            ,l_row_index
13092           );
13093 
13094       END IF;
13095 
13096       --------------------------------------------------
13097       -- Now we update these values for the next loop --
13098       --------------------------------------------------
13099       l_prev_loop_ag_id := l_templ_attr_rec.ATTRIBUTE_GROUP_ID;
13100       l_prev_loop_row_number := l_templ_attr_rec.ROW_NUMBER;
13101 
13102     END LOOP;
13103 
13104     ------------------------------------------------------------------------
13105     -- Now we process the last row (i.e., the row whose values we've been --
13106     -- collecting in the last few loops but that we've not yet processed) --
13107     ------------------------------------------------------------------------
13108     l_row_index := l_row_index + 1;
13109 
13110     IF (l_prev_loop_row_number IS NOT NULL) THEN
13111       --Start Bug 5211171
13112 /***
13113       l_decode_query := 'SELECT DECODE(ATTRIBUTE2, 1, ATTRIBUTE3, 2, ATTRIBUTE5,3, ATTRIBUTE7,''NONE'') ';
13114       l_decode_query := l_decode_query||' FROM FND_LOOKUP_VALUES ';
13115       l_decode_query := l_decode_query||' WHERE LOOKUP_TYPE = ''EGO_EF_DATA_LEVEL'' ';
13116       l_decode_query := l_decode_query||' AND LANGUAGE = USERENV(''LANG'') ';
13117       l_decode_query := l_decode_query||' AND LOOKUP_CODE = (SELECT DATA_LEVEL ';
13118       l_decode_query := l_decode_query||' FROM EGO_OBJ_AG_ASSOCS_B ';
13119       l_decode_query := l_decode_query||' WHERE OBJECT_ID  = '||l_object_id;
13120       l_decode_query := l_decode_query||' AND ATTR_GROUP_ID = '||l_prev_loop_ag_id;
13121       l_decode_query := l_decode_query||' AND ROWNUM = 1 ';
13122       l_decode_query := l_decode_query||' AND CLASSIFICATION_CODE IN ('||l_class_code_hierarchy;
13123       l_decode_query := l_decode_query||'))';
13124 
13125       EXECUTE IMMEDIATE l_decode_query INTO l_rev_level;
13126 
13127       Debug_Msg(l_api_name||' OUT OF LOOP REVISION_LEVEL OBTAINED :'||l_rev_level,1);
13128 ***/
13129       Is_Name_Value_Pairs_Valid
13130          ( p_attr_group_id               => l_prev_loop_ag_id
13131           ,p_data_level_name             => p_data_level
13132           ,p_class_code_hierarchy        => l_class_code_hierarchy
13133           ,p_data_level_name_value_pairs => p_data_level_name_value_pairs
13134           ,x_data_level_id               => l_data_level_id
13135           ,x_name_value_pair_valid       => l_Perform_DML_On_Template_Row
13136          );
13137 
13138       IF FND_API.TO_BOOLEAN(l_Perform_DML_On_Template_Row) THEN
13139         Debug_Msg(l_api_name || ' CALLING Perform_DML_On_Template_Row for data level out of loop',1);
13140         Perform_DML_On_Template_Row(
13141             p_object_id                     => l_object_id
13142            ,p_attr_group_metadata_obj       => l_attr_group_metadata_obj
13143            ,p_ext_table_metadata_obj        => l_ext_table_metadata_obj
13144            ,p_pk_column_name_value_pairs    => p_pk_column_name_value_pairs
13145            ,p_class_code_name_value_pairs   => p_class_code_name_value_pairs
13146            ,p_data_level                    => p_data_level
13147            ,p_data_level_name_value_pairs   => p_data_level_name_value_pairs
13148            ,px_attr_name_value_pairs        => l_attr_name_value_pairs
13149            ,p_commit                        => FND_API.G_FALSE -- we don't commit until the end
13150           );
13151       ELSE
13152         Debug_Msg(l_api_name || ' no need to call Perform_DML_On_Template_Row for data level out of loop',1);
13153       END IF;
13154       --End Bug 5211171
13155 
13156     END IF;
13157 
13158     IF FND_API.To_Boolean(p_commit) THEN
13159       COMMIT WORK;
13160     END IF;
13161 
13162     x_return_status := FND_API.G_RET_STS_SUCCESS;
13163     Debug_Msg(l_api_name||' done ',1);
13164     G_ENABLE_DEBUG := FALSE;
13165 
13166   EXCEPTION
13167     WHEN FND_API.G_EXC_ERROR THEN
13168       Debug_Msg(l_api_name || ' EXCEPTION FND_API.G_EXC_ERROR');
13169       IF FND_API.To_Boolean(p_commit) THEN
13170         ROLLBACK TO Perform_DML_From_Template;
13171       END IF;
13172       x_return_status := FND_API.G_RET_STS_ERROR;
13173 
13174       x_msg_count := ERROR_HANDLER.Get_Message_Count();
13175 
13176       IF (x_msg_count > 0) THEN
13177 
13178         ------------------------------------------------------
13179         -- We log all errors we got as we close our session --
13180         ------------------------------------------------------
13181         Close_Business_Object_Session(
13182           p_init_error_handler_flag       => FALSE
13183          ,p_log_errors                    => TRUE
13184          ,p_write_to_concurrent_log       => FALSE
13185         );
13186 
13187         IF (x_msg_count = 1) THEN
13188           DECLARE
13189             message_list  ERROR_HANDLER.Error_Tbl_Type;
13190           BEGIN
13191             ERROR_HANDLER.Get_Message_List(message_list);
13192             x_msg_data := message_list(message_list.FIRST).message_text;
13193           END;
13194         ELSE
13195           x_msg_data := NULL;
13196         END IF;
13197       END IF;
13198 
13199     WHEN OTHERS THEN
13200       Debug_Msg(l_api_name || ' EXCEPTION OTHERS'||SQLERRM);
13201       IF FND_API.To_Boolean(p_commit) THEN
13202         ROLLBACK TO Perform_DML_From_Template;
13203       END IF;
13204       x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
13205 
13206       l_token_table(1).TOKEN_NAME := 'PKG_NAME';
13207       l_token_table(1).TOKEN_VALUE := G_PKG_NAME;
13208       l_token_table(2).TOKEN_NAME := 'API_NAME';
13209       l_token_table(2).TOKEN_VALUE := l_api_name;
13210       l_token_table(3).TOKEN_NAME := 'SQL_ERR_MSG';
13211       l_token_table(3).TOKEN_VALUE := SQLERRM;
13212 
13213       ERROR_HANDLER.Add_Error_Message(
13214         p_message_name        => 'EGO_PLSQL_ERR'
13215        ,p_application_id      => 'EGO'
13216        ,p_token_tbl           => l_token_table
13217        ,p_message_type        => FND_API.G_RET_STS_ERROR
13218        ,p_row_identifier      => l_row_index
13219        ,p_addto_fnd_stack     => G_ADD_ERRORS_TO_FND_STACK
13220       );
13221 
13222       x_msg_count := ERROR_HANDLER.Get_Message_Count();
13223 
13224       ------------------------------------------------------
13225       -- We log all errors we got as we close our session --
13226       ------------------------------------------------------
13227       Close_Business_Object_Session(
13228         p_init_error_handler_flag       => FALSE
13229        ,p_log_errors                    => TRUE
13230        ,p_write_to_concurrent_log       => FALSE
13231       );
13232 
13233       IF (x_msg_count = 1) THEN
13234         DECLARE
13235           message_list  ERROR_HANDLER.Error_Tbl_Type;
13236         BEGIN
13237           ERROR_HANDLER.Get_Message_List(message_list);
13238           x_msg_data := message_list(message_list.FIRST).message_text;
13239         END;
13240       ELSE
13241         x_msg_data := NULL;
13242       END IF;
13243 
13244 END Perform_DML_From_Template;
13245 
13246 ----------------------------------------------------------------------
13247 
13248 PROCEDURE Copy_User_Attrs_Data (
13249         p_api_version                   IN   NUMBER
13250        ,p_application_id                IN   NUMBER
13251        ,p_object_id                     IN   NUMBER     DEFAULT NULL
13252        ,p_object_name                   IN   VARCHAR2   DEFAULT NULL
13253        ,p_old_pk_col_value_pairs        IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
13254        ,p_old_data_level_id             IN   NUMBER   DEFAULT  NULL
13255        ,p_old_dtlevel_col_value_pairs   IN   EGO_COL_NAME_VALUE_PAIR_ARRAY DEFAULT NULL
13256        ,p_new_pk_col_value_pairs        IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
13257        ,p_new_data_level_id             IN   NUMBER   DEFAULT  NULL
13258        ,p_new_dtlevel_col_value_pairs   IN   EGO_COL_NAME_VALUE_PAIR_ARRAY DEFAULT NULL
13259        ,p_new_cc_col_value_pairs        IN   EGO_COL_NAME_VALUE_PAIR_ARRAY DEFAULT NULL
13260        ,p_attr_group_list               IN   VARCHAR2   DEFAULT  NULL
13261        ,p_init_error_handler            IN   VARCHAR2   DEFAULT FND_API.G_FALSE
13262        ,p_init_fnd_msg_list             IN   VARCHAR2   DEFAULT FND_API.G_FALSE
13263        ,p_add_errors_to_fnd_stack       IN   VARCHAR2   DEFAULT FND_API.G_FALSE
13264        ,p_commit                        IN   VARCHAR2   DEFAULT FND_API.G_FALSE
13265        ,x_return_status                 OUT NOCOPY VARCHAR2
13266        ,x_errorcode                     OUT NOCOPY NUMBER
13267        ,x_msg_count                     OUT NOCOPY NUMBER
13268        ,x_msg_data                      OUT NOCOPY VARCHAR2
13269 ) IS
13270 
13271     l_api_name               CONSTANT VARCHAR2(30) := 'Copy_User_Attrs_Data';
13272 
13273     --we don't use l_api_version yet, but eventually we might:
13274     --if we change required parameters, version goes FROM n.x to (n+1).x
13275     --if we change optional parameters, version goes FROM x.n to x.(n+1)
13276     l_api_version            CONSTANT NUMBER := 1.0;
13277 
13278     l_object_id                NUMBER;
13279     l_b_table_name             VARCHAR2(30);
13280     l_tl_table_name            VARCHAR2(30);
13281     l_vl_name                  VARCHAR2(30);
13282     l_ext_table_metadata_obj     EGO_EXT_TABLE_METADATA_OBJ;
13283     l_pk_col_metadata_array      EGO_COL_METADATA_ARRAY;
13284     l_data_level_metadata_array  EGO_COL_METADATA_ARRAY;
13285     l_class_code_metadata_array  EGO_COL_METADATA_ARRAY;
13286     l_pk_index                 NUMBER;
13287     l_dtlevel_index            NUMBER;
13288     l_cc_col_index             NUMBER;
13289     l_cc_value_index           NUMBER;
13290     l_found_value_for_this_col BOOLEAN;
13291     l_insert_pk_sql            VARCHAR2(500);
13292     l_insert_dtlevel_sql       VARCHAR2(500) := '';
13293     l_insert_class_code_sql    VARCHAR2(100) := '';
13294     l_select_pk_sql            VARCHAR2(2000);
13295     l_select_dtlevel_sql       VARCHAR2(2000) := '';
13296     l_select_class_code_sql    VARCHAR2(500) := '';
13297     l_where_pk_sql             VARCHAR2(2000);
13298     l_where_dtlevel_sql        VARCHAR2(2000) := '';
13299     l_where_not_in_sql         VARCHAR2(1000);
13300     l_column_name_to_copy      VARCHAR2(30);
13301     l_base_table_copy_dml      VARCHAR2(10000) := '';
13302     l_tl_table_copy_dml        VARCHAR2(10000) := '';
13303     l_copy_from_ext_id         NUMBER;
13304     l_copy_to_ext_id           NUMBER;
13305     l_dynamic_sql              VARCHAR2(500);
13306     l_b_table_col_names_list   VARCHAR2(3000);
13307     l_tl_table_col_names_list  VARCHAR2(3000);
13308 
13309     l_current_user_id        NUMBER := FND_GLOBAL.User_Id;
13310     l_current_login_id       NUMBER := FND_GLOBAL.Login_Id;
13311 
13312 l_has_data_level_id   BOOLEAN  := FALSE;    -- TRUE is for R12C
13313 l_all_dl_cols      VARCHAR2(500);
13314 l_dummy_string     VARCHAR2(32767);
13315 l_delimator_loc    NUMBER;
13316 l_pk_name          VARCHAR2(30);
13317 l_attr_group_type  VARCHAR2(40);
13318 
13319     TYPE DYNAMIC_CUR IS REF CURSOR;
13320     l_dynamic_cursor         DYNAMIC_CUR;
13321 
13322     CURSOR group_types_cursor (cp_application_id NUMBER, cp_object_id NUMBER)
13323     IS
13324     SELECT DISTINCT FDF.DESCRIPTIVE_FLEXFIELD_NAME  ATTR_GROUP_TYPE
13325       FROM EGO_OBJECT_EXT_TABLES_B                  EOET
13326           ,FND_DESCRIPTIVE_FLEXS                    FDF
13327      WHERE EOET.APPLICATION_ID = cp_application_id
13328        AND EOET.OBJECT_ID = cp_object_id
13329        AND FDF.APPLICATION_ID = cp_application_id
13330        AND EOET.APPLICATION_ID = FDF.APPLICATION_ID
13331        AND EOET.EXT_TABLE_NAME = FDF.APPLICATION_TABLE_NAME;
13332 
13333   BEGIN
13334 
13335     Debug_Msg(l_api_name || ' Starting ');
13336 
13337     IF FND_API.To_Boolean(p_commit) THEN
13338       SAVEPOINT Copy_User_Attrs_Data_PUB;
13339     END IF;
13340 
13341     -- Initialize FND_MSG_PUB if necessary
13342     IF (FND_API.To_Boolean(p_init_fnd_msg_list)) THEN
13343       FND_MSG_PUB.Initialize;
13344     END IF;
13345 
13346     -- Initialize ERROR_HANDLER if necessary
13347     IF (FND_API.To_Boolean(p_init_error_handler)) THEN
13348       ERROR_HANDLER.Initialize();
13349     END IF;
13350 
13351     -- Check for call compatibility
13352     IF NOT FND_API.Compatible_API_Call (l_api_version, p_api_version,
13353                                         l_api_name, G_PKG_NAME)
13354     THEN
13355       RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
13356     END IF;
13357 
13358     IF (FND_API.To_Boolean(p_add_errors_to_fnd_stack)) THEN
13359       G_ADD_ERRORS_TO_FND_STACK := 'Y';
13360     ELSE
13361       G_ADD_ERRORS_TO_FND_STACK := 'N';
13362     END IF;
13363 
13364     IF (p_object_id IS NULL) THEN
13365       l_object_id := Get_Object_Id_From_Name(p_object_name);
13366     ELSE
13367       l_object_id := p_object_id;
13368     END IF;
13369 
13370     --------------------------------------------------------------------
13371     -- The metadata for all extension tables (though not their names) --
13372     -- will be the same for all group types, so we only query it once --
13373     --------------------------------------------------------------------
13374     l_ext_table_metadata_obj := EGO_USER_ATTRS_COMMON_PVT.Get_Ext_Table_Metadata(l_object_id);
13375 
13376     ---------------------------------------------------------------------
13377     -- Now we build strings that will be necessary for the rest of the --
13378     -- processing and, like l_ext_table_metadata_obj, won't change     --
13379     ---------------------------------------------------------------------
13380     l_pk_col_metadata_array := l_ext_table_metadata_obj.pk_column_metadata;
13381     l_data_level_metadata_array := l_ext_table_metadata_obj.data_level_metadata;
13382     l_class_code_metadata_array := l_ext_table_metadata_obj.class_code_metadata;
13383 
13384     IF p_old_data_level_id IS NOT NULL OR p_new_data_level_id IS NOT NULL THEN
13385       l_has_data_level_id := TRUE;
13386     ELSE
13387       l_has_data_level_id := FALSE;
13388     END IF;
13389     -- processing the pk cols
13390     IF (p_old_pk_col_value_pairs.COUNT <> p_new_pk_col_value_pairs.COUNT) THEN
13391       x_msg_data := 'EGO_EF_CP_PK_COL_COUNT_ERR';
13392       RAISE FND_API.G_EXC_ERROR;
13393     END IF;
13394 
13395     l_pk_index := p_old_pk_col_value_pairs.FIRST;
13396     WHILE (l_pk_index <= p_old_pk_col_value_pairs.LAST)
13397     LOOP
13398       -- assuming that the l_pk_col_metadata_array will be greater than or equal to p_old_pk_col_value_pairs
13399       IF (p_old_pk_col_value_pairs(l_pk_index).NAME = p_new_pk_col_value_pairs(l_pk_index).NAME AND
13400           p_old_pk_col_value_pairs(l_pk_index).NAME = l_pk_col_metadata_array(l_pk_index).COL_NAME) THEN
13401 
13402         IF (p_old_pk_col_value_pairs(l_pk_index).VALUE IS NOT NULL AND
13403             p_new_pk_col_value_pairs(l_pk_index).VALUE IS NOT NULL) THEN
13404           l_select_pk_sql := l_select_pk_sql ||'''' ||p_new_pk_col_value_pairs(l_pk_index).VALUE ||''', ';
13405           l_where_pk_sql  := l_where_pk_sql ||p_old_pk_col_value_pairs(l_pk_index).NAME ||' = ''' ||p_old_pk_col_value_pairs(l_pk_index).VALUE ||''' AND ';
13406           l_insert_pk_sql := l_insert_pk_sql ||p_old_pk_col_value_pairs(l_pk_index).NAME ||', ';
13407         END IF;
13408         l_where_not_in_sql := l_where_not_in_sql ||'''' ||l_pk_col_metadata_array(l_pk_index).COL_NAME ||''', ' ;
13409       ELSE
13410         x_msg_data := 'EGO_EF_CP_PK_COL_NAME_ERR';
13411         RAISE FND_API.G_EXC_ERROR;
13412       END IF;
13413 
13414       l_pk_index := p_old_pk_col_value_pairs.NEXT(l_pk_index);
13415     END LOOP;
13416 
13417     Debug_Msg(l_api_name || ' After PK loop l_insert_pk_sql: '||l_insert_pk_sql);
13418     Debug_Msg(l_api_name || ' After PK loop l_select_pk_sql: '||l_select_pk_sql);
13419     Debug_Msg(l_api_name || ' After PK loop l_where_pk_sql: '||l_where_pk_sql);
13420 
13421     --processing data levels
13422     IF p_old_data_level_id IS NOT NULL OR p_new_data_level_id IS NOT NULL THEN
13423 
13424       -- R12C code changes is this based on data_level_id or an assumption!!
13425       -- preparing where clause from the data levels
13426       IF p_old_dtlevel_col_value_pairs IS NOT NULL AND p_old_dtlevel_col_value_pairs.COUNT > 0 THEN
13427         l_dtlevel_index := p_old_dtlevel_col_value_pairs.FIRST;
13428         WHILE (l_dtlevel_index <= p_old_dtlevel_col_value_pairs.LAST)
13429         LOOP
13430           IF (p_old_dtlevel_col_value_pairs(l_dtlevel_index).VALUE IS NOT NULL) THEN
13431             l_where_dtlevel_sql := l_where_dtlevel_sql ||p_old_dtlevel_col_value_pairs(l_dtlevel_index).NAME ||' = ''' ||p_old_dtlevel_col_value_pairs(l_dtlevel_index).VALUE || ''' AND ';
13432           ELSE
13433             l_where_dtlevel_sql := l_where_dtlevel_sql ||p_old_dtlevel_col_value_pairs(l_dtlevel_index).NAME ||' IS NULL AND ';
13434           END IF;  -- if null
13435           l_dtlevel_index := p_old_dtlevel_col_value_pairs.NEXT(l_dtlevel_index);
13436         END LOOP;
13437       END IF;
13438 
13439       -- preparing select and insert statement for new data levels
13440       IF p_new_dtlevel_col_value_pairs IS NOT NULL AND p_new_dtlevel_col_value_pairs.COUNT > 0 THEN
13441         l_dtlevel_index := p_new_dtlevel_col_value_pairs.FIRST;
13442         WHILE (l_dtlevel_index <= p_new_dtlevel_col_value_pairs.LAST)
13443         LOOP
13444           IF (p_new_dtlevel_col_value_pairs(l_dtlevel_index).VALUE IS NOT NULL) THEN
13445             l_select_dtlevel_sql := l_select_dtlevel_sql ||'''' ||p_new_dtlevel_col_value_pairs(l_dtlevel_index).VALUE ||''', ';
13446           ELSE
13447             l_select_dtlevel_sql := l_select_dtlevel_sql || ' NULL, ';
13448           END IF;  -- if null
13449           l_insert_dtlevel_sql := l_insert_dtlevel_sql ||p_new_dtlevel_col_value_pairs(l_dtlevel_index).NAME ||', ';
13450           l_dtlevel_index := p_new_dtlevel_col_value_pairs.NEXT(l_dtlevel_index);
13451         END LOOP;
13452       END IF;
13453 
13454   ELSE  --  p_old_data_level_id IS NOT NULL OR p_new_data_level_id IS NOT NULL
13455 
13456      -- existing code
13457       -- need to process data level only if it's not null
13458       IF (p_old_dtlevel_col_value_pairs IS NULL AND
13459           p_new_dtlevel_col_value_pairs IS NULL AND
13460           l_data_level_metadata_array IS NOT NULL) THEN
13461         x_msg_data := 'EGO_EF_CP_DL_NOT_PASSED_ERR';
13462         RAISE FND_API.G_EXC_ERROR;
13463       ELSIF (p_old_dtlevel_col_value_pairs IS NOT NULL AND
13464              p_new_dtlevel_col_value_pairs  IS NOT NULL) THEN
13465         IF (p_old_dtlevel_col_value_pairs.COUNT <> p_new_dtlevel_col_value_pairs.COUNT)  THEN
13466           x_msg_data := 'EGO_EF_CP_DL_COUNT_ERR';
13467           RAISE FND_API.G_EXC_ERROR;
13468         END IF;
13469         l_dtlevel_index := p_old_dtlevel_col_value_pairs.FIRST;
13470         WHILE (l_dtlevel_index <= p_old_dtlevel_col_value_pairs.LAST)
13471         LOOP
13472           -- need to check if the names are correct.
13473           IF (p_old_dtlevel_col_value_pairs(l_dtlevel_index).NAME = p_new_dtlevel_col_value_pairs(l_dtlevel_index).NAME AND
13474               p_old_dtlevel_col_value_pairs(l_dtlevel_index).NAME = l_data_level_metadata_array(l_dtlevel_index).COL_NAME) THEN
13475 
13476             IF (p_old_dtlevel_col_value_pairs(l_dtlevel_index).VALUE IS NOT NULL AND
13477                 p_new_dtlevel_col_value_pairs(l_dtlevel_index).VALUE IS NOT NULL) THEN
13478               l_select_dtlevel_sql := l_select_dtlevel_sql ||'''' ||p_new_dtlevel_col_value_pairs(l_dtlevel_index).VALUE ||''', ';
13479               l_where_dtlevel_sql := l_where_dtlevel_sql ||p_old_dtlevel_col_value_pairs(l_dtlevel_index).NAME ||' = ''' ||p_old_dtlevel_col_value_pairs(l_dtlevel_index).VALUE || ''' AND ';
13480             ELSE
13481               l_select_dtlevel_sql := l_select_dtlevel_sql || ' NULL, ';
13482               l_where_dtlevel_sql := l_where_dtlevel_sql ||p_old_dtlevel_col_value_pairs(l_dtlevel_index).NAME ||' IS NULL AND ';
13483             END IF;  -- if null
13484             l_insert_dtlevel_sql := l_insert_dtlevel_sql ||p_old_dtlevel_col_value_pairs(l_dtlevel_index).NAME ||', ';
13485             l_where_not_in_sql := l_where_not_in_sql ||'''' ||l_data_level_metadata_array(l_dtlevel_index).COL_NAME ||''', ';
13486           ELSE
13487             x_msg_data := 'EGO_EF_CP_DL_NAME_ERR';
13488             RAISE FND_API.G_EXC_ERROR;
13489           END IF;
13490           l_dtlevel_index := p_old_dtlevel_col_value_pairs.NEXT(l_dtlevel_index);
13491         END LOOP;
13492       END IF; -- if data level IS NOT NULL
13493     END IF;  -- p_old_data_level_id IS NOT NULL OR p_new_data_level_id IS NOT NULL
13494 
13495     Debug_Msg(l_api_name || ' After DL loop l_insert_dtlevel_sql: '||l_insert_dtlevel_sql);
13496     Debug_Msg(l_api_name || ' After DL loop l_select_dtlevel_sql: '||l_select_dtlevel_sql);
13497     Debug_Msg(l_api_name || ' After DL loop l_where_dtlevel_sql: '||l_where_dtlevel_sql);
13498     Debug_Msg(l_api_name || ' After DL loop l_where_not_in_sql: '||l_where_not_in_sql);
13499 
13500     --processing classification codes
13501     l_cc_col_index := l_class_code_metadata_array.FIRST;
13502     WHILE (l_cc_col_index <= l_class_code_metadata_array.LAST)
13503     LOOP
13504       EXIT WHEN l_class_code_metadata_array(l_cc_col_index).COL_NAME IS NULL;
13505 
13506       l_insert_class_code_sql := l_insert_class_code_sql ||
13507                                  l_class_code_metadata_array(l_cc_col_index).COL_NAME ||
13508                                  ', ';
13509       l_where_not_in_sql := l_where_not_in_sql ||
13510                             '''' ||
13511                             l_class_code_metadata_array(l_cc_col_index).COL_NAME ||
13512                             ''', ' ;
13513 
13514       l_found_value_for_this_col := FALSE;
13515       IF (p_new_cc_col_value_pairs IS NOT NULL AND
13516           p_new_cc_col_value_pairs.COUNT > 0) THEN
13517 
13518         -- loop through the passed-in name value pair array to find the right value for selecting
13519         l_cc_value_index := p_new_cc_col_value_pairs.FIRST;
13520         WHILE (l_cc_value_index <= p_new_cc_col_value_pairs.LAST)
13521         LOOP
13522           EXIT WHEN (l_found_value_for_this_col);
13523 
13524           IF (l_class_code_metadata_array(l_cc_col_index).COL_NAME =
13525               p_new_cc_col_value_pairs(l_cc_value_index).NAME) THEN
13526 
13527             l_select_class_code_sql := l_select_class_code_sql || '''' ||
13528                                        p_new_cc_col_value_pairs(l_cc_value_index).VALUE ||
13529                                        ''', ';
13530             l_found_value_for_this_col := TRUE;
13531           END IF;
13532 
13533           l_cc_value_index := p_new_cc_col_value_pairs.NEXT(l_cc_value_index);
13534         END LOOP;
13535       END IF;
13536 
13537       -- if we didn't find a value for the new classification code, we just copy the old one
13538       IF (NOT l_found_value_for_this_col) THEN
13539         l_select_class_code_sql := l_select_class_code_sql ||
13540                                    l_class_code_metadata_array(l_cc_col_index).COL_NAME ||
13541                                    ', ';
13542       END IF;
13543 
13544       l_cc_col_index := l_class_code_metadata_array.NEXT(l_cc_col_index);
13545     END LOOP;
13546     Debug_Msg(l_api_name || ' After CC loop l_select_class_code_sql: '||l_select_class_code_sql);
13547 
13548     -- appending the rest of columns to where not in sql
13549     l_where_not_in_sql := l_where_not_in_sql ||
13550                           '''EXTENSION_ID'', '||
13551                           '''DATA_LEVEL_ID'', '||
13552                           '''CREATED_BY'', '||
13553                           '''CREATION_DATE'', '||
13554                           '''LAST_UPDATED_BY'', '||
13555                           '''LAST_UPDATE_DATE'', '||
13556                           '''LAST_UPDATE_LOGIN''';
13557 
13558     -----------------------------------------------------------------
13559     -- we loop through all ATTR_GROUP_TYPE values for this object, --
13560     -- inserting rows into the B and TL tables for each group type --
13561     -----------------------------------------------------------------
13562     FOR group_rec IN group_types_cursor(p_application_id, l_object_id)
13563     LOOP
13564 
13565       Debug_Msg(l_api_name || ' In Group Rec Loop : '||group_rec.ATTR_GROUP_TYPE);
13566       SELECT EXT_TABLE_NAME, EXT_TL_TABLE_NAME, EXT_VL_NAME, ATTR_GROUP_TYPE
13567         INTO l_b_table_name, l_tl_table_name, l_vl_name, l_attr_group_type
13568         FROM EGO_ATTR_GROUP_TYPES_V
13569        WHERE APPLICATION_ID = p_application_id
13570          AND ATTR_GROUP_TYPE = group_rec.ATTR_GROUP_TYPE;
13571 
13572       l_has_data_level_id := FND_API.TO_BOOLEAN(EGO_USER_ATTRS_COMMON_PVT.has_column_in_table(
13573                                     p_table_name  => l_b_table_name
13574                                    ,p_column_name => 'DATA_LEVEL_ID')
13575                                              );
13576       IF l_has_data_level_id THEN
13577         l_all_dl_cols := EGO_USER_ATTRS_COMMON_PVT.Get_All_Data_Level_PK_Names
13578                                        (p_application_id  => p_application_id
13579                                        ,p_attr_group_type => l_attr_group_type);
13580         -- l_all_dl_cols are in the format a,b,c
13581         -- this need to be changed as 'a','b','c'
13582         l_where_not_in_sql := l_where_not_in_sql || ', '||REPLACE(''''||l_all_dl_cols||'''',', ',''', ''');
13583         l_all_dl_cols := l_all_dl_cols ||', ';
13584         --
13585         -- l_select_dtlevel_sql
13586         -- must be the given new dt level cols + null for the remaining columns in l_all_cols
13587         -- in the same order as in l_all_cols
13588         --
13589         l_select_dtlevel_sql := '';
13590         l_dummy_string := l_all_dl_cols;
13591         WHILE l_dummy_string IS NOT NULL LOOP
13592           l_delimator_loc := INSTR(l_dummy_string,',');
13593           IF l_delimator_loc = 0 THEN
13594             l_pk_name := l_dummy_string;
13595             l_dummy_string := NULL;
13596           ELSE
13597             l_pk_name := SUBSTR(l_dummy_string,0,l_delimator_loc);
13598             l_dummy_string := SUBSTR(l_dummy_string,l_delimator_loc+1);
13599           END IF;
13600           l_pk_name :=  TRIM(SUBSTR(TRIM(l_pk_name),1,LENGTH(TRIM(l_pk_name))-1));
13601           IF INSTR(l_insert_dtlevel_sql,l_pk_name) = 0 THEN
13602             l_select_dtlevel_sql := l_select_dtlevel_sql || ' NULL, ';
13603           ELSE
13604             IF p_new_dtlevel_col_value_pairs IS NOT NULL AND p_new_dtlevel_col_value_pairs.COUNT > 0 THEN
13605               l_dtlevel_index := p_new_dtlevel_col_value_pairs.FIRST;
13606               WHILE (l_dtlevel_index <= p_new_dtlevel_col_value_pairs.LAST)
13607               LOOP
13608                 IF (p_new_dtlevel_col_value_pairs(l_dtlevel_index).NAME = l_pk_name) THEN
13609                   l_select_dtlevel_sql := l_select_dtlevel_sql ||'''' ||p_new_dtlevel_col_value_pairs(l_dtlevel_index).VALUE ||''', ';
13610                   EXIT;
13611                 END IF;  -- if null
13612                 l_insert_dtlevel_sql := l_insert_dtlevel_sql ||p_new_dtlevel_col_value_pairs(l_dtlevel_index).NAME ||', ';
13613                 l_dtlevel_index := p_new_dtlevel_col_value_pairs.NEXT(l_dtlevel_index);
13614               END LOOP;
13615             END IF;
13616           END IF;
13617         END LOOP;
13618       END IF; -- l_has_data_level
13619       ----------------------------------------------
13620       -- Fetch all the base table column names... --
13621       ----------------------------------------------
13622       Debug_Msg(l_api_name || ' before Get_Table_Columns_List '||l_where_not_in_sql );
13623       l_b_table_col_names_list := Get_Table_Columns_List(
13624                                     p_application_id            => p_application_id
13625                                    ,p_from_table_name           => l_b_table_name
13626                                    ,p_from_cols_to_exclude_list => l_where_not_in_sql
13627                                   );
13628       Debug_Msg(l_api_name || ' after Get_Table_Columns_List '|| l_b_table_col_names_list);
13629 
13630       -------------------------------------------------------------
13631       -- ...and all the TL table column names (if there are any) --
13632       -------------------------------------------------------------
13633       IF (l_tl_table_name IS NOT NULL) THEN
13634 
13635         l_tl_table_col_names_list := Get_Table_Columns_List(
13636                                        p_application_id            => p_application_id
13637                                       ,p_from_table_name           => l_tl_table_name
13638                                       ,p_from_cols_to_exclude_list => l_where_not_in_sql
13639                                      );
13640 
13641       END IF;
13642 
13643       -----------------------------------------
13644       -- Build DML statements to use in each --
13645       -- iteration of our extension ID loop  --
13646       -----------------------------------------
13647 
13648       -- Bug 4071472
13649       -- Appending a comma in the end
13650       IF( l_b_table_col_names_list IS NOT NULL )
13651       THEN
13652         l_b_table_col_names_list := l_b_table_col_names_list||',';
13653       END IF;
13654 
13655       IF( l_tl_table_col_names_list IS NOT NULL )
13656       THEN
13657         l_tl_table_col_names_list := l_tl_table_col_names_list||',';
13658       END IF;
13659       Debug_Msg(l_api_name || ' Before Query l_insert_pk_sql: '||l_insert_pk_sql);
13660       Debug_Msg(l_api_name || ' Before Query l_all_dl_cols: '|| l_all_dl_cols );
13661       Debug_Msg(l_api_name || ' Before Query l_insert_class_code_sql: '||l_insert_class_code_sql );
13662       Debug_Msg(l_api_name || ' Before Query l_b_table_col_names_list: '|| l_b_table_col_names_list);
13663       Debug_Msg(l_api_name || ' Before Query l_select_pk_sql: '|| l_select_pk_sql);
13664       Debug_Msg(l_api_name || ' Before Query l_select_dtlevel_sql: '|| l_select_dtlevel_sql);
13665       Debug_Msg(l_api_name || ' Before Query l_select_class_code_sql: '|| l_select_class_code_sql );
13666       Debug_Msg(l_api_name || ' Before Query l_b_table_col_names_list: '|| l_b_table_col_names_list);
13667       Debug_Msg(l_api_name || ' Before Query l_tl_table_col_names_list: '|| l_tl_table_col_names_list);
13668 
13669       IF l_has_data_level_id THEN
13670         l_base_table_copy_dml := ' INSERT INTO '||l_b_table_name||
13671                                  ' (EXTENSION_ID, '||
13672                                     l_insert_pk_sql ||' '||
13673                                   ' DATA_LEVEL_ID, '||
13674                                     l_all_dl_cols ||' '||
13675                                     l_insert_class_code_sql ||' '||
13676                                     l_b_table_col_names_list||' '||
13677                                    'CREATED_BY, '||
13678                                    'CREATION_DATE, '||
13679                                    'LAST_UPDATED_BY, '||
13680                                    'LAST_UPDATE_DATE, '||
13681                                    'LAST_UPDATE_LOGIN)'||
13682                                  ' SELECT '||
13683                                     ':1, '||
13684                                     l_select_pk_sql ||' '||
13685                                     p_new_data_level_id ||', '||
13686                                     l_select_dtlevel_sql ||' '||
13687                                     l_select_class_code_sql ||' '||
13688                                     l_b_table_col_names_list||' '||
13689                                     l_current_user_id||', '||
13690                                    'SYSDATE, '||
13691                                     l_current_user_id||', '||
13692                                    'SYSDATE, '||
13693                                     l_current_login_id||
13694                                  ' FROM '||l_b_table_name||
13695                                 ' WHERE EXTENSION_ID = :2';
13696         IF (l_tl_table_name IS NOT NULL) THEN
13697           l_tl_table_copy_dml := ' INSERT INTO '||l_tl_table_name||
13698                                  ' (EXTENSION_ID, '||
13699                                     l_insert_pk_sql ||' '||
13700                                   ' DATA_LEVEL_ID, '||
13701                                     l_all_dl_cols ||' '||
13702                                     l_insert_class_code_sql ||' '||
13703                                     l_tl_table_col_names_list||' '||
13704                                    'CREATED_BY, '||
13705                                    'CREATION_DATE, '||
13706                                    'LAST_UPDATED_BY, '||
13707                                    'LAST_UPDATE_DATE, '||
13708                                    'LAST_UPDATE_LOGIN)'||
13709                                  ' SELECT '||
13710                                     ':1, '||
13711                                     l_select_pk_sql ||' '||
13712                                     p_new_data_level_id ||', '||
13713                                     l_select_dtlevel_sql ||' '||
13714                                     l_select_class_code_sql ||' '||
13715                                     l_tl_table_col_names_list||' '||
13716                                     l_current_user_id||', '||
13717                                    'SYSDATE, '||
13718                                     l_current_user_id||', '||
13719                                    'SYSDATE, '||
13720                                     l_current_login_id||
13721                                  ' FROM '||l_tl_table_name||
13722                                 ' WHERE EXTENSION_ID = :2';
13723         END IF;
13724       ELSE
13725         l_base_table_copy_dml := ' INSERT INTO '||l_b_table_name||
13726                                  ' (EXTENSION_ID, '||
13727                                     l_insert_pk_sql ||' '||
13728                                     l_insert_dtlevel_sql ||' '||
13729                                     l_insert_class_code_sql ||' '||
13730                                     l_b_table_col_names_list||' '||
13731                                    'CREATED_BY, '||
13732                                    'CREATION_DATE, '||
13733                                    'LAST_UPDATED_BY, '||
13734                                    'LAST_UPDATE_DATE, '||
13735                                    'LAST_UPDATE_LOGIN)'||
13736                                  ' SELECT '||
13737                                     ':1, '||
13738                                     l_select_pk_sql ||' '||
13739                                     l_select_dtlevel_sql ||' '||
13740                                     l_select_class_code_sql ||' '||
13741                                     l_b_table_col_names_list||' '||
13742                                     l_current_user_id||', '||
13743                                    'SYSDATE, '||
13744                                     l_current_user_id||', '||
13745                                    'SYSDATE, '||
13746                                     l_current_login_id||
13747                                  ' FROM '||l_b_table_name||
13748                                 ' WHERE EXTENSION_ID = :2';
13749 
13750         IF (l_tl_table_name IS NOT NULL) THEN
13751           l_tl_table_copy_dml := ' INSERT INTO '||l_tl_table_name||
13752                                  ' (EXTENSION_ID, '||
13753                                     l_insert_pk_sql ||' '||
13754                                     l_insert_dtlevel_sql ||' '||
13755                                     l_insert_class_code_sql ||' '||
13756                                     l_tl_table_col_names_list||' '||
13757                                    'CREATED_BY, '||
13758                                    'CREATION_DATE, '||
13759                                    'LAST_UPDATED_BY, '||
13760                                    'LAST_UPDATE_DATE, '||
13761                                    'LAST_UPDATE_LOGIN)'||
13762                                  ' SELECT '||
13763                                     ':1, '||
13764                                     l_select_pk_sql ||' '||
13765                                     l_select_dtlevel_sql ||' '||
13766                                     l_select_class_code_sql ||' '||
13767                                     l_tl_table_col_names_list||' '||
13768                                     l_current_user_id||', '||
13769                                    'SYSDATE, '||
13770                                     l_current_user_id||', '||
13771                                    'SYSDATE, '||
13772                                     l_current_login_id||
13773                                  ' FROM '||l_tl_table_name||
13774                                 ' WHERE EXTENSION_ID = :2';
13775         END IF;
13776       END IF;  -- l_has_data_level
13777       Debug_Msg(l_api_name || ' l_base_table_copy_dml: '||l_base_table_copy_dml);
13778       Debug_Msg(l_api_name || ' l_tl_table_copy_dml: '||l_tl_table_copy_dml);
13779       ------------------------------------------------------------------------
13780       -- We build a cursor to query extension IDs from the copy-from object --
13781       -- and to generate extension IDs for the copy-to object; then we loop --
13782       -- through that cursor inserting rows for the copy-to object into the --
13783       -- B and TL tables, using the copy-from object's values.              --
13784       ------------------------------------------------------------------------
13785       l_dynamic_sql := ' SELECT EXTENSION_ID, EGO_EXTFWK_S.NEXTVAL '||
13786                          ' FROM '||NVL(l_vl_name, l_b_table_name)||
13787                         ' WHERE '||l_where_pk_sql||l_where_dtlevel_sql;
13788 
13789       -------------------------------------------------------------
13790       -- Trim the last 'AND' that is left on l_where_dtlevel_sql --
13791       -------------------------------------------------------------
13792       l_dynamic_sql := SUBSTR(l_dynamic_sql, 1, LENGTH(l_dynamic_sql) - LENGTH(' AND'));
13793 
13794       OPEN l_dynamic_cursor FOR l_dynamic_sql;
13795       LOOP
13796         FETCH l_dynamic_cursor INTO l_copy_from_ext_id, l_copy_to_ext_id;
13797         EXIT WHEN l_dynamic_cursor%NOTFOUND;
13798 
13799           EXECUTE IMMEDIATE l_base_table_copy_dml USING l_copy_to_ext_id, l_copy_from_ext_id;
13800 
13801           IF (l_tl_table_name IS NOT NULL) THEN
13802             EXECUTE IMMEDIATE l_tl_table_copy_dml USING l_copy_to_ext_id, l_copy_from_ext_id;
13803 
13804           END IF;
13805 
13806       END LOOP;
13807       CLOSE l_dynamic_cursor;
13808     END LOOP;
13809 
13810     IF FND_API.To_Boolean(p_commit) THEN
13811       COMMIT WORK;
13812     END IF;
13813 
13814     x_return_status := FND_API.G_RET_STS_SUCCESS;
13815 
13816   EXCEPTION
13817     WHEN FND_API.G_EXC_ERROR THEN
13818       Debug_Msg(l_api_name || ' EXCEPTION FND_API.G_EXC_ERROR');
13819       IF FND_API.To_Boolean(p_commit) THEN
13820         ROLLBACK TO Copy_User_Attrs_Data_PUB;
13821       END IF;
13822       x_return_status := FND_API.G_RET_STS_ERROR;
13823 
13824       ERROR_HANDLER.Add_Error_Message(
13825         p_message_name      => x_msg_data
13826        ,p_application_id    => 'EGO'
13827        ,p_message_type      => FND_API.G_RET_STS_ERROR
13828        ,p_addto_fnd_stack   => G_ADD_ERRORS_TO_FND_STACK
13829       );
13830 
13831     WHEN OTHERS THEN
13832       Debug_Msg(l_api_name || ' EXCEPTION OTHERS '||SQLERRM);
13833       IF FND_API.To_Boolean(p_commit) THEN
13834         ROLLBACK TO Copy_User_Attrs_Data_PUB;
13835       END IF;
13836       x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
13837 
13838       DECLARE
13839         l_token_table            ERROR_HANDLER.Token_Tbl_Type;
13840       BEGIN
13841         l_token_table(1).TOKEN_NAME := 'PKG_NAME';
13842         l_token_table(1).TOKEN_VALUE := G_PKG_NAME;
13843         l_token_table(2).TOKEN_NAME := 'API_NAME';
13844         l_token_table(2).TOKEN_VALUE := l_api_name;
13845         l_token_table(3).TOKEN_NAME := 'SQL_ERR_MSG';
13846         l_token_table(3).TOKEN_VALUE := SQLERRM;
13847 
13848         ERROR_HANDLER.Add_Error_Message(
13849           p_message_name      => 'EGO_PLSQL_ERR'
13850          ,p_application_id    => 'EGO'
13851          ,p_token_tbl         => l_token_table
13852          ,p_message_type      => FND_API.G_RET_STS_ERROR
13853          ,p_addto_fnd_stack   => G_ADD_ERRORS_TO_FND_STACK
13854         );
13855       END;
13856 
13857 END Copy_User_Attrs_Data;
13858 
13859 ---------------------------------------------------------------------------
13860 
13861 PROCEDURE Implement_Change_Line (
13862         p_api_version                   IN   NUMBER
13863        ,p_object_name                   IN   VARCHAR2
13864        ,p_production_b_table_name       IN   VARCHAR2
13865        ,p_production_tl_table_name      IN   VARCHAR2
13866        ,p_change_b_table_name           IN   VARCHAR2
13867        ,p_change_tl_table_name          IN   VARCHAR2
13868        ,p_tables_application_id         IN   NUMBER
13869        ,p_change_line_id                IN   NUMBER
13870        ,p_old_data_level_nv_pairs       IN   EGO_COL_NAME_VALUE_PAIR_ARRAY DEFAULT NULL
13871        ,p_new_data_level_nv_pairs       IN   EGO_COL_NAME_VALUE_PAIR_ARRAY DEFAULT NULL
13872        ,p_related_class_code_function   IN   VARCHAR2
13873        ,p_init_msg_list                 IN   VARCHAR2   DEFAULT FND_API.G_FALSE
13874        ,p_commit                        IN   VARCHAR2   DEFAULT FND_API.G_FALSE
13875        ,x_return_status                 OUT NOCOPY VARCHAR2
13876        ,x_errorcode                     OUT NOCOPY NUMBER
13877        ,x_msg_count                     OUT NOCOPY NUMBER
13878        ,x_msg_data                      OUT NOCOPY VARCHAR2
13879 ) IS
13880 
13881     l_api_name               CONSTANT VARCHAR2(30) := 'Implement_Change_Line';
13882 
13883     --we don't use l_api_version yet, but eventually we might:
13884     --if we change required parameters, version goes FROM n.x to (n+1).x
13885     --if we change optional parameters, version goes FROM x.n to x.(n+1)
13886     l_api_version            CONSTANT NUMBER := 1.0;
13887 
13888     l_object_id              NUMBER;
13889     l_data_level_name_value_pairs EGO_COL_NAME_VALUE_PAIR_ARRAY;
13890     l_current_dl_name_value_pairs EGO_COL_NAME_VALUE_PAIR_ARRAY;
13891     l_ext_table_metadata_obj EGO_EXT_TABLE_METADATA_OBJ;
13892     l_chng_col_names_list    VARCHAR2(20000);
13893     l_cols_to_exclude_list   VARCHAR2(2000);
13894     l_pk_column_name_value_pairs EGO_COL_NAME_VALUE_PAIR_ARRAY;
13895     l_class_code_name_value_pairs EGO_COL_NAME_VALUE_PAIR_ARRAY;
13896     l_b_chng_cols_list       VARCHAR2(10000);
13897     l_tl_chng_cols_list      VARCHAR2(10000);
13898     l_history_b_chng_cols_list VARCHAR2(10000);
13899     l_history_tl_chng_cols_list VARCHAR2(10000);
13900     l_history_b_prod_cols_list VARCHAR2(10000);
13901     l_history_tl_prod_cols_list VARCHAR2(10000);
13902     l_dynamic_sql            VARCHAR2(32767); --the largest a VARCHAR2 can be
13903     l_cursor_id              NUMBER;
13904     l_column_count           NUMBER;
13905     l_desc_table             DBMS_SQL.Desc_Tab;
13906     l_retrieved_value        VARCHAR2(1000);
13907     l_dummy                  NUMBER;
13908     l_current_column_index   NUMBER;
13909     l_current_row_language   VARCHAR2(30);
13910     l_current_row_source_lang VARCHAR2(30);
13911     l_current_acd_type       VARCHAR2(30);
13912     l_attr_group_metadata_obj EGO_ATTR_GROUP_METADATA_OBJ;
13913     l_current_pending_ext_id NUMBER;
13914     l_current_column_name    VARCHAR2(30);
13915     l_attr_metadata_obj      EGO_ATTR_METADATA_OBJ;
13916     l_dummy_err_msg_name     VARCHAR2(30);
13917     l_token_table            ERROR_HANDLER.Token_Tbl_Type;
13918     l_attr_name_value_pairs  EGO_USER_ATTR_DATA_TABLE := EGO_USER_ATTR_DATA_TABLE();
13919     l_uom_column_nv_pairs    LOCAL_COL_NV_PAIR_TABLE;
13920     l_uom_nv_pairs_index     NUMBER := 0;
13921     l_current_uom_col_nv_obj EGO_COL_NAME_VALUE_PAIR_OBJ;
13922     l_attr_col_name_for_uom_col VARCHAR2(30);
13923     l_current_production_ext_id NUMBER;
13924     l_mode_for_current_row   VARCHAR2(10);
13925     l_ext_id_for_current_row NUMBER;
13926     l_utility_dynamic_sql    VARCHAR2(32767); --the largest a VARCHAR2 can be
13927     l_return_status          VARCHAR2(1);
13928     l_errorcode              NUMBER;
13929     l_msg_count              NUMBER;
13930     l_msg_data               VARCHAR2(1000);
13931 
13932   BEGIN
13933 
13934     Debug_Msg('In Implement_Change_Line, starting', 1);
13935 
13936     IF FND_API.To_Boolean(p_commit) THEN
13937       SAVEPOINT Implement_Change_Line_PUB;
13938     END IF;
13939 
13940     -- Initialize FND_MSG_PUB and ERROR_HANDLER if necessary
13941     IF (FND_API.To_Boolean(p_init_msg_list)) THEN
13942       FND_MSG_PUB.Initialize;
13943       ERROR_HANDLER.Initialize;
13944     END IF;
13945 
13946     -- Check for call compatibility
13947     IF NOT FND_API.Compatible_API_Call (l_api_version, p_api_version,
13948                                         l_api_name, G_PKG_NAME)
13949     THEN
13950       RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
13951     END IF;
13952 
13953     -----------------------------------------------
13954     -- First, we get the Object ID for our calls --
13955     -----------------------------------------------
13956     l_object_id := Get_Object_Id_From_Name(p_object_name);
13957 
13958     ----------------------------------------------------
13959     -- Determine whether we got new Data Level values --
13960     ----------------------------------------------------
13961     IF (p_new_data_level_nv_pairs IS NOT NULL) THEN
13962       l_data_level_name_value_pairs := p_new_data_level_nv_pairs;
13963     ELSE
13964       l_data_level_name_value_pairs := p_old_data_level_nv_pairs;
13965     END IF;
13966 
13967     ---------------------------------------------------------
13968     -- Get the necessary metadata for our production table --
13969     ---------------------------------------------------------
13970     l_ext_table_metadata_obj :=
13971       EGO_USER_ATTRS_COMMON_PVT.Get_Ext_Table_Metadata(l_object_id);
13972 
13973     ----------------------------------------------------------
13974     -- Build a PK name/value pair array and begin the lists --
13975     -- of column names to fetch explicitly instead of from  --
13976     -- our constructed table columns list                   --
13977     ----------------------------------------------------------
13978 
13979     --
13980     -- ASSUMPTION: no PKs will ever be DATE objects
13981     --
13982     IF (l_ext_table_metadata_obj.pk_column_metadata.COUNT = 5) THEN
13983       l_pk_column_name_value_pairs :=
13984         EGO_COL_NAME_VALUE_PAIR_ARRAY(
13985           EGO_COL_NAME_VALUE_PAIR_OBJ(
13986             l_ext_table_metadata_obj.pk_column_metadata(1).COL_NAME, NULL
13987           )
13988          ,EGO_COL_NAME_VALUE_PAIR_OBJ(
13989             l_ext_table_metadata_obj.pk_column_metadata(2).COL_NAME, NULL
13990           )
13991          ,EGO_COL_NAME_VALUE_PAIR_OBJ(
13992             l_ext_table_metadata_obj.pk_column_metadata(3).COL_NAME, NULL
13993           )
13994          ,EGO_COL_NAME_VALUE_PAIR_OBJ(
13995             l_ext_table_metadata_obj.pk_column_metadata(4).COL_NAME, NULL
13996           )
13997          ,EGO_COL_NAME_VALUE_PAIR_OBJ(
13998             l_ext_table_metadata_obj.pk_column_metadata(5).COL_NAME, NULL
13999           )
14000         );
14001       l_chng_col_names_list := 'B.'||
14002                                l_ext_table_metadata_obj.pk_column_metadata(1).COL_NAME||
14003                                ',B.'||
14004                                l_ext_table_metadata_obj.pk_column_metadata(2).COL_NAME||
14005                                ',B.'||
14006                                l_ext_table_metadata_obj.pk_column_metadata(3).COL_NAME||
14007                                ',B.'||
14008                                l_ext_table_metadata_obj.pk_column_metadata(4).COL_NAME||
14009                                ',B.'||
14010                                l_ext_table_metadata_obj.pk_column_metadata(5).COL_NAME;
14011       l_cols_to_exclude_list := ''''||
14012                                 l_ext_table_metadata_obj.pk_column_metadata(1).COL_NAME||
14013                                 ''','''||
14014                                 l_ext_table_metadata_obj.pk_column_metadata(2).COL_NAME||
14015                                 ''','''||
14016                                 l_ext_table_metadata_obj.pk_column_metadata(3).COL_NAME||
14017                                 ''','''||
14018                                 l_ext_table_metadata_obj.pk_column_metadata(4).COL_NAME||
14019                                 ''','''||
14020                                 l_ext_table_metadata_obj.pk_column_metadata(5).COL_NAME||
14021                                 '''';
14022     ELSIF (l_ext_table_metadata_obj.pk_column_metadata.COUNT = 4) THEN
14023       l_pk_column_name_value_pairs :=
14024         EGO_COL_NAME_VALUE_PAIR_ARRAY(
14025           EGO_COL_NAME_VALUE_PAIR_OBJ(
14026             l_ext_table_metadata_obj.pk_column_metadata(1).COL_NAME, NULL
14027           )
14028          ,EGO_COL_NAME_VALUE_PAIR_OBJ(
14029             l_ext_table_metadata_obj.pk_column_metadata(2).COL_NAME, NULL
14030           )
14031          ,EGO_COL_NAME_VALUE_PAIR_OBJ(
14032             l_ext_table_metadata_obj.pk_column_metadata(3).COL_NAME, NULL
14033           )
14034          ,EGO_COL_NAME_VALUE_PAIR_OBJ(
14035             l_ext_table_metadata_obj.pk_column_metadata(4).COL_NAME, NULL
14036           )
14037         );
14038       l_chng_col_names_list := 'B.'||
14039                                l_ext_table_metadata_obj.pk_column_metadata(1).COL_NAME||
14040                                ',B.'||
14041                                l_ext_table_metadata_obj.pk_column_metadata(2).COL_NAME||
14042                                ',B.'||
14043                                l_ext_table_metadata_obj.pk_column_metadata(3).COL_NAME||
14044                                ',B.'||
14045                                l_ext_table_metadata_obj.pk_column_metadata(4).COL_NAME;
14046       l_cols_to_exclude_list := ''''||
14047                                 l_ext_table_metadata_obj.pk_column_metadata(1).COL_NAME||
14048                                 ''','''||
14049                                 l_ext_table_metadata_obj.pk_column_metadata(2).COL_NAME||
14050                                 ''','''||
14051                                 l_ext_table_metadata_obj.pk_column_metadata(3).COL_NAME||
14052                                 ''','''||
14053                                 l_ext_table_metadata_obj.pk_column_metadata(4).COL_NAME||
14054                                 '''';
14055     ELSIF (l_ext_table_metadata_obj.pk_column_metadata.COUNT = 3) THEN
14056       l_pk_column_name_value_pairs :=
14057         EGO_COL_NAME_VALUE_PAIR_ARRAY(
14058           EGO_COL_NAME_VALUE_PAIR_OBJ(
14059             l_ext_table_metadata_obj.pk_column_metadata(1).COL_NAME, NULL
14060           )
14061          ,EGO_COL_NAME_VALUE_PAIR_OBJ(
14062             l_ext_table_metadata_obj.pk_column_metadata(2).COL_NAME, NULL
14063           )
14064          ,EGO_COL_NAME_VALUE_PAIR_OBJ(
14065             l_ext_table_metadata_obj.pk_column_metadata(3).COL_NAME, NULL
14066           )
14067         );
14068       l_chng_col_names_list := 'B.'||
14069                                l_ext_table_metadata_obj.pk_column_metadata(1).COL_NAME||
14070                                ',B.'||
14071                                l_ext_table_metadata_obj.pk_column_metadata(2).COL_NAME||
14072                                ',B.'||
14073                                l_ext_table_metadata_obj.pk_column_metadata(3).COL_NAME;
14074       l_cols_to_exclude_list := ''''||
14075                                 l_ext_table_metadata_obj.pk_column_metadata(1).COL_NAME||
14076                                 ''','''||
14077                                 l_ext_table_metadata_obj.pk_column_metadata(2).COL_NAME||
14078                                 ''','''||
14079                                 l_ext_table_metadata_obj.pk_column_metadata(3).COL_NAME||
14080                                 '''';
14081     ELSIF (l_ext_table_metadata_obj.pk_column_metadata.COUNT = 2) THEN
14082       l_pk_column_name_value_pairs :=
14083         EGO_COL_NAME_VALUE_PAIR_ARRAY(
14084           EGO_COL_NAME_VALUE_PAIR_OBJ(
14085             l_ext_table_metadata_obj.pk_column_metadata(1).COL_NAME, NULL
14086           )
14087          ,EGO_COL_NAME_VALUE_PAIR_OBJ(
14088             l_ext_table_metadata_obj.pk_column_metadata(2).COL_NAME, NULL
14089           )
14090         );
14091       l_chng_col_names_list := 'B.'||
14092                                l_ext_table_metadata_obj.pk_column_metadata(1).COL_NAME||
14093                                ',B.'||
14094                                l_ext_table_metadata_obj.pk_column_metadata(2).COL_NAME;
14095       l_cols_to_exclude_list := ''''||
14096                                 l_ext_table_metadata_obj.pk_column_metadata(1).COL_NAME||
14097                                 ''','''||
14098                                 l_ext_table_metadata_obj.pk_column_metadata(2).COL_NAME||
14099                                 '''';
14100     ELSIF (l_ext_table_metadata_obj.pk_column_metadata.COUNT = 1) THEN
14101       l_pk_column_name_value_pairs :=
14102         EGO_COL_NAME_VALUE_PAIR_ARRAY(
14103           EGO_COL_NAME_VALUE_PAIR_OBJ(
14104             l_ext_table_metadata_obj.pk_column_metadata(1).COL_NAME, NULL
14105           )
14106         );
14107       l_chng_col_names_list := 'B.'||
14108                                l_ext_table_metadata_obj.pk_column_metadata(1).COL_NAME;
14109       l_cols_to_exclude_list := ''''||
14110                                 l_ext_table_metadata_obj.pk_column_metadata(1).COL_NAME||
14111                                 '''';
14112     END IF;
14113 
14114     ----------------------------------------------------------
14115     -- Now we add Classification Code columns to the lists, --
14116     -- if necessary; this includes room for a list of Class --
14117     -- Codes that are related to the current Class Code     --
14118     ----------------------------------------------------------
14119     IF (l_ext_table_metadata_obj.class_code_metadata IS NOT NULL AND
14120         l_ext_table_metadata_obj.class_code_metadata.COUNT > 0 AND
14121         l_ext_table_metadata_obj.class_code_metadata(1).COL_NAME IS NOT NULL) THEN
14122       l_class_code_name_value_pairs :=
14123         EGO_COL_NAME_VALUE_PAIR_ARRAY(
14124           EGO_COL_NAME_VALUE_PAIR_OBJ(
14125             l_ext_table_metadata_obj.class_code_metadata(1).COL_NAME, NULL
14126           ),
14127           EGO_COL_NAME_VALUE_PAIR_OBJ(
14128             'RELATED_CLASS_CODE_LIST_1', NULL
14129           )
14130         );
14131 
14132       l_chng_col_names_list := l_chng_col_names_list||',B.'||
14133                                l_ext_table_metadata_obj.class_code_metadata(1).COL_NAME;
14134 
14135       l_cols_to_exclude_list := l_cols_to_exclude_list||','''||
14136                                 l_ext_table_metadata_obj.class_code_metadata(1).COL_NAME||
14137                                 '''';
14138     END IF;
14139 
14140     -----------------------------------------------------------------
14141     -- For Data Level, we exclude the columns but don't explicitly --
14142     -- include them, because we already have the values we want    --
14143     -----------------------------------------------------------------
14144     IF (l_ext_table_metadata_obj.data_level_metadata IS NOT NULL) THEN
14145       IF (l_ext_table_metadata_obj.data_level_metadata.COUNT > 0) THEN
14146         l_cols_to_exclude_list :=
14147           l_cols_to_exclude_list||','''||
14148           l_ext_table_metadata_obj.data_level_metadata(1).COL_NAME||
14149           '''';
14150       END IF;
14151       IF (l_ext_table_metadata_obj.data_level_metadata.COUNT > 1) THEN
14152         l_cols_to_exclude_list :=
14153           l_cols_to_exclude_list||','''||
14154           l_ext_table_metadata_obj.data_level_metadata(2).COL_NAME||
14155           '''';
14156       END IF;
14157       IF (l_ext_table_metadata_obj.data_level_metadata.COUNT > 2) THEN
14158         l_cols_to_exclude_list :=
14159           l_cols_to_exclude_list||','''||
14160           l_ext_table_metadata_obj.data_level_metadata(3).COL_NAME||
14161           '''';
14162       END IF;
14163     END IF;
14164 
14165     ---------------------------------------------------------------
14166     -- Next, we add to the lists the rest of the columns that we --
14167     -- either want to get explicitly or don't want to get at all --
14168     ---------------------------------------------------------------
14169     l_chng_col_names_list := l_chng_col_names_list||
14170                              ',B.ACD_TYPE,B.ATTR_GROUP_ID,B.EXTENSION_ID';
14171     l_cols_to_exclude_list := l_cols_to_exclude_list||
14172                               ',''ACD_TYPE'',''ATTR_GROUP_ID'',''EXTENSION_ID'','||
14173                               '''CHANGE_ID'',''CHANGE_LINE_ID'','||
14174                               '''IMPLEMENTATION_DATE'',''CREATED_BY'','||
14175                               '''CREATION_DATE'',''LAST_UPDATED_BY'','||
14176                               '''LAST_UPDATE_DATE'',''LAST_UPDATE_LOGIN''';
14177 
14178     ----------------------------------------------------------
14179     -- Get lists of columns for the B and TL pending tables --
14180     -- (i.e., all Attr cols and the language cols from TL)  --
14181     ----------------------------------------------------------
14182     l_b_chng_cols_list := Get_Table_Columns_List(
14183                             p_application_id            => p_tables_application_id
14184                            ,p_from_table_name           => p_change_b_table_name
14185                            ,p_from_cols_to_exclude_list => l_cols_to_exclude_list
14186                            ,p_cast_date_cols_to_char    => TRUE
14187                           );
14188     l_tl_chng_cols_list := Get_Table_Columns_List(
14189                              p_application_id            => p_tables_application_id
14190                             ,p_from_table_name           => p_change_tl_table_name
14191                             ,p_from_cols_to_exclude_list => l_cols_to_exclude_list
14192                             ,p_cast_date_cols_to_char    => TRUE
14193                            );
14194 
14195     --------------------------------------------------------
14196     -- While we're getting lists of columns, we also get  --
14197     -- lists for later use in copying old production rows --
14198     -- into the pending tables as HISTORY rows            --
14199     --------------------------------------------------------
14200     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'' ';
14201 
14202     l_history_b_chng_cols_list := Get_Table_Columns_List(
14203                                     p_application_id            => p_tables_application_id
14204                                    ,p_from_table_name           => p_change_b_table_name
14205                                    ,p_from_table_alias_prefix   => 'CT'
14206                                    ,p_from_cols_to_exclude_list => l_cols_to_exclude_list
14207                                   );
14208     l_history_tl_chng_cols_list := Get_Table_Columns_List(
14209                                      p_application_id            => p_tables_application_id
14210                                     ,p_from_table_name           => p_change_tl_table_name
14211                                     ,p_from_table_alias_prefix   => 'CT'
14212                                     ,p_from_cols_to_exclude_list => l_cols_to_exclude_list
14213                                    );
14214     l_history_b_prod_cols_list := Get_Table_Columns_List(
14215                                     p_application_id            => p_tables_application_id
14216                                    ,p_from_table_name           => p_production_b_table_name
14217                                    ,p_from_table_alias_prefix   => 'PT'
14218                                    ,p_from_cols_to_exclude_list => l_cols_to_exclude_list
14219                                   );
14220     l_history_tl_prod_cols_list := Get_Table_Columns_List(
14221                                      p_application_id            => p_tables_application_id
14222                                     ,p_from_table_name           => p_production_tl_table_name
14223                                     ,p_from_table_alias_prefix   => 'PT'
14224                                     ,p_from_cols_to_exclude_list => l_cols_to_exclude_list
14225                                    );
14226 
14227     -------------------------------------------------
14228     -- Now we build the SQL for our dynamic cursor --
14229     -------------------------------------------------
14230     l_dynamic_sql := 'SELECT '||l_chng_col_names_list||','||
14231                                 l_b_chng_cols_list||','||
14232                                 l_tl_chng_cols_list||
14233                       ' FROM '||p_change_b_table_name||' B,'||
14234                                 p_change_tl_table_name||' TL'||
14235                      ' WHERE B.ACD_TYPE <> ''HISTORY'' AND B.IMPLEMENTATION_DATE IS NULL'||
14236                        ' AND B.EXTENSION_ID = TL.EXTENSION_ID'||
14237                        ' AND B.ACD_TYPE = TL.ACD_TYPE'||
14238                        ' AND B.CHANGE_LINE_ID = TL.CHANGE_LINE_ID'||
14239                        ' AND B.CHANGE_LINE_ID = :1';
14240 
14241     l_cursor_id := DBMS_SQL.Open_Cursor;
14242     DBMS_SQL.Parse(l_cursor_id, l_dynamic_sql, DBMS_SQL.Native);
14243     DBMS_SQL.Bind_Variable(l_cursor_id, ':1', p_change_line_id);
14244     DBMS_SQL.Describe_Columns(l_cursor_id, l_column_count, l_desc_table);
14245 
14246     FOR i IN 1 .. l_column_count
14247     LOOP
14248       -------------------------------------------------------------
14249       -- We define all columns as VARCHAR2(1000) for convenience --
14250        -- ASSUMPTION: no PKs will ever be DATE objects           --
14251       -------------------------------------------------------------
14252       DBMS_SQL.Define_Column(l_cursor_id, i, l_retrieved_value, 1000);
14253     END LOOP;
14254 
14255     ----------------------------------
14256     -- Execute our dynamic query... --
14257     ----------------------------------
14258     l_dummy := DBMS_SQL.Execute(l_cursor_id);
14259 
14260     ----------------------------------------------------
14261     -- ...then loop through the result set, gathering --
14262     -- the column values and then calling Process_Row --
14263     ----------------------------------------------------
14264     WHILE (DBMS_SQL.Fetch_Rows(l_cursor_id) > 0)
14265     LOOP
14266 
14267       l_current_column_index := 1;
14268       l_attr_name_value_pairs.DELETE();
14269 
14270       ------------------------------------
14271       -- Get the PK values for this row --
14272       ------------------------------------
14273       IF (l_pk_column_name_value_pairs.COUNT > 0) THEN
14274         DBMS_SQL.Column_Value(l_cursor_id, l_current_column_index, l_retrieved_value);
14275         l_current_column_index := l_current_column_index + 1;
14276         l_pk_column_name_value_pairs(1).VALUE := SUBSTRB(l_retrieved_value, 1, 150);
14277       END IF;
14278       IF (l_pk_column_name_value_pairs.COUNT > 1) THEN
14279         DBMS_SQL.Column_Value(l_cursor_id, l_current_column_index, l_retrieved_value);
14280         l_current_column_index := l_current_column_index + 1;
14281         l_pk_column_name_value_pairs(2).VALUE := SUBSTRB(l_retrieved_value, 1, 150);
14282       END IF;
14283       IF (l_pk_column_name_value_pairs.COUNT > 2) THEN
14284         DBMS_SQL.Column_Value(l_cursor_id, l_current_column_index, l_retrieved_value);
14285         l_current_column_index := l_current_column_index + 1;
14286         l_pk_column_name_value_pairs(3).VALUE := SUBSTRB(l_retrieved_value, 1, 150);
14287       END IF;
14288       IF (l_pk_column_name_value_pairs.COUNT > 3) THEN
14289         DBMS_SQL.Column_Value(l_cursor_id, l_current_column_index, l_retrieved_value);
14290         l_current_column_index := l_current_column_index + 1;
14291         l_pk_column_name_value_pairs(4).VALUE := SUBSTRB(l_retrieved_value, 1, 150);
14292       END IF;
14293       IF (l_pk_column_name_value_pairs.COUNT > 4) THEN
14294         DBMS_SQL.Column_Value(l_cursor_id, l_current_column_index, l_retrieved_value);
14295         l_current_column_index := l_current_column_index + 1;
14296         l_pk_column_name_value_pairs(5).VALUE := SUBSTRB(l_retrieved_value, 1, 150);
14297       END IF;
14298 
14299       ------------------------------------------------
14300       -- Get the Class Code value, if there is one, --
14301       -- and try to get related Class Codes as well --
14302       ------------------------------------------------
14303       IF (l_class_code_name_value_pairs IS NOT NULL AND
14304           l_class_code_name_value_pairs.COUNT > 0) THEN
14305         DBMS_SQL.Column_Value(l_cursor_id, l_current_column_index, l_retrieved_value);
14306         l_current_column_index := l_current_column_index + 1;
14307         l_class_code_name_value_pairs(1).VALUE := SUBSTRB(l_retrieved_value, 1, 150);
14308 
14309         EXECUTE IMMEDIATE 'BEGIN '||p_related_class_code_function||'(:1, :2); END;'
14310         USING IN  l_class_code_name_value_pairs(1).VALUE,
14311               OUT l_class_code_name_value_pairs(2).VALUE;
14312       END IF;
14313 
14314       ----------------------------
14315       -- Determine the ACD Type --
14316       ----------------------------
14317       DBMS_SQL.Column_Value(l_cursor_id, l_current_column_index, l_retrieved_value);
14318       l_current_column_index := l_current_column_index + 1;
14319       l_current_acd_type := l_retrieved_value;
14320 
14321       ---------------------------------------------------------
14322       -- Find the Attr Group metadata from the Attr Group ID --
14323       ---------------------------------------------------------
14324       DBMS_SQL.Column_Value(l_cursor_id, l_current_column_index, l_retrieved_value);
14325       l_current_column_index := l_current_column_index + 1;
14326       l_attr_group_metadata_obj :=
14327         EGO_USER_ATTRS_COMMON_PVT.Get_Attr_Group_Metadata(
14328           p_attr_group_id => TO_NUMBER(l_retrieved_value)
14329         );
14330 
14331       ---------------------------------------------------------------
14332       -- Determine whether this Attr Group needs Data Level values --
14333       ---------------------------------------------------------------
14334       IF (Is_Data_Level_Correct
14335              (p_object_id                     => l_object_id
14336              ,p_attr_group_id                 => l_attr_group_metadata_obj.ATTR_GROUP_ID
14337              ,p_ext_table_metadata_obj        => l_ext_table_metadata_obj
14338              ,p_class_code_name_value_pairs   => l_class_code_name_value_pairs
14339              ,p_data_level                    => NULL
14340              ,p_data_level_name_value_pairs   => l_data_level_name_value_pairs
14341              ,p_attr_group_disp_name          => l_attr_group_metadata_obj.ATTR_GROUP_DISP_NAME
14342              ,x_err_msg_name                  => l_dummy_err_msg_name
14343              ,x_token_table                   => l_token_table)
14344          ) THEN
14345         l_current_dl_name_value_pairs := l_data_level_name_value_pairs;
14346       ELSE
14347         --------------------------------------------------------------------
14348         -- If the passed-in Data Levels are incorrect (e.g., they include --
14349         -- Revision ID for an Attr Group associated at the Item level),   --
14350         -- we will try to pass NULL and hope it works.  NOTE: this is an  --
14351         -- imperfect fix; it'll work for Items, but maybe not in general  --
14352         --------------------------------------------------------------------
14353 /***
14354 TO DO: make this logic more robust; right now it assumes that either
14355 we use all the passed-in Data Levels or none of them, but what about
14356 someday if there's a multi-DL implementation (i.e., one in which there's
14357 more than a binary situation of "passing DL" or "not passing DL"--e.g.,
14358 "passing some but not all DL")?
14359 ***/
14360         l_token_table.DELETE();
14361         l_current_dl_name_value_pairs := NULL;
14362       END IF;
14363 
14364       --------------------------
14365       -- Get the extension ID --
14366       --------------------------
14367       DBMS_SQL.Column_Value(l_cursor_id, l_current_column_index, l_retrieved_value);
14368       l_current_column_index := l_current_column_index + 1;
14369       l_current_pending_ext_id := TO_NUMBER(l_retrieved_value);
14370 
14371       -------------------------------------------------------------------
14372       -- Now we loop through the rest of the columns assigning values  --
14373       -- to Attr data objects, which we add to a table of such objects --
14374       -------------------------------------------------------------------
14375       FOR i IN l_current_column_index .. l_column_count
14376       LOOP
14377 
14378         -----------------------------------------------
14379         -- Get the current column name and its value --
14380         -----------------------------------------------
14381         l_current_column_name := l_desc_table(i).COL_NAME;
14382         DBMS_SQL.Column_Value(l_cursor_id, i, l_retrieved_value);
14383 
14384         ------------------------------------------------------------------------
14385         -- See whether the current column belongs to a User-Defined Attribute --
14386         ------------------------------------------------------------------------
14387         l_attr_metadata_obj := EGO_USER_ATTRS_COMMON_PVT.Find_Metadata_For_Attr(
14388                                  p_attr_metadata_table => l_attr_group_metadata_obj.attr_metadata_table
14389                                 ,p_db_column_name      => l_current_column_name
14390                                );
14391 
14392         ------------------------------------------------
14393         -- If the current column is an Attr column... --
14394         ------------------------------------------------
14395         IF (l_attr_metadata_obj IS NOT NULL AND
14396             l_attr_metadata_obj.ATTR_NAME IS NOT NULL) THEN
14397 
14398           -----------------------------------------------------
14399           -- ...then we add its value to our Attr data table --
14400           -----------------------------------------------------
14401           l_attr_name_value_pairs.EXTEND();
14402           l_attr_name_value_pairs(l_attr_name_value_pairs.LAST) :=
14403             EGO_USER_ATTR_DATA_OBJ(
14404               1
14405              ,l_attr_metadata_obj.ATTR_NAME
14406              ,null -- ATTR_VALUE_STR
14407              ,null -- ATTR_VALUE_NUM
14408              ,null -- ATTR_VALUE_DATE
14409              ,null -- ATTR_DISP_VALUE
14410              ,null -- ATTR_UNIT_OF_MEASURE (will be set below if necessary)
14411              ,-1
14412             );
14413 
14414           --------------------------------------------------------
14415           -- We assign l_retrieved_value according to data type --
14416           --------------------------------------------------------
14417           IF (l_attr_metadata_obj.DATA_TYPE_CODE = 'N') THEN
14418             -----------------------------
14419             -- We deal with UOMs below --
14420             -----------------------------
14421             l_attr_name_value_pairs(l_attr_name_value_pairs.LAST).ATTR_VALUE_NUM :=
14422               TO_NUMBER(l_retrieved_value);
14423           ELSIF (l_attr_metadata_obj.DATA_TYPE_CODE = 'X') THEN
14424             l_attr_name_value_pairs(l_attr_name_value_pairs.LAST).ATTR_VALUE_DATE :=
14425               TRUNC(TO_DATE(l_retrieved_value, EGO_USER_ATTRS_COMMON_PVT.G_DATE_FORMAT));
14426           ELSIF (l_attr_metadata_obj.DATA_TYPE_CODE = 'Y') THEN
14427             l_attr_name_value_pairs(l_attr_name_value_pairs.LAST).ATTR_VALUE_DATE :=
14428               TO_DATE(l_retrieved_value, EGO_USER_ATTRS_COMMON_PVT.G_DATE_FORMAT);
14429           ELSE
14430             l_attr_name_value_pairs(l_attr_name_value_pairs.LAST).ATTR_VALUE_STR :=
14431               l_retrieved_value;
14432           END IF;
14433         ELSIF (INSTR(l_current_column_name, 'UOM_') = 1) THEN
14434 
14435           --------------------------------------------
14436           -- Store the UOM column's name and value  --
14437           -- in a PL/SQL table for assignment below --
14438           --------------------------------------------
14439           l_uom_nv_pairs_index := l_uom_nv_pairs_index + 1;
14440           l_uom_column_nv_pairs(l_uom_nv_pairs_index) :=
14441             EGO_COL_NAME_VALUE_PAIR_OBJ(l_current_column_name, l_retrieved_value);
14442 
14443         ELSIF (l_current_column_name = 'LANGUAGE') THEN
14444 
14445           -------------------------------------------------------
14446           -- Determine the Language for passing to Process_Row --
14447           -------------------------------------------------------
14448           l_current_row_language := l_retrieved_value;
14449 
14450         ELSIF (l_current_column_name = 'SOURCE_LANG') THEN
14451 
14452           ------------------------------------------------
14453           -- Determine the Source Lang for knowing when --
14454           -- to insert a History row into the B table   --
14455           ------------------------------------------------
14456           l_current_row_source_lang := l_retrieved_value;
14457 
14458         END IF;
14459       END LOOP;
14460 
14461       ---------------------------------------------------------
14462       -- If we gathered any UOM data, we assign all gathered --
14463       -- UOM values to the appropriate Attr data object      --
14464       ---------------------------------------------------------
14465       IF (l_uom_nv_pairs_index > 0) THEN
14466 
14467         FOR i IN 1 .. l_uom_nv_pairs_index
14468         LOOP
14469 
14470           l_current_uom_col_nv_obj := l_uom_column_nv_pairs(i);
14471 
14472           ----------------------------------------------
14473           -- We derive the Attr's DB column name from --
14474           -- the UOM column name in one of two ways   --
14475           ----------------------------------------------
14476           IF (INSTR(l_current_uom_col_nv_obj.NAME, 'UOM_EXT_ATTR') = 1) THEN
14477             l_attr_col_name_for_uom_col := 'N_'||SUBSTR(l_current_uom_col_nv_obj.NAME, 5);
14478           ELSE
14479             l_attr_col_name_for_uom_col := SUBSTR(l_current_uom_col_nv_obj.NAME, 5);
14480           END IF;
14481 
14482           -------------------------------------------------------------
14483           -- Now we find the Attr from the column name we've derived --
14484           -- and set its Attr data object's UOM field with our value --
14485           -------------------------------------------------------------
14486           IF (l_attr_name_value_pairs IS NOT NULL AND
14487               l_attr_name_value_pairs.COUNT > 0) THEN
14488 
14489             l_attr_metadata_obj := EGO_USER_ATTRS_COMMON_PVT.Find_Metadata_For_Attr(
14490                                      p_attr_metadata_table => l_attr_group_metadata_obj.attr_metadata_table
14491                                     ,p_db_column_name      => l_attr_col_name_for_uom_col
14492                                    );
14493 
14494             ------------------------------------------------------------------
14495             -- If we found the metadata object, we look for the data object --
14496             ------------------------------------------------------------------
14497             IF (l_attr_metadata_obj IS NOT NULL AND
14498                 l_attr_metadata_obj.ATTR_NAME IS NOT NULL) THEN
14499 
14500               FOR j IN l_attr_name_value_pairs.FIRST .. l_attr_name_value_pairs.LAST
14501               LOOP
14502                 IF (l_attr_name_value_pairs(j).ATTR_NAME =
14503                     l_attr_metadata_obj.ATTR_NAME) THEN
14504 
14505                   -----------------------------------------------------------
14506                   -- When we find the data object, we set its UOM and exit --
14507                   -----------------------------------------------------------
14508                   l_attr_name_value_pairs(j).ATTR_UNIT_OF_MEASURE :=
14509                     l_current_uom_col_nv_obj.VALUE;
14510                   EXIT;
14511 
14512                 END IF;
14513               END LOOP;
14514             END IF;
14515           END IF;
14516         END LOOP;
14517       END IF;
14518 
14519       -------------------------------------------------------------------
14520       -- Now that we've got all necessary data and metadata, we try to --
14521       -- find a corresponding production row for this pending row; we  --
14522       -- use the new data level values if we have them, because we are --
14523       -- trying to see whether or not the row we're about to move into --
14524       -- the production table already exists there                     --
14525       -------------------------------------------------------------------
14526       l_current_production_ext_id :=
14527         Get_Extension_Id_For_Row(
14528           p_attr_group_metadata_obj     => l_attr_group_metadata_obj
14529          ,p_ext_table_metadata_obj      => l_ext_table_metadata_obj
14530          ,p_pk_column_name_value_pairs  => l_pk_column_name_value_pairs
14531          ,p_data_level_name_value_pairs => l_current_dl_name_value_pairs
14532          ,p_attr_name_value_pairs       => l_attr_name_value_pairs
14533         );
14534 
14535       ---------------------------------------------------------------------
14536       -- The mode and extension ID we pass to Process_Row are determined --
14537       -- by the existence of a production row, the ACD Type, and in some --
14538       -- cases by whether the Attr Group is single-row or multi-row      --
14539       ---------------------------------------------------------------------
14540       IF (l_current_acd_type = 'ADD') THEN
14541         IF (l_current_production_ext_id IS NULL) THEN
14542           ---------------------------------------
14543           -- If ACD Type is CREATE and there's --
14544           -- no production row, we create one  --
14545           ---------------------------------------
14546           l_mode_for_current_row := G_IMPLEMENT_CREATE_MODE;
14547           l_ext_id_for_current_row := l_current_pending_ext_id;
14548         ELSE
14549           IF (l_attr_group_metadata_obj.MULTI_ROW_CODE = 'N') THEN
14550             ------------------------------------------------------
14551             -- If ACD Type is CREATE, there's a production row, --
14552             -- and it's a single-row Attr Group, then someone   --
14553             -- created the row after this change was proposed,  --
14554             -- so we'll update the production row; we'll also   --
14555             -- copy the production Ext ID into the pending row  --
14556             -- to record the fact that this pending row updated --
14557             -- this production row                              --
14558             ------------------------------------------------------
14559             l_mode_for_current_row := G_UPDATE_MODE;
14560             l_ext_id_for_current_row := l_current_production_ext_id;
14561 
14562             ------------------------------------------------------------
14563             -- Process_Row will only process our pending B table row  --
14564             -- in the loop when LANGUAGE is NULL or when LANGUAGE =   --
14565             -- SOURCE_LANG, so we change the pending row in that loop --
14566             ------------------------------------------------------------
14567             IF (l_current_row_language IS NULL OR
14568                 l_current_row_language = l_current_row_source_lang) THEN
14569 
14570               l_utility_dynamic_sql := 'UPDATE '||p_change_b_table_name||
14571                                          ' SET EXTENSION_ID = :1'||
14572                                        ' WHERE EXTENSION_ID = :2'||
14573                                          ' AND ACD_TYPE = ''ADD'''||
14574                                          ' AND CHANGE_LINE_ID = :3';
14575               EXECUTE IMMEDIATE l_utility_dynamic_sql
14576               USING l_current_production_ext_id
14577                    ,l_current_pending_ext_id
14578                    ,p_change_line_id;
14579 
14580             END IF;
14581 
14582             l_utility_dynamic_sql := 'UPDATE '||p_change_tl_table_name||
14583                                        ' SET EXTENSION_ID = :1'||
14584                                      ' WHERE EXTENSION_ID = :2'||
14585                                        ' AND ACD_TYPE = ''ADD'''||
14586                                        ' AND CHANGE_LINE_ID = :3'||
14587                                        ' AND LANGUAGE = :4';
14588             EXECUTE IMMEDIATE l_utility_dynamic_sql
14589             USING l_current_production_ext_id
14590                  ,l_current_pending_ext_id
14591                  ,p_change_line_id
14592                  ,l_current_row_language;
14593 
14594           ELSE
14595             ---------------------------------------------------------------
14596             -- We let the ADD + multi-row + existing production row case --
14597             -- through so Get_Extension_Id_And_Mode can throw the error  --
14598             ---------------------------------------------------------------
14599             l_mode_for_current_row := G_IMPLEMENT_CREATE_MODE;
14600             l_ext_id_for_current_row := l_current_pending_ext_id;
14601           END IF;
14602         END IF;
14603       ELSIF (l_current_acd_type = 'CHANGE') THEN
14604         IF (l_current_production_ext_id IS NULL) THEN
14605           -------------------------------------------------------------
14606           -- In every case below, we'll use the pending extension ID --
14607           -------------------------------------------------------------
14608           l_ext_id_for_current_row := l_current_pending_ext_id;
14609 
14610           --
14611           -- TO DO: check if pendingExtID is in prod; if so, error
14612           --
14613 
14614           IF (l_attr_group_metadata_obj.MULTI_ROW_CODE = 'N') THEN
14615             -------------------------------------------------------
14616             -- If ACD Type is CHANGE, there's no production row, --
14617             -- and it's a single-row Attr Group, that means that --
14618             -- the row was somehow deleted since this change was --
14619             -- proposed, so we'll need to re-insert the row.     --
14620             -------------------------------------------------------
14621             l_mode_for_current_row := G_IMPLEMENT_CREATE_MODE;
14622           ELSE
14623             -------------------------------------------------------
14624             -- If ACD Type is CHANGE, there's no production row, --
14625             -- and it's a multi-row Attr Group, there are two    --
14626             -- possibilities: either the row was deleted since   --
14627             -- this change was proposed (in which case we will   --
14628             -- re-insert the row) or else this change involves   --
14629             -- changing Unique Key values (in which case the     --
14630             -- production row really does still exist, and we    --
14631             -- really do want to change it); we look for the     --
14632             -- production row using the pending extension ID to  --
14633             -- see which of these two possibilities we face now  --
14634             -------------------------------------------------------
14635             EXECUTE IMMEDIATE 'SELECT COUNT(1) FROM '||p_change_b_table_name||
14636                               ' WHERE EXTENSION_ID = :1'
14637             INTO l_dummy
14638             USING l_current_pending_ext_id;
14639 
14640             IF (l_dummy > 0) THEN
14641               l_mode_for_current_row := G_UPDATE_MODE;
14642             ELSE
14643               l_mode_for_current_row := G_IMPLEMENT_CREATE_MODE;
14644             END IF;
14645           END IF;
14646         ELSE
14647           ---------------------------------------
14648           -- If ACD Type is CHANGE and there's --
14649           -- a production row, we change it    --
14650           ---------------------------------------
14651           l_mode_for_current_row := G_UPDATE_MODE;
14652           l_ext_id_for_current_row := l_current_production_ext_id;
14653         END IF;
14654       ELSIF (l_current_acd_type = 'DELETE') THEN
14655         IF (l_current_production_ext_id IS NULL) THEN
14656           ---------------------------------------
14657           -- If ACD Type is DELETE and there's --
14658           -- no production row, we do nothing  --
14659           ---------------------------------------
14660           l_mode_for_current_row := 'SKIP';
14661         ELSE
14662           ---------------------------------------
14663           -- If ACD Type is DELETE and there's --
14664           -- a production row, we delete it    --
14665           ---------------------------------------
14666           l_mode_for_current_row := G_DELETE_MODE;
14667           l_ext_id_for_current_row := l_current_production_ext_id;
14668         END IF;
14669       END IF;
14670 
14671       IF (l_mode_for_current_row <> 'SKIP') THEN
14672 
14673         -----------------------------------------------------------
14674         -- If we're altering a production row, we first copy the --
14675         -- row into the pending tables with the ACD Type HISTORY --
14676         -----------------------------------------------------------
14677         IF (l_mode_for_current_row = G_DELETE_MODE OR
14678             l_mode_for_current_row = G_UPDATE_MODE) THEN
14679 
14680           -----------------------------------------------------------
14681           -- Process_Row will only process our pending B table row --
14682           -- in the loop when LANGUAGE is NULL or when LANGUAGE =  --
14683           -- SOURCE_LANG, so we insert a History row in that loop  --
14684           -----------------------------------------------------------
14685           IF (l_current_row_language IS NULL OR
14686               l_current_row_language = l_current_row_source_lang) THEN
14687             l_utility_dynamic_sql := ' INSERT INTO '||p_change_b_table_name||' CT ('||
14688                                      l_history_b_chng_cols_list||
14689                                      ', CT.CHANGE_ID, CT.CHANGE_LINE_ID, CT.ACD_TYPE'||
14690                                      ', CT.EXTENSION_ID) SELECT '||
14691                                      l_history_b_prod_cols_list||
14692                                      ', CT.CHANGE_ID, CT.CHANGE_LINE_ID, ''HISTORY'''||
14693                                      ', PT.EXTENSION_ID FROM '||
14694                                      p_production_b_table_name||' PT, '||
14695                                      p_change_b_table_name||
14696                                      ' CT WHERE PT.EXTENSION_ID = :1'||
14697                                      ' AND CT.EXTENSION_ID = :2'||
14698                                      ' AND CT.CHANGE_LINE_ID = :3'||
14699                                      ' AND CT.ACD_TYPE = :4';
14700 
14701             EXECUTE IMMEDIATE l_utility_dynamic_sql
14702             USING l_ext_id_for_current_row, l_current_pending_ext_id,
14703                   p_change_line_id, l_current_acd_type;
14704 
14705           END IF;
14706 
14707           ------------------------------------------------------------
14708           -- Process_Row will only process the pending TL table row --
14709           -- whose language matches LANGUAGE, so we only insert a   --
14710           -- History row for that row                               --
14711           ------------------------------------------------------------
14712           l_utility_dynamic_sql := ' INSERT INTO '||p_change_tl_table_name||' CT ('||
14713                                    l_history_tl_chng_cols_list||
14714                                    ', CT.CHANGE_ID, CT.CHANGE_LINE_ID, CT.ACD_TYPE'||
14715                                    ', CT.EXTENSION_ID) SELECT '||
14716                                    l_history_tl_prod_cols_list||
14717                                    ', CT.CHANGE_ID, CT.CHANGE_LINE_ID, ''HISTORY'''||
14718                                    ', PT.EXTENSION_ID FROM '||
14719                                    p_production_tl_table_name||' PT, '||
14720                                    p_change_tl_table_name||
14721                                    ' CT WHERE PT.EXTENSION_ID = :1'||
14722                                    ' AND CT.EXTENSION_ID = :2'||
14723                                    ' AND CT.CHANGE_LINE_ID = :3'||
14724                                    ' AND CT.ACD_TYPE = :4'||
14725                                    ' AND CT.LANGUAGE = PT.LANGUAGE AND CT.LANGUAGE = :5';
14726 
14727           EXECUTE IMMEDIATE l_utility_dynamic_sql
14728           USING l_ext_id_for_current_row, l_current_pending_ext_id,
14729                 p_change_line_id, l_current_acd_type, l_current_row_language;
14730 
14731         END IF;
14732 
14733         ---------------------------------------------------------------------
14734         -- Now at last we're ready to call Process_Row on this pending row --
14735         ---------------------------------------------------------------------
14736 
14737         Process_Row(
14738           p_api_version                   => 1.0
14739          ,p_object_name                   => p_object_name
14740          ,p_attr_group_id                 => l_attr_group_metadata_obj.ATTR_GROUP_ID
14741          ,p_application_id                => l_attr_group_metadata_obj.APPLICATION_ID
14742          ,p_attr_group_type               => l_attr_group_metadata_obj.ATTR_GROUP_TYPE
14743          ,p_attr_group_name               => l_attr_group_metadata_obj.ATTR_GROUP_NAME
14744          ,p_pk_column_name_value_pairs    => l_pk_column_name_value_pairs
14745          ,p_class_code_name_value_pairs   => l_class_code_name_value_pairs
14746          ,p_data_level_name_value_pairs   => l_current_dl_name_value_pairs
14747          ,p_extension_id                  => l_ext_id_for_current_row
14748          ,p_attr_name_value_pairs         => l_attr_name_value_pairs
14749          ,p_language_to_process           => l_current_row_language
14750          ,p_mode                          => l_mode_for_current_row
14751          ,p_add_errors_to_fnd_stack       => FND_API.G_TRUE
14752          ,x_return_status                 => x_return_status
14753          ,x_errorcode                     => x_errorcode
14754          ,x_msg_count                     => x_msg_count
14755          ,x_msg_data                      => x_msg_data
14756         );
14757 
14758         IF (x_return_status <> FND_API.G_RET_STS_SUCCESS) THEN
14759           RAISE FND_API.G_EXC_ERROR;
14760         END IF;
14761       END IF;
14762     END LOOP;
14763     DBMS_SQL.Close_Cursor(l_cursor_id);
14764 
14765     ---------------------------------------------------------------------------
14766     -- Finally, set the IMPLEMENTATION_DATE for all rows we just implemented --
14767     ---------------------------------------------------------------------------
14768     EXECUTE IMMEDIATE ' UPDATE '||p_change_b_table_name||
14769                          ' SET IMPLEMENTATION_DATE = :1'||
14770                        ' WHERE CHANGE_LINE_ID = :2'
14771     USING SYSDATE, p_change_line_id;
14772     EXECUTE IMMEDIATE ' UPDATE '||p_change_tl_table_name||
14773                          ' SET IMPLEMENTATION_DATE = :1'||
14774                        ' WHERE CHANGE_LINE_ID = :2'
14775     USING SYSDATE, p_change_line_id;
14776 
14777     IF FND_API.To_Boolean(p_commit) THEN
14778       COMMIT WORK;
14779     END IF;
14780 
14781     x_return_status := FND_API.G_RET_STS_SUCCESS;
14782 
14783     Debug_Msg('In Implement_Change_Line, done', 1);
14784 
14785   EXCEPTION
14786     WHEN FND_API.G_EXC_ERROR THEN
14787       Debug_Msg('In Implement_Change_Line, EXCEPTION FND_API.G_EXC_ERROR ', 1);
14788       IF FND_API.To_Boolean(p_commit) THEN
14789         ROLLBACK TO Implement_Change_Line_PUB;
14790       END IF;
14791       x_return_status := FND_API.G_RET_STS_ERROR;
14792 
14793       -----------------------------------------------------------------
14794       -- If Process_Row didn't return any errors, make one ourselves --
14795       -----------------------------------------------------------------
14796       IF (x_msg_data IS NULL AND x_msg_count = 0) THEN
14797         ERROR_HANDLER.Add_Error_Message(
14798           p_message_name              => 'EGO_EF_IMPLEMENT_ERR'
14799          ,p_application_id            => 'EGO'
14800          ,p_message_type              => FND_API.G_RET_STS_ERROR
14801          ,p_addto_fnd_stack           => 'Y'
14802         );
14803       END IF;
14804 
14805       -------------------------------------------------------------------
14806       -- If Process_Row had more than one error, return the first one  --
14807       -- (or else return the one we just added to ERROR_HANDLER above) --
14808       -------------------------------------------------------------------
14809       IF (x_msg_data IS NULL AND x_msg_count > 0) THEN
14810         DECLARE
14811           message_list  ERROR_HANDLER.Error_Tbl_Type;
14812         BEGIN
14813           ERROR_HANDLER.Get_Message_List(message_list);
14814           x_msg_data := message_list(message_list.FIRST).message_text;
14815         END;
14816       END IF;
14817 
14818     Debug_Msg('In Implement_Change_Line, got expected error: x_msg_data is '||x_msg_data, 3);
14819 
14820     WHEN OTHERS THEN
14821       Debug_Msg('In Implement_Change_Line, EXCEPTION OTHERS ', 1);
14822       IF FND_API.To_Boolean(p_commit) THEN
14823         ROLLBACK TO Implement_Change_Line_PUB;
14824       END IF;
14825       x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
14826 
14827       DECLARE
14828         l_dummy_entity_index     NUMBER;
14829         l_dummy_entity_id        VARCHAR2(60);
14830         l_dummy_message_type     VARCHAR2(1);
14831       BEGIN
14832         l_token_table(1).TOKEN_NAME := 'PKG_NAME';
14833         l_token_table(1).TOKEN_VALUE := G_PKG_NAME;
14834         l_token_table(2).TOKEN_NAME := 'API_NAME';
14835         l_token_table(2).TOKEN_VALUE := l_api_name;
14836         l_token_table(3).TOKEN_NAME := 'SQL_ERR_MSG';
14837         l_token_table(3).TOKEN_VALUE := SQLERRM;
14838 
14839         ERROR_HANDLER.Add_Error_Message(
14840           p_message_name                  => 'EGO_PLSQL_ERR'
14841          ,p_application_id                => 'EGO'
14842          ,p_token_tbl                     => l_token_table
14843          ,p_message_type                  => FND_API.G_RET_STS_ERROR
14844          ,p_addto_fnd_stack               => 'Y'
14845         );
14846 
14847         ERROR_HANDLER.Get_Message(x_message_text => x_msg_data
14848                                  ,x_entity_index => l_dummy_entity_index
14849                                  ,x_entity_id    => l_dummy_entity_id
14850                                  ,x_message_type => l_dummy_message_type);
14851       END;
14852 
14853     Debug_Msg('In Implement_Change_Line, got unexpected error: x_msg_data is '||x_msg_data, 3);
14854 
14855 END Implement_Change_Line;
14856 
14857 ----------------------------------------------------------------------
14858 
14859 --------------------------------------------------------------------
14860 -- This procedure retrieves directly from the extension table the --
14861 -- internal value for an attribute.                               --
14862 --------------------------------------------------------------------
14863 
14864 PROCEDURE Get_Ext_Data (
14865         p_attr_group_metadata_obj   IN   EGO_ATTR_GROUP_METADATA_OBJ
14866        ,p_attr_metadata_obj         IN   EGO_ATTR_METADATA_OBJ
14867        ,p_pk_col1                   IN   VARCHAR2
14868        ,p_pk_col2                   IN   VARCHAR2   DEFAULT NULL
14869        ,p_pk_col3                   IN   VARCHAR2   DEFAULT NULL
14870        ,p_pk_col4                   IN   VARCHAR2   DEFAULT NULL
14871        ,p_pk_col5                   IN   VARCHAR2   DEFAULT NULL
14872        ,p_pk_value1                 IN   VARCHAR2
14873        ,p_pk_value2                 IN   VARCHAR2   DEFAULT NULL
14874        ,p_pk_value3                 IN   VARCHAR2   DEFAULT NULL
14875        ,p_pk_value4                 IN   VARCHAR2   DEFAULT NULL
14876        ,p_pk_value5                 IN   VARCHAR2   DEFAULT NULL
14877        ,p_data_level                IN   VARCHAR2   DEFAULT NULL
14878        ,p_dl_pk_values              IN   EGO_COL_NAME_VALUE_PAIR_ARRAY DEFAULT NULL
14879        ,p_dl_metadata_obj           IN   EGO_DATA_LEVEL_METADATA_OBJ   DEFAULT NULL
14880        ,x_str_val                   OUT  NOCOPY     VARCHAR2
14881        ,x_num_val                   OUT  NOCOPY     NUMBER
14882        ,x_date_val                  OUT  NOCOPY     DATE
14883 )
14884 IS
14885 
14886     l_api_name               CONSTANT VARCHAR2(30) := 'Get_Ext_Data';
14887     l_db_column_alias        VARCHAR2(90);
14888     l_dynamic_sql            VARCHAR2(7000);
14889     l_bind_index             NUMBER;
14890     l_cursor                 NUMBER;
14891     l_row_count              NUMBER;
14892     l_str                    VARCHAR2(200);
14893 
14894 l_token_table          ERROR_HANDLER.Token_Tbl_Type;
14895 l_has_data_level_id    BOOLEAN  := FALSE;                   -- TRUE is for R12C
14896 
14897 -- In EGOBETRU.sql, we have the following type declaration:
14898 --   TYPE LOCAL_VARCHAR_TABLE        IS TABLE OF VARCHAR2(80)
14899 l_bind_value_table     LOCAL_VARCHAR_TABLE;
14900 l_bind_var_name        VARCHAR2(80);
14901 l_bind_var_value       VARCHAR2(80);
14902 l_bind_var_value_num       NUMBER;
14903 
14904 l_dl_pk_index          NUMBER;
14905 l_dl_metadata_obj      EGO_DATA_LEVEL_METADATA_OBJ;
14906 
14907 BEGIN
14908 
14909 Debug_Msg(l_api_name || '' );
14910 Debug_Msg(l_api_name || ' Get_Ext_Data (' );
14911 Debug_Msg(l_api_name || '   p_attr_group_metadata_obj => <not printed>');
14912 Debug_Msg(l_api_name || '   p_attr_metadata_obj       => <not printed>');
14913 Debug_Msg(l_api_name || '   p_pk_col1                 => ' || p_pk_col1);
14914 Debug_Msg(l_api_name || '   p_pk_col2                 => ' || p_pk_col2);
14915 Debug_Msg(l_api_name || '   p_pk_col3                 => ' || p_pk_col3);
14916 Debug_Msg(l_api_name || '   p_pk_col4                 => ' || p_pk_col4);
14917 Debug_Msg(l_api_name || '   p_pk_col5                 => ' || p_pk_col5);
14918 Debug_Msg(l_api_name || '   p_pk_value1               => ' || p_pk_value1);
14919 Debug_Msg(l_api_name || '   p_pk_value2               => ' || p_pk_value2);
14920 Debug_Msg(l_api_name || '   p_pk_value3               => ' || p_pk_value3);
14921 Debug_Msg(l_api_name || '   p_pk_value4               => ' || p_pk_value4);
14922 Debug_Msg(l_api_name || '   p_pk_value5               => ' || p_pk_value5);
14923 Debug_Msg(l_api_name || '   p_data_level              => ' || p_data_level);
14924 Debug_Msg(l_api_name || '   p_dl_pk_values            => <not printed>');
14925 Debug_Msg(l_api_name || '   p_dl_metadata_obj         => <not printed>');
14926 Debug_Msg(l_api_name || ' )' );
14927 
14928     --======================================================================--
14929     --                       1. Build the query                             --
14930     --======================================================================--
14931 
14932     x_str_val         := NULL;
14933     x_num_val         := NULL;
14934     x_date_val        := NULL;
14935 
14936     l_db_column_alias := EGO_USER_ATTRS_COMMON_PVT.Create_DB_Col_Alias_If_Needed(p_attr_metadata_obj);
14937 
14938     l_cursor          := DBMS_SQL.OPEN_CURSOR;
14939     l_bind_index      := 0;
14940 
14941     --------------------------
14942     -- SELECT, FROM clauses --
14943     --------------------------
14944 
14945     l_dynamic_sql := 'SELECT ' || l_db_column_alias ||
14946                      ' FROM ' || NVL(p_attr_group_metadata_obj.EXT_TABLE_VL_NAME
14947                                      ,p_attr_group_metadata_obj.EXT_TABLE_B_NAME) ||
14948                      ' WHERE ';
14949 
14950     ------------------------------------------
14951     -- WHERE conditions: Attribute Group ID --
14952     ------------------------------------------
14953 
14954     IF (p_attr_group_metadata_obj.ATTR_GROUP_ID_FLAG ='Y') THEN
14955       l_bind_value_table(l_bind_index) := p_attr_group_metadata_obj.ATTR_GROUP_ID;
14956 Debug_Msg(l_api_name || ' Bind value :' || (l_bind_index + 1) || ' has value ' || l_bind_value_table(l_bind_index) || ' (ATTR_GROUP_ID)');
14957       l_bind_index := l_bind_index + 1;
14958       l_dynamic_sql := l_dynamic_sql ||  ' ATTR_GROUP_ID = :1 AND ';
14959     END IF;
14960 
14961     -----------------------------------
14962     -- WHERE conditions: Primary key --
14963     -----------------------------------
14964 
14965     l_bind_value_table(l_bind_index) := p_pk_value1;
14966 Debug_Msg(l_api_name || ' Bind value :' || (l_bind_index + 1) || ' has value ' || l_bind_value_table(l_bind_index) || ' (' || p_pk_col1 || ')');
14967     l_bind_index := l_bind_index + 1;
14968     l_dynamic_sql := l_dynamic_sql || p_pk_col1 || ' = :' || l_bind_index;
14969 
14970 
14971     IF (p_pk_col2 IS NOT NULL) THEN
14972       l_bind_value_table(l_bind_index) := p_pk_value2;
14973 Debug_Msg(l_api_name || ' Bind value :' || (l_bind_index + 1) || ' has value ' || l_bind_value_table(l_bind_index) || ' (' || p_pk_col2 || ')');
14974       l_bind_index := l_bind_index + 1;
14975       l_dynamic_sql := l_dynamic_sql || ' AND ' || p_pk_col2 || ' = :' || l_bind_index;
14976 
14977       IF (p_pk_col3 IS NOT NULL) THEN
14978         l_bind_value_table(l_bind_index) := p_pk_value3;
14979 Debug_Msg(l_api_name || ' Bind value :' || (l_bind_index + 1) || ' has value ' || l_bind_value_table(l_bind_index) || ' (' || p_pk_col3 || ')');
14980         l_bind_index := l_bind_index + 1;
14981         l_dynamic_sql := l_dynamic_sql || ' AND ' || p_pk_col3 || ' = :' || l_bind_index;
14982 
14983         IF (p_pk_col4 IS NOT NULL) THEN
14984           l_bind_value_table(l_bind_index) := p_pk_value4;
14985           l_bind_index := l_bind_index + 1;
14986           l_dynamic_sql := l_dynamic_sql || ' AND ' || p_pk_col4 || ' = :' || l_bind_index;
14987 
14988           IF (p_pk_col5 IS NOT NULL) THEN
14989             l_bind_value_table(l_bind_index) := p_pk_value5;
14990             l_bind_index := l_bind_index + 1;
14991             l_dynamic_sql := l_dynamic_sql || ' AND ' || p_pk_col5 || ' = :' || l_bind_index;
14992           END IF;
14993         END IF;
14994       END IF;
14995     END IF;
14996 
14997     --------------------------------------------------------------
14998     -- WHERE conditions: Data Level ID, Data Level Primary Keys --
14999     --------------------------------------------------------------
15000 
15001     l_has_data_level_id := FND_API.TO_BOOLEAN(
15002                  EGO_USER_ATTRS_COMMON_PVT.has_column_in_table(p_table_name => p_attr_group_metadata_obj.EXT_TABLE_B_NAME
15003                                                               ,p_column_name => 'DATA_LEVEL_ID')
15004                                              );
15005 
15006     IF p_data_level IS NOT NULL AND l_has_data_level_id THEN
15007       IF p_dl_metadata_obj IS NULL THEN
15008           l_dl_metadata_obj := NULL;
15009           IF (p_attr_group_metadata_obj.ENABLED_DATA_LEVELS IS NOT NULL AND p_attr_group_metadata_obj.ENABLED_DATA_LEVELS.COUNT <> 0) THEN
15010 
15011             FOR dl_index IN p_attr_group_metadata_obj.ENABLED_DATA_LEVELS.FIRST .. p_attr_group_metadata_obj.ENABLED_DATA_LEVELS.LAST
15012             LOOP
15013 
15014               IF p_attr_group_metadata_obj.ENABLED_DATA_LEVELS(dl_index).data_level_name = p_data_level THEN
15015                 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);
15016 Debug_Msg(l_api_name || ' Data level found, exiting loop.');
15017                 -- exit the loop as we found the DL
15018                 EXIT;
15019               END IF;
15020 
15021             END LOOP;
15022 
15023             IF l_dl_metadata_obj IS NULL THEN
15024               -- the data level is not correct, flash error message.
15025               l_token_table(1).TOKEN_NAME := 'DL_NAME';
15026               l_token_table(1).TOKEN_VALUE := p_data_level;
15027               l_token_table(2).TOKEN_NAME := 'AG_NAME';
15028               l_token_table(2).TOKEN_VALUE := p_attr_group_metadata_obj.attr_group_disp_name;
15029               ERROR_HANDLER.Add_Error_Message(
15030                   p_message_name      => 'EGO_EF_DL_AG_INVALID'
15031                  ,p_application_id    => 'EGO'
15032                  ,p_token_tbl         => l_token_table
15033                  ,p_message_type      => FND_API.G_RET_STS_ERROR
15034                  ,p_row_identifier    => G_USER_ROW_IDENTIFIER
15035                  ,p_entity_id         => NULL
15036                  ,p_entity_index      => NULL
15037                  ,p_entity_code       => NULL
15038                  ,p_addto_fnd_stack   => G_ADD_ERRORS_TO_FND_STACK
15039                 );
15040               l_token_table.DELETE();
15041               RAISE FND_API.G_EXC_ERROR;
15042             END IF;
15043 
15044           END IF;
15045       ELSE
15046         l_dl_metadata_obj := p_dl_metadata_obj;
15047       END IF;
15048 
15049       IF l_dl_metadata_obj IS NOT NULL THEN
15050         l_bind_value_table(l_bind_index) := l_dl_metadata_obj.data_level_id;
15051         l_bind_index := l_bind_index + 1;
15052         l_dynamic_sql := l_dynamic_sql || ' AND DATA_LEVEL_ID = :' || l_bind_index;
15053         IF p_dl_pk_values IS NOT NULL AND p_dl_pk_values.COUNT > 0 THEN
15054           l_dl_pk_index := p_dl_pk_values.FIRST;
15055 
15056           WHILE (l_dl_pk_index <= p_dl_pk_values.LAST)
15057           LOOP
15058             IF p_dl_pk_values(l_dl_pk_index).NAME IS NOT NULL AND
15059                p_dl_pk_values(l_dl_pk_index).NAME IN
15060                      (l_dl_metadata_obj.pk_column_name1
15061                      ,l_dl_metadata_obj.pk_column_name2
15062                      ,l_dl_metadata_obj.pk_column_name3
15063                      ,l_dl_metadata_obj.pk_column_name4
15064                      ,l_dl_metadata_obj.pk_column_name5 ) THEN
15065               l_bind_value_table(l_bind_index) := p_dl_pk_values(l_dl_pk_index).NAME;
15066               l_bind_index := l_bind_index + 1;
15067               l_dynamic_sql := l_dynamic_sql || ' AND ' || p_dl_pk_values(l_dl_pk_index).NAME || ' = :' || l_bind_index;
15068             END IF;
15069             l_dl_pk_index := p_dl_pk_values.NEXT(l_dl_pk_index);
15070           END LOOP;
15071 
15072         END IF;
15073       END IF;
15074     END IF; -- p_data_level IS NOT NULL
15075 Debug_Msg(l_api_name || ' Query is:' );
15076 Debug_Msg(l_api_name || '   ' || l_dynamic_sql );
15077 Debug_Msg(l_api_name || ' ' );
15078 
15079     --======================================================================--
15080     --         2. Parse the query and bind the input variables              --
15081     --======================================================================--
15082 
15083     DBMS_SQL.PARSE(l_cursor, l_dynamic_sql, DBMS_SQL.NATIVE);
15084 
15085 Debug_Msg('Get_Ext_Data(): Bind value table has ' || l_bind_value_table.COUNT || ' elements');
15086 
15087     -- Bind the attribute group ID value, and the primary key values for the object
15088     FOR i IN l_bind_value_table.FIRST .. l_bind_value_table.LAST
15089     LOOP
15090        l_bind_var_name  := ':' || (i + 1);
15091        l_bind_var_value := l_bind_value_table(i);
15092        l_bind_var_value_num    := to_number(l_bind_var_value);
15093 Debug_Msg(l_api_name || ' Binding '|| l_bind_var_name || ' to value ' || l_bind_var_value_num);
15094 
15095       DBMS_SQL.BIND_VARIABLE(
15096         c      => l_cursor,                                        -- SQL query
15097         name   => l_bind_var_name,                        -- bind variable name
15098         value  => l_bind_var_value                 -- bind value (VARCHAR2(80))
15099       );
15100     END LOOP;
15101 
15102     ------------------------
15103     -- Define the outputs --
15104     ------------------------
15105     IF (p_attr_metadata_obj.DATA_TYPE_CODE = EGO_EXT_FWK_PUB.G_NUMBER_DATA_TYPE) THEN
15106       DBMS_SQL.DEFINE_COLUMN(l_cursor, 1, x_num_val);
15107     ELSIF (p_attr_metadata_obj.DATA_TYPE_CODE = 'X' OR p_attr_metadata_obj.DATA_TYPE_CODE = 'Y') THEN
15108       DBMS_SQL.DEFINE_COLUMN(l_cursor, 1, l_str,150);
15109     ELSE
15110       DBMS_SQL.DEFINE_COLUMN(l_cursor, 1, x_str_val, 150);
15111     END IF;
15112 
15113     --======================================================================--
15114     --    3. Execute the query and fetch the attribute internal value       --
15115     --======================================================================--
15116 
15117     l_row_count := DBMS_SQL.EXECUTE_AND_FETCH(l_cursor, FALSE);
15118     IF (l_row_count > 0) THEN
15119 
15120       IF (p_attr_metadata_obj.DATA_TYPE_CODE = 'N') THEN
15121         DBMS_SQL.COLUMN_VALUE(l_cursor, 1, x_num_val);
15122       ELSIF (p_attr_metadata_obj.DATA_TYPE_CODE = 'X' OR p_attr_metadata_obj.DATA_TYPE_CODE = 'Y') THEN
15123         DBMS_SQL.COLUMN_VALUE(l_cursor, 1, l_str);
15124         x_date_val := TO_DATE(l_str,EGO_USER_ATTRS_COMMON_PVT.G_DATE_FORMAT);
15125       ELSE
15126         DBMS_SQL.COLUMN_VALUE(l_cursor, 1, x_str_val);
15127       END IF;
15128     END IF;
15129 
15130     DBMS_SQL.CLOSE_CURSOR(l_cursor);
15131 
15132 Debug_Msg(l_api_name || ' Done.' );
15133 
15134 END Get_Ext_Data;
15135 
15136 ----------------------------------------------------------------------
15137 
15138 /*
15139  * Get_User_Attr_Val
15140  * -----------------
15141  */
15142 FUNCTION Get_User_Attr_Val (
15143         p_appl_id           IN   NUMBER
15144        ,p_attr_grp_type     IN   VARCHAR2
15145        ,p_attr_grp_name     IN   VARCHAR2               -- Attribute Group Name
15146        ,p_attr_name         IN   VARCHAR2                     -- Attribute Name
15147        ,p_object_name       IN   VARCHAR2
15148        ,p_pk_col1           IN   VARCHAR2
15149        ,p_pk_col2           IN   VARCHAR2   DEFAULT NULL
15150        ,p_pk_col3           IN   VARCHAR2   DEFAULT NULL
15151        ,p_pk_col4           IN   VARCHAR2   DEFAULT NULL
15152        ,p_pk_col5           IN   VARCHAR2   DEFAULT NULL
15153        ,p_pk_value1         IN   VARCHAR2
15154        ,p_pk_value2         IN   VARCHAR2   DEFAULT NULL
15155        ,p_pk_value3         IN   VARCHAR2   DEFAULT NULL
15156        ,p_pk_value4         IN   VARCHAR2   DEFAULT NULL
15157        ,p_pk_value5         IN   VARCHAR2   DEFAULT NULL
15158        ,p_data_level        IN   VARCHAR2   DEFAULT NULL
15159        ,p_dl_pk_values      IN   EGO_COL_NAME_VALUE_PAIR_ARRAY DEFAULT NULL
15160 )
15161 RETURN VARCHAR2
15162 IS
15163 
15164     l_api_name VARCHAR2(30) := 'Get_User_Attr_Val():';
15165     l_attr_group_metadata_obj      EGO_ATTR_GROUP_METADATA_OBJ;
15166                                                     -- declared in EGOSEFD2.sql
15167     l_attr_metadata_obj            EGO_ATTR_METADATA_OBJ;
15168     l_pk_column_name_value_pairs   EGO_COL_NAME_VALUE_PAIR_ARRAY;
15169     l_attr_int_value         VARCHAR2(1000);
15170     l_attr_disp_value        VARCHAR2(1000);
15171 
15172     l_attr_metadata_table    EGO_ATTR_METADATA_TABLE;
15173     l_attr_name_value_pairs  EGO_USER_ATTR_DATA_TABLE;
15174     l_attr_counter           NUMBER;
15175     l_temp_attr_metadata     EGO_ATTR_METADATA_OBJ;
15176     l_temp_str               VARCHAR2(150);
15177     l_temp_num               NUMBER;
15178     l_temp_date              DATE;
15179     --bug 5094087
15180     l_return_status          VARCHAR2(1);
15181     l_msg_count              NUMBER;
15182     l_msg_data               VARCHAR2(1000);
15183 
15184 l_token_table                 ERROR_HANDLER.Token_Tbl_Type;
15185 l_has_data_level_id           BOOLEAN  := TRUE;    -- TRUE is for R12C
15186 l_curr_data_level_metadata    EGO_DATA_LEVEL_METADATA_OBJ := NULL;
15187 l_curr_data_level_row_obj     EGO_DATA_LEVEL_ROW_OBJ;
15188 
15189   BEGIN
15190 
15191 Debug_Msg(l_api_name || '(');
15192 Debug_Msg(l_api_name || '    p_appl_id                 => ' || p_appl_id);
15193 Debug_Msg(l_api_name || '    p_attr_grp_type           => ' || p_attr_grp_type);
15194 Debug_Msg(l_api_name || '    p_attr_grp_name           => ' || p_attr_grp_name);
15195 Debug_Msg(l_api_name || '    p_attr_name               => ' || p_attr_name);
15196 Debug_Msg(l_api_name || '    p_object_name             => ' || p_object_name);
15197 Debug_Msg(l_api_name || '    p_pk_col1                 => ' || p_pk_col1);
15198 Debug_Msg(l_api_name || '    p_pk_col2                 => ' || p_pk_col2);
15199 Debug_Msg(l_api_name || '    p_pk_col3                 => ' || p_pk_col3);
15200 Debug_Msg(l_api_name || '    p_pk_col4                 => ' || p_pk_col4);
15201 Debug_Msg(l_api_name || '    p_pk_col5                 => ' || p_pk_col5);
15202 Debug_Msg(l_api_name || '    p_pk_value1               => ' || p_pk_value1);
15203 Debug_Msg(l_api_name || '    p_pk_value2               => ' || p_pk_value2);
15204 Debug_Msg(l_api_name || '    p_pk_value3               => ' || p_pk_value3);
15205 Debug_Msg(l_api_name || '    p_pk_value4               => ' || p_pk_value4);
15206 Debug_Msg(l_api_name || '    p_pk_value5               => ' || p_pk_value5);
15207 Debug_Msg(l_api_name || '    p_data_level              => ' || p_data_level);
15208 Debug_Msg(l_api_name || '    p_dl_pk_values            => <not printed>');
15209 Debug_Msg(l_api_name || ' )' );
15210 
15211     l_attr_int_value := NULL;
15212 
15213     -----------------------------------------
15214     -- Get or build the necessary metadata --
15215     -----------------------------------------
15216     l_attr_group_metadata_obj :=
15217       EGO_USER_ATTRS_COMMON_PVT.Get_Attr_Group_Metadata(
15218                                  p_application_id  => p_appl_id
15219                                 ,p_attr_group_type => p_attr_grp_type
15220                                 ,p_attr_group_name => p_attr_grp_name
15221                                );
15222 
15223     l_attr_metadata_table := l_attr_group_metadata_obj.attr_metadata_table;
15224     l_attr_metadata_obj := EGO_USER_ATTRS_COMMON_PVT.Find_Metadata_For_Attr(
15225                              p_attr_metadata_table => l_attr_group_metadata_obj.attr_metadata_table
15226                             ,p_attr_name           => p_attr_name
15227                            );
15228 
15229 Debug_Msg(l_api_name || ' Found attribute group metadata ');
15230 Debug_Msg(l_api_name || ' l_attr_metadata_obj (');
15231 Debug_Msg(l_api_name || '   ATTR_GROUP_ID              = ' || l_attr_group_metadata_obj.ATTR_GROUP_ID);
15232 Debug_Msg(l_api_name || '   APPLICATION_ID             = ' || l_attr_group_metadata_obj.APPLICATION_ID);
15233 Debug_Msg(l_api_name || '   ATTR_GROUP_TYPE            = ' || l_attr_group_metadata_obj.ATTR_GROUP_TYPE);
15234 Debug_Msg(l_api_name || '   ATTR_GROUP_NAME            = ' || l_attr_group_metadata_obj.ATTR_GROUP_NAME);
15235 Debug_Msg(l_api_name || '   ATTR_GROUP_DISP_NAME       = ' || l_attr_group_metadata_obj.ATTR_GROUP_DISP_NAME);
15236 Debug_Msg(l_api_name || '   AGV_NAME                   = ' || l_attr_group_metadata_obj.AGV_NAME);
15237 Debug_Msg(l_api_name || '   MULTI_ROW_CODE             = ' || l_attr_group_metadata_obj.MULTI_ROW_CODE);
15238 Debug_Msg(l_api_name || '   VIEW_PRIVILEGE             = ' || l_attr_group_metadata_obj.VIEW_PRIVILEGE);
15239 Debug_Msg(l_api_name || '   EDIT_PRIVILEGE             = ' || l_attr_group_metadata_obj.EDIT_PRIVILEGE);
15240 Debug_Msg(l_api_name || '   EXT_TABLE_B_NAME           = ' || l_attr_group_metadata_obj.EXT_TABLE_B_NAME);
15241 Debug_Msg(l_api_name || '   EXT_TABLE_TL_NAME          = ' || l_attr_group_metadata_obj.EXT_TABLE_TL_NAME);
15242 Debug_Msg(l_api_name || '   EXT_TABLE_VL_NAME          = ' || l_attr_group_metadata_obj.EXT_TABLE_VL_NAME);
15243 Debug_Msg(l_api_name || '   SORT_ATTR_VALUES_FLAG      = ' || l_attr_group_metadata_obj.SORT_ATTR_VALUES_FLAG);
15244 Debug_Msg(l_api_name || '   UNIQUE_KEY_ATTRS_COUNT     = ' || l_attr_group_metadata_obj.UNIQUE_KEY_ATTRS_COUNT);
15245 Debug_Msg(l_api_name || '   TRANS_ATTRS_COUNT          = ' || l_attr_group_metadata_obj.TRANS_ATTRS_COUNT);
15246 Debug_Msg(l_api_name || '   ATTR_METADATA_TABLE        = <not displayed>');
15247 Debug_Msg(l_api_name || '   ATTR_GROUP_ID_FLAG         = ' || l_attr_group_metadata_obj.ATTR_GROUP_ID_FLAG);
15248 Debug_Msg(l_api_name || '   HIERARCHY_NODE_QUERY       = ' || l_attr_group_metadata_obj.HIERARCHY_NODE_QUERY);
15249 Debug_Msg(l_api_name || '   HIERARCHY_PROPAGATION_API  = ' || l_attr_group_metadata_obj.HIERARCHY_PROPAGATION_API);
15250 Debug_Msg(l_api_name || '   HIERARCHY_PROPAGATE_FLAG   = ' || l_attr_group_metadata_obj.HIERARCHY_PROPAGATE_FLAG);
15251 Debug_Msg(l_api_name || '   ENABLED_DATA_LEVELS        =  <not displayed>');
15252 Debug_Msg(l_api_name || '   VARIANT                    = ' || l_attr_group_metadata_obj.VARIANT);
15253 Debug_Msg(l_api_name || ' )');
15254 
15255 
15256     -- Get data level metadata, if applicable
15257     IF p_data_level IS NOT NULL THEN
15258       -- check if the passed in data level is valid for this attribute group.
15259         Debug_Msg(l_api_name || ' Non-null data level');
15260         l_has_data_level_id := FND_API.TO_BOOLEAN(
15261                  EGO_USER_ATTRS_COMMON_PVT.has_column_in_table(p_table_name => l_attr_group_metadata_obj.EXT_TABLE_B_NAME
15262                                                               ,p_column_name => 'DATA_LEVEL_ID')
15263                                                  );
15264         IF l_has_data_level_id THEN
15265           l_curr_data_level_row_obj := NULL;
15266           Debug_Msg(l_api_name || ' Has Data Level');
15267           IF (l_attr_group_metadata_obj.ENABLED_DATA_LEVELS IS NOT NULL AND
15268               l_attr_group_metadata_obj.ENABLED_DATA_LEVELS.COUNT <> 0) THEN
15269 
15270             Debug_Msg(l_api_name || ' ' || l_attr_group_metadata_obj.ENABLED_DATA_LEVELS.COUNT || ' data level(s) enabled');
15271 
15272             ------------------------------------------------------------------
15273             -- See if the supplied data level is in the list of enabled     --
15274             -- data levels for this attribute group.                        --
15275             ------------------------------------------------------------------
15276             FOR dl_index IN l_attr_group_metadata_obj.ENABLED_DATA_LEVELS.FIRST ..
15277                             l_attr_group_metadata_obj.ENABLED_DATA_LEVELS.LAST
15278             LOOP
15279               Debug_Msg(l_api_name || ' enabled data level: ' ||
15280                         l_attr_group_metadata_obj.ENABLED_DATA_LEVELS(dl_index).data_level_name || '(' ||
15281                         l_attr_group_metadata_obj.ENABLED_DATA_LEVELS(dl_index).data_level_id || ')');
15282               IF l_attr_group_metadata_obj.ENABLED_DATA_LEVELS(dl_index).data_level_name = p_data_level THEN
15283                 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);
15284                 Debug_Msg(l_api_name || ' Found Data Level, finished searching.');
15285                 EXIT;
15286               END IF;
15287             END LOOP;
15288 
15289             ------------------------------------------------------------------
15290             -- If the specified data level was not in the list of enabled   --
15291             -- data levels flash error message.                             --
15292             ------------------------------------------------------------------
15293             IF l_curr_data_level_metadata IS NULL THEN
15294               Debug_Msg(l_api_name || ' Couldn''t find data level.');
15295               l_token_table(1).TOKEN_NAME  := 'DL_NAME';
15296               l_token_table(1).TOKEN_VALUE := p_data_level;
15297               l_token_table(2).TOKEN_NAME  := 'AG_NAME';
15298               l_token_table(2).TOKEN_VALUE := l_attr_group_metadata_obj.attr_group_name;
15299               ERROR_HANDLER.Add_Error_Message(
15300                   p_message_name      => 'EGO_EF_DL_AG_INVALID'
15301                  ,p_application_id    => 'EGO'
15302                  ,p_token_tbl         => l_token_table
15303                  ,p_message_type      => FND_API.G_RET_STS_ERROR
15304                  ,p_row_identifier    => G_USER_ROW_IDENTIFIER
15305                  ,p_entity_id         => NULL
15306                  ,p_entity_index      => NULL
15307                  ,p_entity_code       => NULL
15308                  ,p_addto_fnd_stack   => G_ADD_ERRORS_TO_FND_STACK
15309                 );
15310               l_token_table.DELETE();
15311               RAISE FND_API.G_EXC_ERROR;
15312             END IF;
15313 
15314           END IF;
15315         END IF;  -- has_data_level
15316 
15317     END IF;
15318 
15319     IF (p_pk_col2 IS NOT NULL AND
15320         p_pk_col3 IS NOT NULL AND
15321         p_pk_col4 IS NOT NULL AND
15322         p_pk_col5 IS NOT NULL) THEN
15323 
15324       l_pk_column_name_value_pairs := EGO_COL_NAME_VALUE_PAIR_ARRAY(
15325                                         EGO_COL_NAME_VALUE_PAIR_OBJ(p_pk_col1, p_pk_value1)
15326                                        ,EGO_COL_NAME_VALUE_PAIR_OBJ(p_pk_col2, p_pk_value2)
15327                                        ,EGO_COL_NAME_VALUE_PAIR_OBJ(p_pk_col3, p_pk_value3)
15328                                        ,EGO_COL_NAME_VALUE_PAIR_OBJ(p_pk_col4, p_pk_value4)
15329                                        ,EGO_COL_NAME_VALUE_PAIR_OBJ(p_pk_col5, p_pk_value5)
15330                                       );
15331 
15332     ------------------------------------------------------------------
15333     -- We build a name/value pair array for our Primary Keys to use --
15334     -- in tokenizing our query; NOTE: We assume (and require) that  --
15335     -- at least one Primary Key name/value pair is passed           --
15336     ------------------------------------------------------------------
15337     ELSIF (p_pk_col2 IS NOT NULL AND
15338            p_pk_col3 IS NOT NULL AND
15339            p_pk_col4 IS NOT NULL) THEN
15340 
15341       l_pk_column_name_value_pairs := EGO_COL_NAME_VALUE_PAIR_ARRAY(
15342                                         EGO_COL_NAME_VALUE_PAIR_OBJ(p_pk_col1, p_pk_value1)
15343                                        ,EGO_COL_NAME_VALUE_PAIR_OBJ(p_pk_col2, p_pk_value2)
15344                                        ,EGO_COL_NAME_VALUE_PAIR_OBJ(p_pk_col3, p_pk_value3)
15345                                        ,EGO_COL_NAME_VALUE_PAIR_OBJ(p_pk_col4, p_pk_value4)
15346                                       );
15347 
15348     ELSIF (p_pk_col2 IS NOT NULL AND
15349            p_pk_col3 IS NOT NULL) THEN
15350 
15351       l_pk_column_name_value_pairs := EGO_COL_NAME_VALUE_PAIR_ARRAY(
15352                                         EGO_COL_NAME_VALUE_PAIR_OBJ(p_pk_col1, p_pk_value1)
15353                                        ,EGO_COL_NAME_VALUE_PAIR_OBJ(p_pk_col2, p_pk_value2)
15354                                        ,EGO_COL_NAME_VALUE_PAIR_OBJ(p_pk_col3, p_pk_value3)
15355                                       );
15356 
15357     ELSIF (p_pk_col2 IS NOT NULL) THEN
15358 
15359       l_pk_column_name_value_pairs := EGO_COL_NAME_VALUE_PAIR_ARRAY(
15360                                         EGO_COL_NAME_VALUE_PAIR_OBJ(p_pk_col1, p_pk_value1)
15361                                        ,EGO_COL_NAME_VALUE_PAIR_OBJ(p_pk_col2, p_pk_value2)
15362                                       );
15363 
15364     ELSE
15365 
15366       l_pk_column_name_value_pairs := EGO_COL_NAME_VALUE_PAIR_ARRAY(
15367                                         EGO_COL_NAME_VALUE_PAIR_OBJ(p_pk_col1, p_pk_value1)
15368                                       );
15369 
15370     END IF;
15371 
15372     Debug_Msg('In Find_Metadata_For_Attr, about to get attribute''s internal value', 5);
15373 
15374     --------------------------------------------------------------------
15375     -- Build a query to get the Attribute's internal (database) value --
15376     -- NOTE: We assume an association at the top data level           --
15377     --------------------------------------------------------------------
15378     Get_Ext_Data(
15379         p_attr_group_metadata_obj  =>  l_attr_group_metadata_obj
15380        ,p_attr_metadata_obj        =>  l_attr_metadata_obj
15381        ,p_pk_col1                  =>  p_pk_col1
15382        ,p_pk_col2                  =>  p_pk_col2
15383        ,p_pk_col3                  =>  p_pk_col3
15384        ,p_pk_col4                  =>  p_pk_col4
15385        ,p_pk_col5                  =>  p_pk_col5
15386        ,p_pk_value1                =>  p_pk_value1
15387        ,p_pk_value2                =>  p_pk_value2
15388        ,p_pk_value3                =>  p_pk_value3
15389        ,p_pk_value4                =>  p_pk_value4
15390        ,p_pk_value5                =>  p_pk_value5
15391        ,p_data_level               =>  p_data_level
15392        ,p_dl_pk_values             =>  p_dl_pk_values
15393        ,p_dl_metadata_obj          =>  l_curr_data_level_metadata
15394        ,x_str_val                  =>  l_temp_str
15395        ,x_num_val                  =>  l_temp_num
15396        ,x_date_val                 =>  l_temp_date
15397     );
15398 
15399     Debug_Msg('In Find_Metadata_For_Attr, attribute''s internal value = ' || l_temp_str || l_temp_num || l_temp_date, 5);
15400 
15401     IF (l_temp_str IS NOT NULL) THEN
15402       l_attr_int_value := l_temp_str;
15403     ELSIF (l_temp_num IS NOT NULL) THEN
15404       l_attr_int_value := TO_CHAR(l_temp_num);
15405     ELSIF (l_temp_date IS NOT NULL) THEN
15406     --bug 5094087
15407       l_attr_int_value := TO_CHAR(l_temp_date,EGO_USER_ATTRS_COMMON_PVT.G_DATE_FORMAT);
15408     END IF;
15409 
15410     ----------------------------------------------------------
15411     -- At this point I have the internal value; if the Attr --
15412     -- has a display value, I need to try to get it instead --
15413     ----------------------------------------------------------
15414     -- fix for bug 4543638 included translatable independent validation code to get disp value
15415     IF (l_attr_metadata_obj.VALIDATION_CODE = EGO_EXT_FWK_PUB.G_INDEPENDENT_VALIDATION_CODE OR
15416         l_attr_metadata_obj.VALIDATION_CODE = EGO_EXT_FWK_PUB.G_TRANS_IND_VALIDATION_CODE OR
15417         l_attr_metadata_obj.VALIDATION_CODE = EGO_EXT_FWK_PUB.G_TABLE_VALIDATION_CODE) THEN
15418 
15419       ------------------------------------------------------------
15420       -- We must query up the rest of the attribute data in the --
15421       -- same group in case there are binds                     --
15422       ------------------------------------------------------------
15423       l_attr_name_value_pairs := EGO_USER_ATTR_DATA_TABLE();
15424 
15425       l_attr_counter := l_attr_metadata_table.FIRST();
15426       WHILE (l_attr_counter IS NOT NULL)
15427       LOOP
15428 
15429         l_temp_attr_metadata := l_attr_metadata_table(l_attr_counter);
15430         Get_Ext_Data(
15431             p_attr_group_metadata_obj  =>  l_attr_group_metadata_obj
15432            ,p_attr_metadata_obj        =>  l_temp_attr_metadata
15433            ,p_pk_col1                  =>  p_pk_col1
15434            ,p_pk_col2                  =>  p_pk_col2
15435            ,p_pk_col3                  =>  p_pk_col3
15436            ,p_pk_col4                  =>  p_pk_col4
15437            ,p_pk_col5                  =>  p_pk_col5
15438            ,p_pk_value1                =>  p_pk_value1
15439            ,p_pk_value2                =>  p_pk_value2
15440            ,p_pk_value3                =>  p_pk_value3
15441            ,p_pk_value4                =>  p_pk_value4
15442            ,p_pk_value5                =>  p_pk_value5
15443            ,p_data_level               =>  p_data_level
15444            ,p_dl_pk_values             =>  p_dl_pk_values
15445            ,p_dl_metadata_obj          =>  l_curr_data_level_metadata
15446            ,x_str_val                  =>  l_temp_str
15447            ,x_num_val                  =>  l_temp_num
15448            ,x_date_val                 =>  l_temp_date
15449         );
15450 
15451         l_attr_name_value_pairs.EXTEND();
15452         l_attr_name_value_pairs(l_attr_name_value_pairs.LAST) :=
15453           EGO_USER_ATTR_DATA_OBJ (
15454             1
15455            ,l_temp_attr_metadata.ATTR_NAME
15456            ,l_temp_str                                        -- ATTR_VALUE_STR
15457            ,l_temp_num                                        -- ATTR_VALUE_NUM
15458            ,l_temp_date                                      -- ATTR_VALUE_DATE
15459            ,NULL                                             -- ATTR_DISP_VALUE
15460            ,NULL                                        -- ATTR_UNIT_OF_MEASURE
15461            ,1
15462           );
15463 
15464         l_attr_counter := l_attr_metadata_table.NEXT(l_attr_counter);
15465 
15466       END LOOP;
15467 
15468       l_attr_disp_value := Get_Disp_Val_For_Int_Val(
15469                              p_attr_int_value                => l_attr_int_value
15470                             ,p_attr_metadata_obj             => l_attr_metadata_obj
15471                             ,p_attr_group_metadata_obj       => l_attr_group_metadata_obj
15472                             ,p_pk_column_name_value_pairs    => l_pk_column_name_value_pairs
15473                             ,p_object_name                   => p_object_name
15474                             ,p_attr_name_value_pairs         => l_attr_name_value_pairs
15475                            );
15476 
15477     END IF;
15478 
15479     -----------------------------------------------------
15480     -- If the Attr has no display value or we couldn't --
15481     -- find it, we simply return the internal value    --
15482     -----------------------------------------------------
15483     IF (l_attr_disp_value IS NULL) THEN
15484      --bug 5094087
15485       --------------------------------------------------------------
15486         -- If the Attribute is of Date or DateTime then we        --
15487         -- change the format to user preferences, else we return  --
15488         -- the obtained String as it is.                          --
15489         ------------------------------------------------------------
15490       IF ( l_attr_metadata_obj.DATA_TYPE_CODE IN
15491              (EGO_EXT_FWK_PUB.G_DATE_DATA_TYPE,
15492               EGO_EXT_FWK_PUB.G_DATE_TIME_DATA_TYPE) )
15493       THEN
15494         l_attr_disp_value := EGO_USER_ATTRS_COMMON_PVT.Get_User_Pref_Date_Time_Val(
15495                                        p_date => TO_DATE(l_attr_int_value,EGO_USER_ATTRS_COMMON_PVT.G_DATE_FORMAT)
15496                                       ,p_attr_type => l_attr_metadata_obj.DATA_TYPE_CODE
15497                                       ,x_return_status =>l_return_status
15498                                       ,x_msg_count     =>l_msg_count
15499                                       ,x_msg_data      =>l_msg_data
15500                                       );
15501       ELSE
15502          l_attr_disp_value := l_attr_int_value;
15503       END IF;
15504     END IF;
15505      --bug 5094087
15506      ------------------------------------------------------------
15507      -- If the Display value is NOT NULL and Attribute is of Date
15508      -- or DateTime and is coming from a Independent Type
15509      -- of Valueset then we change the format to user preferences,
15510      -- else we return the obtained String as it is.
15511      ------------------------------------------------------------
15512        IF ((l_attr_metadata_obj.VALIDATION_CODE = EGO_EXT_FWK_PUB.G_INDEPENDENT_VALIDATION_CODE )
15513            AND (l_attr_metadata_obj.DATA_TYPE_CODE IN
15514                  (EGO_EXT_FWK_PUB.G_DATE_DATA_TYPE,
15515                   EGO_EXT_FWK_PUB.G_DATE_TIME_DATA_TYPE)))
15516        THEN
15517         l_attr_disp_value := EGO_USER_ATTRS_COMMON_PVT.Get_User_Pref_Date_Time_Val(
15518                                      p_date => TO_DATE(l_attr_disp_value,EGO_USER_ATTRS_COMMON_PVT.G_DATE_FORMAT)
15519                                     ,p_attr_type => l_attr_metadata_obj.DATA_TYPE_CODE
15520                                     ,x_return_status =>l_return_status
15521                                     ,x_msg_count     =>l_msg_count
15522                                     ,x_msg_data      =>l_msg_data
15523                                     );
15524       END IF;
15525     RETURN l_attr_disp_value;
15526   ---------------------------------------------------------------------------------
15527   -- In case of any error, we try to return l_attr_int_value (which may be NULL) --
15528   ---------------------------------------------------------------------------------
15529   EXCEPTION
15530     WHEN OTHERS THEN
15531       Debug_Msg(' Get_User_Attr_Val EXCEPTION OTHERS '||SQLERRM);
15532       RETURN l_attr_int_value;
15533 
15534 END Get_User_Attr_Val;
15535 
15536 ----------------------------------------------------------------------
15537 
15538 PROCEDURE Set_Up_Debug_Session (
15539         p_entity_id                     IN   NUMBER
15540        ,p_entity_code                   IN   VARCHAR2
15541        ,p_debug_level                   IN   NUMBER DEFAULT 0
15542 ) IS
15543 
15544     l_output_dir             VARCHAR2(512);
15545     l_return_status          VARCHAR2(1);
15546     l_error_mesg             VARCHAR2(512);
15547 
15548   BEGIN
15549 
15550     IF (ERROR_HANDLER.Get_Debug() = 'N') THEN
15551 
15552       IF (p_debug_level > 0) THEN
15553 
15554         SELECT VALUE
15555           INTO l_output_dir
15556           FROM V$PARAMETER
15557          WHERE NAME = 'utl_file_dir';
15558 
15559         ---------------------------------------
15560         -- This global holds the debug level --
15561         ---------------------------------------
15562         G_DEBUG_OUTPUT_LEVEL := p_debug_level;
15563 
15564         ------------------------------------------------------
15565         -- Trim to get only the first directory in the list --
15566         ------------------------------------------------------
15567         IF (INSTR(l_output_dir, ',') > 0) THEN
15568           l_output_dir := SUBSTR(l_output_dir, 1, INSTR(l_output_dir, ',') - 1);
15569         END IF;
15570 
15571         ERROR_HANDLER.Open_Debug_Session(
15572           p_debug_filename   => 'EGO_USER_ATTRS_DATA_PVT-'||TO_CHAR(SYSDATE, 'J.SSSSS')||'.log'
15573          ,p_output_dir       => l_output_dir
15574          ,x_return_status    => l_return_status
15575          ,x_error_mesg       => l_error_mesg
15576         );
15577 
15578         IF (l_return_status <> FND_API.G_RET_STS_SUCCESS) THEN
15579 
15580           ERROR_HANDLER.Add_Error_Message(
15581             p_message_text      => l_error_mesg
15582            ,p_message_type      => 'E'
15583            ,p_entity_code       => p_entity_code
15584            ,p_addto_fnd_stack   => G_ADD_ERRORS_TO_FND_STACK
15585           );
15586 
15587         END IF;
15588       END IF;
15589     END IF;
15590 
15591 END Set_Up_Debug_Session;
15592 
15593 ----------------------------------------------------------------------
15594 
15595 PROCEDURE Update_Attributes (
15596           p_pk_column_name_value_pairs    IN EGO_COL_NAME_VALUE_PAIR_ARRAY
15597         , p_class_code_name_value_pairs   IN EGO_COL_NAME_VALUE_PAIR_ARRAY
15598         , p_data_level                    IN VARCHAR2  DEFAULT NULL
15599         , p_data_level_name_value_pairs   IN EGO_COL_NAME_VALUE_PAIR_ARRAY
15600         , p_attr_diffs                    IN EGO_USER_ATTR_DIFF_TABLE
15601         , p_transaction_type              IN VARCHAR2
15602         , p_attr_group_id                 IN NUMBER DEFAULT NULL
15603         , x_error_message                 OUT NOCOPY VARCHAR2
15604         )
15605   IS
15606 
15607     l_object_id                 NUMBER;
15608     l_attr_group_metadata_obj   EGO_ATTR_GROUP_METADATA_OBJ;
15609     l_ext_table_metadata_obj    EGO_EXT_TABLE_METADATA_OBJ;
15610     l_extension_id              NUMBER;
15611     l_old_attr_name_value_pairs EGO_USER_ATTR_DATA_TABLE;
15612     l_new_attr_name_value_pairs EGO_USER_ATTR_DATA_TABLE;
15613     l_mode                      VARCHAR2(10);
15614     l_return_status             VARCHAR2(1);
15615     l_row_identifier            NUMBER;
15616     l_max_row_identifier        NUMBER;
15617     l_perform_dml               BOOLEAN := TRUE;
15618     l_is_delete                 BOOLEAN;
15619 
15620 
15621   BEGIN
15622 
15623     -- get object id
15624     Debug_Msg('In Update_Attributes, called with transaction type '||p_transaction_type);
15625 
15626     l_object_id := Get_Object_Id_From_Name('EGO_ITEM');
15627 
15628     Debug_Msg('In Update_Attributes, retrieved l_object_id as '||l_object_id, 2);
15629     Debug_Msg('In Update_Attributes, getting AG metadata for '||p_attr_group_id, 2);
15630 
15631     l_attr_group_metadata_obj := EGO_USER_ATTRS_COMMON_PVT.Get_Attr_Group_Metadata
15632                                    ( p_attr_group_id => p_attr_group_id );
15633 
15634     Debug_Msg('In Update_Attributes, got AG metadata: '||
15635       l_attr_group_metadata_obj.attr_group_id||','||
15636       l_attr_group_metadata_obj.application_id||','||
15637       l_attr_group_metadata_obj.attr_group_type||','||
15638       l_attr_group_metadata_obj.attr_group_name||','||
15639       l_attr_group_metadata_obj.attr_group_disp_name
15640       , 2);
15641 
15642     l_ext_table_metadata_obj := EGO_USER_ATTRS_COMMON_PVT.Get_Ext_Table_Metadata(l_object_id);
15643     Convert_Attr_Diff_To_Data(p_attr_diffs, l_old_attr_name_value_pairs, FALSE, l_is_delete, x_error_message);
15644     Convert_Attr_Diff_To_Data(p_attr_diffs, l_new_attr_name_value_pairs, TRUE, l_is_delete, x_error_message);
15645 
15646     Debug_Msg('In Update_Attributes, got AG and ext table objs, getting ext id ');
15647 
15648     if l_old_attr_name_value_pairs is not null then
15649       for i in l_old_attr_name_value_pairs.FIRST .. l_old_attr_name_value_pairs.LAST loop
15650         Debug_Msg('In Update_Attributes, old('||i||') '
15651           ||l_old_attr_name_value_pairs(i).ROW_IDENTIFIER||','
15652           ||l_old_attr_name_value_pairs(i).ATTR_NAME||','
15653           ||l_old_attr_name_value_pairs(i).ATTR_VALUE_STR||','
15654           ||l_old_attr_name_value_pairs(i).ATTR_VALUE_NUM);
15655       end loop;
15656     end if;
15657     if l_new_attr_name_value_pairs is not null then
15658       for i in l_new_attr_name_value_pairs.FIRST .. l_new_attr_name_value_pairs.LAST loop
15659         Debug_Msg('In Update_Attributes, new('||i||') '
15660           ||l_new_attr_name_value_pairs(i).ROW_IDENTIFIER||','
15661           ||l_new_attr_name_value_pairs(i).ATTR_NAME||','
15662           ||l_new_attr_name_value_pairs(i).ATTR_VALUE_STR||','
15663           ||l_new_attr_name_value_pairs(i).ATTR_VALUE_NUM);
15664       end loop;
15665     end if;
15666 
15667     -- try to find an extension id, which tells us whether to CREATE/UPDATE/DELETE
15668     l_extension_id := Get_Extension_Id_For_Row
15669                           ( p_attr_group_metadata_obj     => l_attr_group_metadata_obj
15670                           , p_ext_table_metadata_obj      => l_ext_table_metadata_obj
15671                           , p_pk_column_name_value_pairs  => p_pk_column_name_value_pairs
15672                           , p_data_level                  => p_data_level
15673                           , p_data_level_name_value_pairs => p_data_level_name_value_pairs
15674                           , p_attr_name_value_pairs       => l_old_attr_name_value_pairs
15675                           );
15676 
15677     IF (l_extension_id IS NULL) THEN
15678 
15679       -- fallback on new values (to handle case where update_attrs is called
15680       -- redundantly on the each, which has already been updated)
15681 
15682       l_extension_id := Get_Extension_Id_For_Row
15683                           ( p_attr_group_metadata_obj     => l_attr_group_metadata_obj
15684                           , p_ext_table_metadata_obj      => l_ext_table_metadata_obj
15685                           , p_pk_column_name_value_pairs  => p_pk_column_name_value_pairs
15686                           , p_data_level                  => p_data_level
15687                           , p_data_level_name_value_pairs => p_data_level_name_value_pairs
15688                           , p_attr_name_value_pairs       => l_new_attr_name_value_pairs
15689                           );
15690 
15691     END IF;
15692 
15693     Debug_Msg('In Update_Attributes, using ext id '||l_extension_id);
15694 
15695     IF p_transaction_type = 'SYNC' THEN
15696       -- are we updating or deleting this row?
15697       --  uses data contained in diff object to find out
15698       IF (l_is_delete) THEN
15699         l_mode := G_DELETE_MODE;
15700       ELSE
15701         IF (l_extension_id IS NOT NULL) THEN
15702           l_mode := G_UPDATE_MODE;
15703         ELSE
15704           l_mode := G_CREATE_MODE;
15705         END IF;
15706       END IF;
15707     ELSE -- transaction type is DELETE
15708       l_mode := p_transaction_type;
15709       IF (l_extension_id IS NULL) THEN
15710         l_perform_dml := FALSE;
15711       END IF;
15712     END IF;   -- p_transaction_type = 'SYNC'
15713 
15714     IF l_perform_dml THEN
15715 
15716       Debug_Msg('In Update_Attributes, calling perform_dml_on_row_pvt with mode '||l_mode, 2);
15717 
15718       Perform_DML_On_Row_Pvt(
15719         p_api_version                   => 1.0
15720        ,p_object_id                     => l_object_id
15721        ,p_attr_group_metadata_obj       => l_attr_group_metadata_obj
15722        ,p_ext_table_metadata_obj        => l_ext_table_metadata_obj
15723        ,p_pk_column_name_value_pairs    => p_pk_column_name_value_pairs
15724        ,p_class_code_name_value_pairs   => p_class_code_name_value_pairs
15725        ,p_data_level                    => p_data_level
15726        ,p_data_level_name_value_pairs   => p_data_level_name_value_pairs
15727        ,p_extension_id                  => l_extension_id
15728        ,p_attr_name_value_pairs         => l_new_attr_name_value_pairs
15729        ,p_mode                          => l_mode
15730        ,p_commit                        => FND_API.G_FALSE
15731        ,p_bulkload_flag                 => TRUE
15732        ,x_extension_id                  => l_extension_id
15733        ,x_return_status                 => l_return_status
15734       );
15735       Debug_Msg('In Update_Attributes, Perform_DML_On_Row_Pvt returned with status '||l_return_status, 2);
15736     ELSE
15737       Debug_Msg('In Update_Attributes, skipped perform_dml');
15738     END IF;
15739 
15740     IF (l_return_status <> FND_API.G_RET_STS_SUCCESS) THEN
15741       Debug_Msg('In Update_Attributes, ERROR ret status: '||l_return_status, 2);
15742       RAISE FND_API.G_EXC_ERROR;
15743     END IF;
15744 
15745   EXCEPTION
15746     WHEN FND_API.G_EXC_ERROR THEN
15747       Debug_Msg('In Update_Attributes, EXCEPTION FND_API.G_EXC_ERROR');
15748       x_error_message := FND_API.G_RET_STS_ERROR;
15749 
15750 END Update_Attributes;
15751 
15752 ----------------------------------------------------------------------
15753 
15754 -- Either pass in attr_group_id or attr_group_name
15755 PROCEDURE Get_Attr_Diffs (
15756           p_object_name                   IN VARCHAR2
15757         , p_pk_column_name_value_pairs    IN EGO_COL_NAME_VALUE_PAIR_ARRAY
15758         , p_class_code_name_value_pairs   IN EGO_COL_NAME_VALUE_PAIR_ARRAY
15759         , p_data_level                    IN   VARCHAR2   DEFAULT NULL --R12C
15760         , p_data_level_name_value_pairs   IN EGO_COL_NAME_VALUE_PAIR_ARRAY
15761         , p_attr_group_id                 IN NUMBER DEFAULT NULL
15762         , p_application_id                IN NUMBER DEFAULT NULL
15763         , p_attr_group_type               IN VARCHAR2 DEFAULT NULL
15764         , p_attr_group_name               IN VARCHAR2 DEFAULT NULL
15765         , px_attr_diffs                   IN OUT NOCOPY EGO_USER_ATTR_DIFF_TABLE
15766         , x_error_message                 OUT NOCOPY VARCHAR2
15767         )
15768   IS
15769     l_attr_name_value_pairs               EGO_USER_ATTR_DATA_TABLE;
15770     l_attr_name_value_rec                 EGO_USER_ATTR_DATA_OBJ;
15771     l_attr_metadata_obj                   EGO_ATTR_METADATA_OBJ;
15772     l_ext_table_metadata_obj              EGO_EXT_TABLE_METADATA_OBJ;
15773     l_attr_group_metadata_obj             EGO_ATTR_GROUP_METADATA_OBJ;
15774     l_object_id                           NUMBER;
15775     l_attr_diffs                          EGO_USER_ATTR_DIFF_TABLE;
15776 
15777   BEGIN
15778 
15779     Debug_Msg('In Get_Attr_Diffs, starting');
15780 
15781     -- get list of attributes in this group
15782     l_attr_group_metadata_obj := EGO_USER_ATTRS_COMMON_PVT.Get_Attr_Group_Metadata
15783                                    ( p_attr_group_id
15784                                    , p_application_id
15785                                    , p_attr_group_type
15786                                    , p_attr_group_name
15787                                    );
15788 
15789     FOR i IN  l_attr_group_metadata_obj.attr_metadata_table.FIRST .. l_attr_group_metadata_obj.attr_metadata_table.LAST
15790     LOOP
15791 
15792       l_attr_metadata_obj := l_attr_group_metadata_obj.attr_metadata_table(i);
15793 
15794       IF (l_attr_name_value_pairs IS NULL) THEN
15795         l_attr_name_value_pairs := EGO_USER_ATTR_DATA_TABLE();
15796       END IF;
15797 
15798       -- add all attributes to the name_value pairs table, to pass into Get_Change_Attrs
15799       l_attr_name_value_pairs.EXTEND();
15800       l_attr_name_value_pairs(l_attr_name_value_pairs.LAST) :=
15801         EGO_USER_ATTR_DATA_OBJ(1
15802                               ,l_attr_metadata_obj.ATTR_NAME
15803                               ,null
15804                               ,null
15805                               ,null
15806                               ,null
15807                               ,null
15808                               ,1
15809                               );
15810 
15811     END LOOP;
15812 
15813     -- get other objects necessary for Get_Change_Attrs call
15814     l_object_id := Get_Object_Id_From_Name(p_object_name);
15815     l_ext_table_metadata_obj := EGO_USER_ATTRS_COMMON_PVT.Get_Ext_Table_Metadata(l_object_id);
15816 
15817     -- call Get_Changed_Attrs to get diffs as output
15818     Get_Changed_Attributes(
15819            p_dml_operation                 => 'UPDATE'
15820          , p_object_name                   =>  p_object_name
15821          , p_pk_column_name_value_pairs    =>  p_pk_column_name_value_pairs
15822          , p_attr_group_metadata_obj       =>  l_attr_group_metadata_obj
15823          , p_ext_table_metadata_obj        =>  l_ext_table_metadata_obj
15824          , p_data_level                    =>  p_data_level
15825          , p_data_level_name_value_pairs   =>  p_data_level_name_value_pairs
15826          , p_attr_name_value_pairs         =>  l_attr_name_value_pairs
15827          , p_extension_id                  =>  null
15828          , p_entity_id                     =>  null
15829          , p_entity_index                  =>  null
15830          , p_entity_code                   =>  null
15831          , px_attr_diffs                   =>  l_attr_diffs);
15832 
15833     -- Bug 4029064: need to remove diff object if both new and old values are null
15834     FOR i IN l_attr_diffs.FIRST .. l_attr_diffs.LAST
15835     LOOP
15836 
15837       IF (l_attr_diffs(i).old_attr_value_str IS NOT NULL OR
15838           l_attr_diffs(i).new_attr_value_str IS NOT NULL OR
15839           l_attr_diffs(i).old_attr_value_num IS NOT NULL OR
15840           l_attr_diffs(i).new_attr_value_num IS NOT NULL OR
15841           l_attr_diffs(i).old_attr_value_date IS NOT NULL OR
15842           l_attr_diffs(i).new_attr_value_date IS NOT NULL OR
15843           l_attr_diffs(i).old_attr_uom IS NOT NULL OR
15844           l_attr_diffs(i).new_attr_uom IS NOT NULL) THEN
15845 
15846         IF px_attr_diffs IS NULL THEN
15847           px_attr_diffs := EGO_USER_ATTR_DIFF_TABLE();
15848         END IF;
15849 
15850         px_attr_diffs.EXTEND();
15851         px_attr_diffs(px_attr_diffs.LAST) := l_attr_diffs(i);
15852 
15853       END IF;
15854 
15855     END LOOP;
15856 
15857     Debug_Msg('In Get_Attr_Diffs, finished');
15858 
15859   EXCEPTION
15860     WHEN OTHERS THEN
15861       Debug_Msg('In Get_Attr_Diffs, EXCEPTION FND_API.G_EXC_ERROR');
15862       RAISE FND_API.G_EXC_ERROR;
15863 
15864 END Get_Attr_Diffs;
15865 
15866 ---------------------------------------------------------------------------------
15867 /*
15868  * Get_Attr_Disp_Val_From_ValueSet
15869  * -------------------------------
15870  * Function returns the display value
15871  * of the attribute for a given internal value.
15872  */
15873  --gnanda api created for bug  4038065
15874 FUNCTION Get_Attr_Disp_Val_From_VSet (
15875          p_application_id               IN   NUMBER
15876         ,p_attr_internal_date_value     IN   DATE     DEFAULT NULL
15877         ,p_attr_internal_str_value      IN   VARCHAR2 DEFAULT NULL
15878         ,p_attr_internal_num_value      IN   NUMBER   DEFAULT NULL
15879         ,p_attr_internal_name           IN   VARCHAR2
15880         ,p_attr_group_type              IN   VARCHAR2
15881         ,p_attr_group_int_name          IN   VARCHAR2
15882         ,p_attr_id                      IN   NUMBER
15883         ,p_object_name                  IN   VARCHAR2
15884         ,p_pk1_column_name              IN   VARCHAR2
15885         ,p_pk1_value                    IN   VARCHAR2
15886         ,p_pk2_column_name              IN   VARCHAR2 DEFAULT NULL
15887         ,p_pk2_value                    IN   VARCHAR2 DEFAULT NULL
15888         ,p_pk3_column_name              IN   VARCHAR2 DEFAULT NULL
15889         ,p_pk3_value                    IN   VARCHAR2 DEFAULT NULL
15890         ,p_pk4_column_name              IN   VARCHAR2 DEFAULT NULL
15891         ,p_pk4_value                    IN   VARCHAR2 DEFAULT NULL
15892         ,p_pk5_column_name              IN   VARCHAR2 DEFAULT NULL
15893         ,p_pk5_value                    IN   VARCHAR2 DEFAULT NULL
15894         ,p_data_level1_column_name      IN   VARCHAR2 DEFAULT NULL
15895         ,p_data_level1_value            IN   VARCHAR2 DEFAULT NULL
15896         ,p_data_level2_column_name      IN   VARCHAR2 DEFAULT NULL
15897         ,p_data_level2_value            IN   VARCHAR2 DEFAULT NULL
15898         ,p_data_level3_column_name      IN   VARCHAR2 DEFAULT NULL
15899         ,p_data_level3_value            IN   VARCHAR2 DEFAULT NULL
15900 )
15901 RETURN VARCHAR2
15902 IS
15903        l_attr_value_obj                EGO_USER_ATTR_DATA_OBJ;
15904        l_attr_metadata_obj             EGO_ATTR_METADATA_OBJ;
15905        l_attr_metadata_obj_table       EGO_ATTR_METADATA_TABLE;
15906        l_attr_group_metadata_obj       EGO_ATTR_GROUP_METADATA_OBJ;
15907        l_pk_column_name_value_pairs    EGO_COL_NAME_VALUE_PAIR_ARRAY;
15908        l_data_level_name_value_pairs   EGO_COL_NAME_VALUE_PAIR_ARRAY;
15909        l_attr_disp_value               VARCHAR2(5000);
15910   BEGIN
15911        l_attr_value_obj :=  EGO_USER_ATTR_DATA_OBJ (null
15912                                                    ,p_attr_internal_name
15913                                                    ,p_attr_internal_str_value
15914                                                    ,p_attr_internal_num_value
15915                                                    ,p_attr_internal_date_value
15916                                                    ,null
15917                                                    ,null
15918                                                    ,null
15919                                                    );
15920 
15921        l_attr_group_metadata_obj := EGO_USER_ATTRS_COMMON_PVT.Get_Attr_Group_Metadata(
15922                                                     p_attr_group_id   => NULL
15923                                                    ,p_application_id  => p_application_id
15924                                                    ,p_attr_group_type => p_attr_group_type
15925                                                    ,p_attr_group_name => p_attr_group_int_name
15926                                                    );
15927 
15928 --todo:  why is this  here?
15929        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
15930          -- data level exists
15931 NULL;
15932        END IF;
15933 
15934        l_attr_metadata_obj_table := l_attr_group_metadata_obj.ATTR_METADATA_TABLE;
15935        IF l_attr_metadata_obj_table.count > 0 THEN
15936         FOR i IN l_attr_metadata_obj_table.FIRST .. l_attr_metadata_obj_table.LAST LOOP
15937          IF l_attr_metadata_obj_table(i).attr_name = p_attr_internal_name THEN
15938            l_attr_metadata_obj := l_attr_metadata_obj_table(i);
15939          END IF;
15940         END LOOP;
15941        END IF;
15942 
15943        l_pk_column_name_value_pairs := EGO_COL_NAME_VALUE_PAIR_ARRAY(
15944                                                     EGO_COL_NAME_VALUE_PAIR_OBJ(p_pk1_column_name,p_pk1_value)
15945                                                    ,EGO_COL_NAME_VALUE_PAIR_OBJ(p_pk2_column_name,p_pk2_value)
15946                                                    ,EGO_COL_NAME_VALUE_PAIR_OBJ(p_pk3_column_name,p_pk3_value)
15947                                                    ,EGO_COL_NAME_VALUE_PAIR_OBJ(p_pk4_column_name,p_pk4_value)
15948                                                    ,EGO_COL_NAME_VALUE_PAIR_OBJ(p_pk5_column_name,p_pk5_value)
15949                                                    );
15950        l_data_level_name_value_pairs :=  EGO_COL_NAME_VALUE_PAIR_ARRAY(
15951                                                     EGO_COL_NAME_VALUE_PAIR_OBJ(p_data_level1_column_name,p_data_level1_value)
15952                                                    ,EGO_COL_NAME_VALUE_PAIR_OBJ(p_data_level2_column_name,p_data_level2_value)
15953                                                    ,EGO_COL_NAME_VALUE_PAIR_OBJ(p_data_level3_column_name,p_data_level3_value)
15954                                                    );
15955        l_attr_disp_value := Get_Disp_Val_For_Int_Val(
15956                                                    p_attr_value_obj                => l_attr_value_obj
15957                                                   ,p_attr_metadata_obj             => l_attr_metadata_obj
15958                                                   ,p_attr_group_metadata_obj       => l_attr_group_metadata_obj
15959                                                   ,p_pk_column_name_value_pairs    => l_pk_column_name_value_pairs
15960                                                   ,p_data_level_name_value_pairs   => l_data_level_name_value_pairs
15961                                                   ,p_object_name                   => p_object_name
15962                                                   );
15963 
15964        RETURN l_attr_disp_value;
15965 
15966   EXCEPTION
15967     WHEN OTHERS THEN
15968       Debug_Msg('In Get_Attr_Disp_Val_From_ValueSet, got exception '||SQLERRM, 3);
15969       RETURN NULL;
15970 
15971 END Get_Attr_Disp_Val_From_VSet;
15972 
15973 
15974 
15975 
15976 /*
15977  * Get_Attr_Int_Val_From_VSet
15978  * -------------------------------
15979  * Function returns the internal value for a given display
15980  * value of the value set. In case the attribute does not have
15981  * a value set attached the display value privded to the api is
15982  * returned back.
15983  */
15984 
15985 ---------------------------------------------------------------------------
15986 FUNCTION Get_Attr_Int_Val_From_VSet (
15987          p_application_id               IN   NUMBER
15988         ,p_attr_disp_value              IN   VARCHAR2
15989         ,p_attr_internal_name           IN   VARCHAR2
15990         ,p_attr_group_type              IN   VARCHAR2
15991         ,p_attr_group_int_name          IN   VARCHAR2
15992         ,p_attr_group_id                IN   NUMBER
15993         ,p_attr_id                      IN   NUMBER
15994         ,p_return_intf_col              IN   VARCHAR2
15995         ,p_object_name                  IN   VARCHAR2
15996         ,p_ext_table_metadata_obj       IN   EGO_EXT_TABLE_METADATA_OBJ
15997         ,p_pk1_column_name              IN   VARCHAR2
15998         ,p_pk1_value                    IN   VARCHAR2
15999         ,p_pk2_column_name              IN   VARCHAR2
16000         ,p_pk2_value                    IN   VARCHAR2
16001         ,p_pk3_column_name              IN   VARCHAR2
16002         ,p_pk3_value                    IN   VARCHAR2
16003         ,p_pk4_column_name              IN   VARCHAR2
16004         ,p_pk4_value                    IN   VARCHAR2
16005         ,p_pk5_column_name              IN   VARCHAR2
16006         ,p_pk5_value                    IN   VARCHAR2
16007         ,p_data_level1_column_name      IN   VARCHAR2
16008         ,p_data_level1_value            IN   VARCHAR2
16009         ,p_data_level2_column_name      IN   VARCHAR2
16010         ,p_data_level2_value            IN   VARCHAR2
16011         ,p_data_level3_column_name      IN   VARCHAR2
16012         ,p_data_level3_value            IN   VARCHAR2
16013         ,p_entity_id                    IN   VARCHAR2
16014         ,p_entity_index                 IN   NUMBER
16015         ,p_entity_code                  IN   VARCHAR2
16016 )
16017 RETURN VARCHAR2
16018 IS
16019        l_attr_value_obj                EGO_USER_ATTR_DATA_OBJ;
16020        l_attr_metadata_obj             EGO_ATTR_METADATA_OBJ;
16021        l_attr_metadata_obj_table       EGO_ATTR_METADATA_TABLE;
16022        l_attr_group_metadata_obj       EGO_ATTR_GROUP_METADATA_OBJ;
16023        l_pk_column_name_value_pairs    EGO_COL_NAME_VALUE_PAIR_ARRAY;
16024        l_data_level_name_value_pairs   EGO_COL_NAME_VALUE_PAIR_ARRAY;
16025        l_attr_internal_value           VARCHAR2(4000);
16026        l_ext_table_metadata_obj        EGO_EXT_TABLE_METADATA_OBJ;
16027   BEGIN
16028        l_attr_value_obj :=  EGO_USER_ATTR_DATA_OBJ (null
16029                                                    ,p_attr_internal_name
16030                                                    ,null
16031                                                    ,null
16032                                                    ,null
16033                                                    ,p_attr_disp_value
16034                                                    ,null
16035                                                    ,null
16036                                                    );
16037        l_attr_group_metadata_obj := EGO_USER_ATTRS_COMMON_PVT.Get_Attr_Group_Metadata(
16038                                                     p_attr_group_id   => NULL
16039                                                    ,p_application_id  => p_application_id
16040                                                    ,p_attr_group_type => p_attr_group_type
16041                                                    ,p_attr_group_name => p_attr_group_int_name
16042                                                    );
16043 
16044        IF l_attr_group_metadata_obj IS NULL THEN
16045          RETURN NULL;
16046        END IF;
16047 
16048        l_attr_metadata_obj_table := l_attr_group_metadata_obj.ATTR_METADATA_TABLE;
16049        IF l_attr_metadata_obj_table.count > 0 THEN
16050         FOR i IN l_attr_metadata_obj_table.FIRST .. l_attr_metadata_obj_table.LAST LOOP
16051          IF l_attr_metadata_obj_table(i).attr_name = p_attr_internal_name THEN
16052            l_attr_metadata_obj := l_attr_metadata_obj_table(i);
16053          END IF;
16054         END LOOP;
16055        END IF;
16056 
16057       -- If the value
16058        BEGIN
16059           IF l_attr_metadata_obj IS NULL THEN
16060             RETURN NULL;
16061           ELSE
16062             IF l_attr_metadata_obj.VALUE_SET_ID IS NULL THEN
16063                -- if the data is coming from intf table we have a possibility that its not
16064                -- valid in terms of datatype. We return a null in such a case.
16065                IF p_return_intf_col IS NOT NULL THEN
16066                   IF (l_attr_metadata_obj.DATA_TYPE_CODE = EGO_EXT_FWK_PUB.G_NUMBER_DATA_TYPE)
16067                      AND (p_return_intf_col = 'ATTR_VALUE_NUM') THEN
16068                     RETURN TO_CHAR(TO_NUMBER(p_attr_disp_value));
16069                   ELSIF (l_attr_metadata_obj.DATA_TYPE_CODE = EGO_EXT_FWK_PUB.G_DATE_DATA_TYPE
16070                          OR l_attr_metadata_obj.DATA_TYPE_CODE = EGO_EXT_FWK_PUB.G_DATE_TIME_DATA_TYPE)
16071                         AND (p_return_intf_col = 'ATTR_VALUE_DATE') THEN
16072                     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);
16073                   ELSIF (l_attr_metadata_obj.DATA_TYPE_CODE = EGO_EXT_FWK_PUB.G_TRANS_TEXT_DATA_TYPE
16074                          OR l_attr_metadata_obj.DATA_TYPE_CODE = EGO_EXT_FWK_PUB.G_CHAR_DATA_TYPE)
16075                      AND (p_return_intf_col = 'ATTR_VALUE_STR') THEN
16076                     RETURN p_attr_disp_value;
16077                   ELSE
16078                     RETURN NULL;
16079                   END IF;
16080                ELSE
16081                  RETURN p_attr_disp_value;
16082                END IF;
16083             END IF;
16084           END IF;
16085        EXCEPTION
16086          WHEN OTHERS THEN
16087           RETURN NULL;
16088        END;
16089 
16090 
16091        -- This api can be used as a part of the VO query to fetch the internal values for
16092        -- an attribute in the interface table. In this case we will return a value only for
16093        -- the appropriate column.
16094        IF p_return_intf_col IS NOT NULL THEN
16095 
16096          IF p_return_intf_col = 'ATTR_VALUE_STR' THEN
16097             IF (l_attr_metadata_obj.DATA_TYPE_CODE <> EGO_EXT_FWK_PUB.G_TRANS_TEXT_DATA_TYPE
16098                 AND l_attr_metadata_obj.DATA_TYPE_CODE <> EGO_EXT_FWK_PUB.G_CHAR_DATA_TYPE)  THEN
16099                  RETURN NULL;
16100             END IF;
16101 
16102          ELSIF p_return_intf_col = 'ATTR_VALUE_NUM' THEN
16103             IF l_attr_metadata_obj.DATA_TYPE_CODE <> EGO_EXT_FWK_PUB.G_NUMBER_DATA_TYPE THEN
16104                  RETURN NULL;
16105             END IF;
16106 
16107          ELSIF p_return_intf_col = 'ATTR_VALUE_DATE' THEN
16108             IF (l_attr_metadata_obj.DATA_TYPE_CODE <> EGO_EXT_FWK_PUB.G_DATE_DATA_TYPE
16109                 AND l_attr_metadata_obj.DATA_TYPE_CODE <> EGO_EXT_FWK_PUB.G_DATE_TIME_DATA_TYPE)  THEN
16110                  RETURN NULL;
16111             END IF;
16112 
16113          END IF;
16114 
16115        END IF;
16116 
16117        l_pk_column_name_value_pairs := EGO_COL_NAME_VALUE_PAIR_ARRAY(
16118                     EGO_COL_NAME_VALUE_PAIR_OBJ(p_pk1_column_name,p_pk1_value)
16119                    ,EGO_COL_NAME_VALUE_PAIR_OBJ(p_pk2_column_name,p_pk2_value)
16120                    ,EGO_COL_NAME_VALUE_PAIR_OBJ(p_pk3_column_name,p_pk3_value)
16121                    ,EGO_COL_NAME_VALUE_PAIR_OBJ(p_pk4_column_name,p_pk4_value)
16122                    ,EGO_COL_NAME_VALUE_PAIR_OBJ(p_pk5_column_name,p_pk5_value)
16123                    );
16124 
16125        l_data_level_name_value_pairs :=  EGO_COL_NAME_VALUE_PAIR_ARRAY(
16126                     EGO_COL_NAME_VALUE_PAIR_OBJ(p_data_level1_column_name,p_data_level1_value)
16127                    ,EGO_COL_NAME_VALUE_PAIR_OBJ(p_data_level2_column_name,p_data_level2_value)
16128                    ,EGO_COL_NAME_VALUE_PAIR_OBJ(p_data_level3_column_name,p_data_level3_value)
16129                    );
16130 
16131 
16132       IF (p_ext_table_metadata_obj IS NOT NULL) THEN
16133         l_ext_table_metadata_obj := p_ext_table_metadata_obj;
16134       ELSE
16135         l_ext_table_metadata_obj := EGO_USER_ATTRS_COMMON_PVT.Get_Ext_Table_Metadata(Get_Object_Id_From_Name(p_object_name));
16136       END IF;
16137 
16138 
16139       l_attr_internal_value := Get_Int_Val_For_Disp_Val(
16140                     p_attr_metadata_obj           =>l_attr_metadata_obj
16141                    ,p_attr_value_obj              =>l_attr_value_obj
16142                    ,p_attr_group_metadata_obj     =>l_attr_group_metadata_obj
16143                    ,p_ext_table_metadata_obj      =>l_ext_table_metadata_obj
16144                    ,p_pk_column_name_value_pairs  =>l_pk_column_name_value_pairs
16145                    ,p_data_level_name_value_pairs =>l_data_level_name_value_pairs
16146                    ,p_entity_id                   =>p_entity_id
16147                    ,p_entity_index                =>p_entity_index
16148                    ,p_entity_code                 =>p_entity_code
16149                    ,p_attr_name_value_pairs       =>null
16150                    );
16151 
16152 
16153       BEGIN
16154         IF p_return_intf_col IS NOT NULL THEN
16155            IF (l_attr_metadata_obj.DATA_TYPE_CODE = EGO_EXT_FWK_PUB.G_NUMBER_DATA_TYPE)
16156                AND (p_return_intf_col = 'ATTR_VALUE_NUM') THEN
16157                   l_attr_internal_value := TO_CHAR(TO_NUMBER(l_attr_internal_value));
16158            ELSIF (l_attr_metadata_obj.DATA_TYPE_CODE = EGO_EXT_FWK_PUB.G_DATE_DATA_TYPE
16159                   OR l_attr_metadata_obj.DATA_TYPE_CODE = EGO_EXT_FWK_PUB.G_DATE_TIME_DATA_TYPE)
16160                   AND (p_return_intf_col = 'ATTR_VALUE_DATE') THEN
16161                      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);
16162            ELSIF (l_attr_metadata_obj.DATA_TYPE_CODE = EGO_EXT_FWK_PUB.G_TRANS_TEXT_DATA_TYPE
16163                   OR l_attr_metadata_obj.DATA_TYPE_CODE = EGO_EXT_FWK_PUB.G_CHAR_DATA_TYPE)
16164                   AND (p_return_intf_col = 'ATTR_VALUE_STR') THEN
16165                     l_attr_internal_value := l_attr_internal_value;
16166            END IF;
16167         END IF;
16168       EXCEPTION
16169          WHEN OTHERS THEN
16170           l_attr_internal_value := NULL;
16171       END;
16172 
16173 
16174       RETURN l_attr_internal_value;
16175 
16176 END Get_Attr_Int_Val_From_VSet;
16177 
16178 ---------------------------------------------------------------------------
16179 
16180 PROCEDURE Process_Data_Level_Nvp(
16181         p_data_level_name_value_pairs   IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
16182        ,x_data_level_obj                OUT NOCOPY  EGO_COL_NAME_VALUE_PAIR_OBJ
16183        ,x_data_level_index              OUT NOCOPY  NUMBER
16184 ) IS
16185     l_api_name VARCHAR2(30) := 'Process_data_level_nvp';
16186   BEGIN
16187 
16188 Debug_Msg(l_api_name||' starting', 2);
16189 
16190     IF p_data_level_name_value_pairs IS NULL THEN
16191 Debug_Msg(l_api_name||' p_data_level_name_value_pairs IS NULL. Returning.', 2);
16192       RETURN;
16193     END IF;
16194 
16195 
16196     IF p_data_level_name_value_pairs.COUNT > 0 THEN
16197       FOR i IN p_data_level_name_value_pairs.FIRST .. p_data_level_name_value_pairs.LAST
16198       LOOP
16199 
16200 Debug_Msg(l_api_name||' pair ' || i, 2);
16201 
16202         IF (i = p_data_level_name_value_pairs.FIRST AND
16203             p_data_level_name_value_pairs(i).NAME IS NOT NULL)
16204            OR
16205            (p_data_level_name_value_pairs(i).VALUE IS NOT NULL AND
16206             p_data_level_name_value_pairs(i).NAME IS NOT NULL)
16207         THEN
16208 
16209            x_data_level_obj   := p_data_level_name_value_pairs(i);
16210            x_data_level_index := i;
16211 
16212         END IF;
16213       END LOOP;
16214     ELSE
16215 Debug_Msg(l_api_name||' p_data_level_name_value_pairs.COUNT = ' || p_data_level_name_value_pairs.COUNT, 2);
16216     END IF;                       -- IF p_data_level_name_value_pairs.COUNT > 0
16217 
16218 
16219     IF x_data_level_obj IS NULL THEN
16220 Debug_Msg(l_api_name||' x_data_level_obj IS NULL', 2);
16221     ELSE
16222 Debug_Msg(l_api_name||' chosen data level pair = (' || x_data_level_obj.NAME || ', ' || x_data_level_obj.VALUE || ')', 2);
16223     END IF;
16224 Debug_Msg(l_api_name||' done', 2);
16225 
16226 END Process_Data_Level_Nvp;
16227 
16228 ---------------------------------------------------------------------------
16229 
16230 PROCEDURE Process_Class_Code_Nvp(
16231         p_class_code_name_value_pairs   IN         EGO_COL_NAME_VALUE_PAIR_ARRAY
16232        ,x_base_class_obj                OUT NOCOPY EGO_COL_NAME_VALUE_PAIR_OBJ
16233        ,x_related_class_obj             OUT NOCOPY EGO_COL_NAME_VALUE_PAIR_OBJ
16234 ) IS
16235     l_api_name  VARCHAR2(30) := 'Process_Class_Code_Nvp';
16236   BEGIN
16237 
16238     Debug_Msg(l_api_name||' starting', 2);
16239 
16240     IF p_class_code_name_value_pairs IS NULL THEN
16241       RETURN;
16242     END IF;
16243 
16244     FOR i IN p_class_code_name_value_pairs.FIRST .. p_class_code_name_value_pairs.LAST
16245     LOOP
16246 
16247       IF i = p_class_code_name_value_pairs.FIRST AND
16248          p_class_code_name_value_pairs(i).VALUE IS NOT NULL AND
16249          p_class_code_name_value_pairs(i).NAME IS NOT NULL
16250       THEN
16251 
16252          x_base_class_obj := p_class_code_name_value_pairs(i);
16253 
16254       ELSIF i = p_class_code_name_value_pairs.FIRST + 1 AND
16255             p_class_code_name_value_pairs(i).VALUE IS NOT NULL AND
16256             p_class_code_name_value_pairs(i).NAME IS NOT NULL
16257 
16258       THEN
16259 
16260          x_related_class_obj := p_class_code_name_value_pairs(i);
16261          exit;
16262 
16263       END IF;
16264     END LOOP;
16265 
16266     Debug_Msg(l_api_name||' base class code pair = (' ||
16267               x_base_class_obj.NAME || ', ' || x_base_class_obj.VALUE || ')', 3);
16268 
16269     Debug_Msg(l_api_name||' related class code pair = (' ||
16270               x_related_class_obj.NAME || ', ' || x_related_class_obj.VALUE || ')', 3);
16271 
16272     Debug_Msg(l_api_name||' done', 2);
16273 
16274 END Process_Class_Code_Nvp;
16275 
16276 ---------------------------------------------------------------------------
16277 
16278 PROCEDURE Build_Class_Code_Table(
16279         p_class_code_name_value_pairs   IN         EGO_COL_NAME_VALUE_PAIR_ARRAY
16280        ,x_class_code_table              OUT NOCOPY LOCAL_MEDIUM_VARCHAR_TABLE
16281 ) IS
16282     l_base_class_obj    EGO_COL_NAME_VALUE_PAIR_OBJ;
16283     l_related_class_obj EGO_COL_NAME_VALUE_PAIR_OBJ;
16284     l_remaining         VARCHAR2(300);
16285     l_current_val       VARCHAR2(300); --EGO_COL_NAME_VALUE_PAIR_OBJ.VALUE%TYPE;
16286     l_index             NUMBER;
16287   BEGIN
16288 
16289     Debug_Msg('In Build_Class_Code_Table, starting', 2);
16290 
16291     Process_Class_Code_Nvp(
16292         p_class_code_name_value_pairs  => p_class_code_name_value_pairs
16293        ,x_base_class_obj               => l_base_class_obj
16294        ,x_related_class_obj            => l_related_class_obj
16295     );
16296 
16297     IF l_base_class_obj IS NULL THEN
16298       RETURN;
16299     END IF;
16300 
16301     x_class_code_table(1) := l_base_class_obj.VALUE;
16302 
16303     IF l_related_class_obj IS NULL OR
16304        l_related_class_obj.VALUE IS NULL OR
16305        LENGTH(l_related_class_obj.VALUE) = 0
16306     THEN
16307       RETURN;
16308     END IF;
16309 
16310     l_remaining := l_related_class_obj.VALUE;
16311     l_index     := INSTR(l_remaining, ',');
16312 
16313     WHILE (l_index >  0) LOOP
16314        l_current_val := SUBSTR(l_remaining, 1, l_index - 1);
16315        l_remaining   := SUBSTR(l_remaining, l_index + 1, LENGTH(l_remaining));
16316 
16317        x_class_code_table(x_class_code_table.COUNT+1) := LTRIM(RTRIM(l_current_val));
16318 
16319        l_index := INSTR(l_remaining, ',');
16320     END LOOP;
16321 
16322     -- take care of the last value
16323     x_class_code_table(x_class_code_table.COUNT+1) := LTRIM(RTRIM(l_remaining));
16324 
16325     Debug_Msg('In Build_Class_Code_Table, done', 2);
16326 
16327 END Build_Class_Code_Table;
16328 
16329 /*----------------------------------------------------------------------------
16330 
16331   DESCRIPTION
16332     Extracts the values from the (column name, value) pairs in the
16333     data level pairs array and sets them as out parameters
16334 
16335   AUTHOR
16336     ssarnoba
16337 
16338   RELEASE
16339     R12C
16340 
16341   NOTES
16342     (-) If duplicate column names are specified, the last one's value is
16343         set to the out parameter
16344 
16345 ----------------------------------------------------------------------------*/
16346 PROCEDURE Extract_Data_Level_Values(
16347    p_data_level_name               IN   EGO_DATA_LEVEL_VL.DATA_LEVEL_NAME%TYPE
16348   ,p_data_level_name_value_pairs   IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
16349   ,x_data_level_1                  OUT  NOCOPY VARCHAR2
16350   ,x_data_level_2                  OUT  NOCOPY VARCHAR2
16351   ,x_data_level_3                  OUT  NOCOPY VARCHAR2
16352 )
16353 IS
16354    l_api_name              CONSTANT VARCHAR2(30) := 'Extract_Data_Level_Values';
16355    p_dl1_column                     VARCHAR2(20);
16356    p_dl2_column                     VARCHAR2(20);
16357    p_dl3_column                     VARCHAR2(20);
16358    iter_col_name                    VARCHAR2(150);
16359    iter_value                       VARCHAR2(150);
16360 
16361    CURSOR get_data_levek_col_names (cp_data_level_name EGO_DATA_LEVEL_B.DATA_LEVEL_NAME%TYPE)
16362    IS
16363    SELECT pk1_column_name, pk2_column_name, pk3_column_name
16364    FROM   ego_data_level_vl
16365    WHERE  data_level_name = cp_data_level_name;
16366 
16367 BEGIN
16368 
16369   Debug_Msg(l_api_name || '  Begin', 2);
16370   Debug_Msg(l_api_name || '  p_data_level_name - ' || p_data_level_name, 2);
16371 
16372   ----------------------------------------------------------------------------
16373   -- Determine which array element value will populate which OUT            --
16374   -- parameter                                                              --
16375   ----------------------------------------------------------------------------
16376 
16377   -- e.g.
16378   --
16379   --   (-) x_data_level_1 gets populated with the value from
16380   --       (PK2_VALUE, value)
16381   --   (-) x_data_level_2 gets populated with the value from
16382   --       (PK1_VALUE, value)00
16383 
16384   -- We can't use SELECT INTO because the WHERE clause contains a parameter,
16385   -- not a literal. The SQL engine cannot determine that only one row
16386   -- will be returned. So instead we have to use a cursor.
16387 
16388   OPEN get_data_levek_col_names (p_data_level_name);
16389   FETCH get_data_levek_col_names INTO p_dl1_column, p_dl2_column, p_dl3_column;
16390 
16391   Debug_Msg(l_api_name || '  PK Columns determined', 2);
16392   Debug_Msg(l_api_name || '    p_dl1_column: ' || p_dl1_column, 2);
16393   Debug_Msg(l_api_name || '    p_dl2_column: ' || p_dl2_column, 2);
16394   Debug_Msg(l_api_name || '    p_dl3_column: ' || p_dl3_column, 2);
16395 
16396   Debug_Msg(l_api_name || '  Number of data level pairs: ' || p_data_level_name_value_pairs.COUNT, 2);
16397 
16398   ----------------------------------------------------------------------------
16399   -- Iterate over the list and extract each value in the pair, placing it   --
16400   -- in one of the OUT parameters                                           --
16401   ----------------------------------------------------------------------------
16402 
16403   IF (p_data_level_name_value_pairs.COUNT > 0) THEN
16404 
16405     FOR i IN p_data_level_name_value_pairs.FIRST ..
16406              p_data_level_name_value_pairs.LAST
16407     LOOP
16408       Debug_Msg(l_api_name || '  data level pair ' || i, 2);
16409 
16410       -- Get the column name and value
16411       iter_col_name := p_data_level_name_value_pairs(i).NAME;
16412       iter_value    := p_data_level_name_value_pairs(i).VALUE;
16413 
16414       -- Put the value in the correct OUT parameter
16415       IF    (iter_col_name = p_dl1_column) THEN
16416         x_data_level_1 := iter_value;
16417       ELSIF (iter_col_name = p_dl2_column) THEN
16418         x_data_level_2 := iter_value;
16419       ELSIF (iter_col_name = p_dl3_column) THEN
16420         x_data_level_3 := iter_value;
16421       END IF;
16422 
16423     END LOOP;
16424 
16425   END IF;
16426 
16427   Debug_Msg(l_api_name || '  End', 2);
16428 
16429 END Extract_Data_Level_Values;
16430 
16431 
16432 ----------------------------------------------------------------------------
16433 
16434 
16435 PROCEDURE Process_Data_Level_Values(
16436         p_data_level_obj  IN         EGO_COL_NAME_VALUE_PAIR_OBJ
16437        ,p_data_level_ind  IN         NUMBER
16438        ,x_data_level_1    OUT NOCOPY VARCHAR2
16439        ,x_data_level_2    OUT NOCOPY VARCHAR2
16440        ,x_data_level_3    OUT NOCOPY VARCHAR2
16441 ) IS
16442 
16443   BEGIN
16444 
16445     Debug_Msg('In Process_Data_Level_Values, starting', 2);
16446 
16447     -- reset values
16448     x_data_level_1 := null;
16449     x_data_level_2 := null;
16450     x_data_level_3 := null;
16451 
16452     IF p_data_level_obj.VALUE IS NULL THEN
16453        RETURN;
16454     END IF;
16455 
16456     -- data level is 1 below the index, since index = 1
16457     -- corresponds to the top data level (data level 0)
16458     IF p_data_level_ind = 2 THEN
16459       x_data_level_1 := p_data_level_obj.VALUE;
16460     ELSIF p_data_level_ind = 3 THEN
16461       x_data_level_2 := p_data_level_obj.VALUE;
16462     ELSIF p_data_level_ind = 4 THEN
16463       x_data_level_3 := p_data_level_obj.VALUE;
16464     END IF;
16465 
16466     Debug_Msg('In Process_Data_Level_Values, done', 2);
16467 
16468 END Process_Data_Level_Values;
16469 
16470 
16471 /*----------------------------------------------------------------------------
16472   DESCRIPTION
16473     Builds a request table to validate attribute groups of an object
16474 
16475   NOTES
16476     (-) Only the attribute groups at the specified data level are added
16477         to the request object.
16478     (-) The object type EGO_ATTR_GROUP_REQUEST_OBJ is declared in
16479         EGOSEFD2.sql
16480 
16481 ----------------------------------------------------------------------------*/
16482 PROCEDURE Build_Request_Table_For_Obj(
16483         p_object_name                   IN   VARCHAR2
16484        ,p_class_code_name_value_pairs   IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
16485        ,p_data_level_name               IN   EGO_DATA_LEVEL_VL.DATA_LEVEL_NAME%TYPE
16486        ,p_data_level_name_value_pairs   IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
16487                                                    -- the data level key values
16488        ,p_attr_group_type_table         IN   EGO_VARCHAR_TBL_TYPE
16489        ,x_attr_group_request_table      OUT NOCOPY EGO_ATTR_GROUP_REQUEST_TABLE
16490 ) IS
16491 
16492     l_api_name              VARCHAR2(30) := 'Build_Request_Table_For_Obj';
16493     l_attributes_row_table  EGO_USER_ATTR_ROW_TABLE;
16494     l_attributes_data_table EGO_USER_ATTR_DATA_TABLE;
16495     l_data_level_obj        EGO_COL_NAME_VALUE_PAIR_OBJ;
16496     l_data_level_index      NUMBER;
16497     l_class_code_table      LOCAL_MEDIUM_VARCHAR_TABLE;
16498     l_attr_group_id         ego_obj_ag_assocs_b.attr_group_id%TYPE;
16499     l_data_level_1          VARCHAR2(150);
16500     l_data_level_2          VARCHAR2(150);
16501     l_data_level_3          VARCHAR2(150);
16502 
16503     CURSOR relevant_ag_w_data_level(
16504               p_data_level ego_obj_ag_assocs_b.data_level%TYPE
16505              ,p_class_code ego_obj_ag_assocs_b.classification_code%TYPE
16506              ,p_obj_name   fnd_objects.obj_name%TYPE
16507              ,p_ag_type    ego_fnd_dsc_flx_ctx_ext.descriptive_flexfield_name%TYPE)
16508     IS
16509      SELECT assoc.attr_group_id
16510        FROM ego_obj_ag_assocs_b assoc,
16511             fnd_objects object,
16512             ego_fnd_dsc_flx_ctx_ext ag
16513       WHERE assoc.classification_code     = p_class_code
16514         AND assoc.object_id               = object.object_id
16515         AND object.obj_name               = p_obj_name
16516         AND ag.descriptive_flexfield_name = p_ag_type
16517         AND ag.attr_group_id              = assoc.attr_group_id
16518         AND assoc.data_level              = p_data_level;
16519 
16520     CURSOR relevant_ag_wo_data_level(
16521               p_class_code ego_obj_ag_assocs_b.classification_code%TYPE
16522              ,p_obj_name   fnd_objects.obj_name%TYPE
16523              ,p_ag_type    ego_fnd_dsc_flx_ctx_ext.descriptive_flexfield_name%TYPE)
16524     IS
16525      SELECT assoc.attr_group_id
16526        FROM ego_obj_ag_assocs_b assoc,
16527             fnd_objects object,
16528             ego_fnd_dsc_flx_ctx_ext ag
16529       WHERE assoc.classification_code     = p_class_code
16530         AND assoc.object_id               = object.object_id
16531         AND object.obj_name               = p_obj_name
16532         AND ag.descriptive_flexfield_name = p_ag_type
16533         AND ag.attr_group_id              = assoc.attr_group_id;
16534 
16535   BEGIN
16536 
16537     Debug_Msg(l_api_name||' starting', 2);
16538 
16539     Debug_msg(l_api_name||' will request attribute group at ' ||
16540               p_data_level_name || ' for object ' || p_object_name ||
16541               ' to be validated');
16542 
16543     ---------------------------------------------------------
16544     -- Put the (class code name, value) pairs into a table --
16545     ---------------------------------------------------------
16546 
16547     Build_Class_Code_Table(
16548         p_class_code_name_value_pairs => p_class_code_name_value_pairs
16549        ,x_class_code_table            => l_class_code_table
16550     );
16551 
16552     Debug_Msg(l_api_name || ' finished building class code table', 2);
16553 
16554     --------------------------------------------------------------------
16555     -- Extract the values from the (column name, value) pairs in the  --
16556     -- data level pairs array                                         --
16557     --------------------------------------------------------------------
16558 
16559     Extract_Data_Level_Values(
16560         p_data_level_name               => p_data_level_name
16561        ,p_data_level_name_value_pairs   => p_data_level_name_value_pairs
16562        ,x_data_level_1                  => l_data_level_1
16563        ,x_data_level_2                  => l_data_level_2
16564        ,x_data_level_3                  => l_data_level_3
16565     );
16566 
16567     Debug_Msg(l_api_name||' extracted data level values', 2);
16568 
16569     --------------------------
16570     -- Build Request Table  --
16571     --------------------------
16572 
16573     IF x_attr_group_request_table IS NULL THEN
16574        x_attr_group_request_table := EGO_ATTR_GROUP_REQUEST_TABLE();
16575     END IF;
16576 
16577     IF p_attr_group_type_table.COUNT = 0 THEN
16578 Debug_Msg(l_api_name||' Attribute Group Type Table is empty', 2);
16579     END IF;
16580 
16581     IF l_class_code_table.COUNT = 0 THEN
16582 Debug_Msg(l_api_name||' Class Code Table is empty', 2);
16583     END IF;
16584 
16585     <<ag_types_loop>>
16586     FOR i IN 1 .. p_attr_group_type_table.COUNT LOOP
16587 
16588 Debug_Msg(l_api_name||' type table (' || i || ') = ' || p_attr_group_type_table(i), 2);
16589 
16590        <<class_code_loop>>
16591        FOR j IN 1 .. l_class_code_table.COUNT LOOP
16592 
16593 Debug_Msg(l_api_name||' class code (' || j || ') = ' || l_class_code_table(j), 2);
16594 Debug_Msg(l_api_name||' l_data_level_obj.NAME = ' || l_data_level_obj.NAME, 2);
16595 Debug_Msg(l_api_name||' p_object_name = ' || p_object_name, 2);
16596 
16597 
16598           IF p_data_level_name IS NOT NULL AND
16599              LENGTH(p_data_level_name) > 0
16600           THEN
16601 Debug_Msg(l_api_name||' p_data_level => ' || p_data_level_name , 3);
16602 Debug_Msg(l_api_name||' p_ag_type    => ' || p_attr_group_type_table(i), 3);
16603              OPEN relevant_ag_w_data_level(
16604                     p_data_level => p_data_level_name
16605                    ,p_class_code => l_class_code_table(j)
16606                    ,p_obj_name   => p_object_name
16607                    ,p_ag_type    => p_attr_group_type_table(i));
16608 
16609           ELSE
16610 Debug_Msg(l_api_name||' getting attribute groups not associated to any data level', 3);
16611              OPEN relevant_ag_wo_data_level(
16612                     p_class_code => l_class_code_table(j)
16613                    ,p_obj_name   => p_object_name
16614                    ,p_ag_type    => p_attr_group_type_table(i)
16615                    );
16616 
16617           END IF;
16618 
16619 Debug_Msg(l_api_name||' i = ' || i || ', j = ' || j, 2);
16620 
16621           --------------------------------------------------------------------
16622           -- Create a request object for eatch attribute group which        --
16623           -- eixsts at the specified data level                             --
16624           --------------------------------------------------------------------
16625 
16626           <<attr_groups_loop>>
16627           LOOP
16628 
16629 
16630              ---------------------------------
16631              -- Get the attribute group ID  --
16632              ---------------------------------
16633 
16634              IF relevant_ag_w_data_level%ISOPEN THEN
16635 Debug_Msg(l_api_name || ' fetching next AG ' || l_attr_group_id || ' with data level...', 2);
16636                 FETCH relevant_ag_w_data_level INTO l_attr_group_id;
16637                 EXIT WHEN relevant_ag_w_data_level%NOTFOUND;
16638              ELSE
16639                 FETCH relevant_ag_wo_data_level INTO l_attr_group_id;
16640 Debug_Msg(l_api_name || ' fetching next AG ' || l_attr_group_id || '  without data level...', 2);
16641                 EXIT WHEN relevant_ag_wo_data_level%NOTFOUND;
16642              END IF;
16643 
16644              Debug_Msg(l_api_name||' attribute group ID is ' || l_attr_group_id, 2);
16645 
16646              ------------------------------------------------------
16647              -- Append a request object for this attribute group --
16648              ------------------------------------------------------
16649 
16650              x_attr_group_request_table.EXTEND();
16651              x_attr_group_request_table(x_attr_group_request_table.LAST) :=
16652               EGO_ATTR_GROUP_REQUEST_OBJ(
16653                   l_attr_group_id                              -- ATTR_GROUP_ID
16654                  ,NULL                                        -- APPLICATION_ID
16655                  ,NULL                                       -- ATTR_GROUP_TYPE
16656                  ,NULL                                       -- ATTR_GROUP_NAME
16657                  ,p_data_level_name                               -- DATA_LEVEL
16658                  ,l_data_level_1                                -- DATA_LEVEL_1
16659                  ,l_data_level_2                                -- DATA_LEVEL_2
16660                  ,l_data_level_3                                -- DATA_LEVEL_3
16661                  ,NULL                                          -- DATA_LEVEL_4
16662                  ,NULL                                          -- DATA_LEVEL_5
16663                  ,NULL                                        -- ATTR_NAME_LIST
16664               );
16665 Debug_Msg(l_api_name || ' appended validation request for AG ' || l_attr_group_id, 2);
16666 
16667           END LOOP attr_groups_loop;
16668 Debug_Msg(l_api_name || ' exited attr_groups_loop', 3);
16669 
16670           IF relevant_ag_w_data_level%ISOPEN THEN
16671              CLOSE relevant_ag_w_data_level;
16672           ELSE
16673              CLOSE relevant_ag_wo_data_level;
16674          END IF;
16675 
16676        END LOOP class_code_loop;
16677 Debug_Msg(l_api_name || ' exited class_code_loop', 3);
16678     END LOOP ag_types_loop;
16679 
16680     Debug_Msg(l_api_name||' done', 2);
16681 
16682 END Build_Request_Table_For_Obj;
16683 
16684 ----------------------------------------------------------------------
16685 
16686 PROCEDURE Process_Req_Attr_Results(
16687         p_request_table          IN EGO_ATTR_GROUP_REQUEST_TABLE
16688        ,p_attributes_row_table   IN EGO_USER_ATTR_ROW_TABLE
16689        ,p_attributes_data_table  IN EGO_USER_ATTR_DATA_TABLE
16690        ,px_attributes_req_table  IN OUT NOCOPY EGO_USER_ATTR_TABLE
16691 ) IS
16692     l_has_value BOOLEAN;
16693     l_ix        NUMBER;
16694     l_api_name   VARCHAR2(30) := 'Process_Req_Attr_Results';
16695 
16696     CURSOR fetch_required_attr(
16697              p_ag_id    IN ego_attr_groups_v.attr_group_id%TYPE)
16698     IS
16699      SELECT attr.attr_name,
16700             attr.attr_display_name,
16701             ag.attr_group_id,
16702             ag.attr_group_name,
16703             ag.attr_group_disp_name,
16704             ag.attr_group_type,
16705             ag.application_id
16706        FROM ego_attrs_v attr ,
16707             ego_attr_groups_v ag
16708       WHERE ag.application_id = attr.application_id
16709         AND ag.attr_group_type = attr.attr_group_type
16710         AND ag.attr_group_name = attr.attr_group_name
16711         AND ag.attr_group_id = p_ag_id
16712         AND attr.required_flag = 'Y'
16713         AND attr.enabled_flag = 'Y';
16714 
16715   BEGIN
16716 
16717 Debug_Msg(l_api_name||' starting ', 2);
16718 
16719     IF p_request_table IS NULL THEN
16720 Debug_Msg(l_api_name||' returning as request table is NULL ', 2);
16721        RETURN;
16722     END IF;
16723 
16724 Debug_Msg(l_api_name||' request table size: ' || p_request_table.COUNT, 2);
16725 
16726     ------------------------------
16727     -- For each attribute group --
16728     ------------------------------
16729     FOR i IN 1 .. p_request_table.COUNT LOOP
16730 
16731        -------------------------------------
16732        -- Get all the required attributes --
16733        -------------------------------------
16734        FOR req_attr_rec IN fetch_required_attr(p_request_table(i).ATTR_GROUP_ID) LOOP
16735 
16736           l_has_value := FALSE;
16737 
16738           ------------------------------------------------
16739           -- Check to see if the attribute has any data --
16740           ------------------------------------------------
16741 
16742           IF p_attributes_row_table IS NOT NULL AND
16743              p_attributes_data_table IS NOT NULL
16744           THEN
16745 
16746 Debug_Msg(l_api_name||' p_attributes_data_table size: ' || p_attributes_data_table.COUNT, 2);
16747 
16748              FOR j IN 1 .. p_attributes_data_table.COUNT LOOP
16749 
16750               -- find the corresponding row object index
16751               l_ix := -1;
16752 
16753               FOR k IN 1 .. p_attributes_row_table.COUNT LOOP
16754                  IF p_attributes_row_table(k).ROW_IDENTIFIER =
16755                     p_attributes_data_table(j).ROW_IDENTIFIER
16756                  THEN
16757                    l_ix := k;
16758                    exit;
16759                  END IF;
16760               END LOOP;
16761 
16762               IF l_ix = -1 THEN
16763                  RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
16764               END IF;
16765 
16766               IF p_attributes_data_table(j).ATTR_NAME        = req_attr_rec.attr_name
16767                  AND
16768                  (p_attributes_row_table(l_ix).ATTR_GROUP_ID     = req_attr_rec.attr_group_id
16769                    OR
16770                   (p_attributes_row_table(l_ix).ATTR_GROUP_APP_ID = req_attr_rec.application_id AND
16771                    p_attributes_row_table(l_ix).ATTR_GROUP_TYPE   = req_attr_rec.attr_group_type AND
16772                    p_attributes_row_table(l_ix).ATTR_GROUP_NAME   = req_attr_rec.attr_group_name)
16773                  )
16774                  AND
16775                  (p_attributes_data_table(j).ATTR_VALUE_STR IS NOT NULL OR
16776                   p_attributes_data_table(j).ATTR_VALUE_NUM IS NOT NULL OR
16777                   p_attributes_data_table(j).ATTR_VALUE_DATE IS NOT NULL OR
16778                   p_attributes_data_table(j).ATTR_DISP_VALUE IS NOT NULL)
16779                THEN
16780                   l_has_value := TRUE;
16781 Debug_Msg(l_api_name|| p_attributes_data_table(j).ATTR_NAME || p_attributes_data_table(j).ATTR_VALUE_STR ||
16782           p_attributes_data_table(j).ATTR_VALUE_NUM || p_attributes_data_table(j).ATTR_VALUE_DATE || '(' ||
16783           p_attributes_data_table(j).ATTR_DISP_VALUE || ')', 2);
16784 
16785                   exit;
16786                END IF; -- if value exist for attr group
16787              END LOOP; -- p_attributes_data_table
16788           END IF; -- attr row and data NOT NULL
16789 
16790           --------------------------------------------------------------------
16791           -- If the attribute doesn't have a value, create an attribute     --
16792           -- descriptor object and add it to the results table, which       --
16793           -- contains the attribute descriptors of all required attributes  --
16794           -- that have violated the required property.                      --
16795           --------------------------------------------------------------------
16796 
16797           IF NOT l_has_value THEN
16798 
16799              IF px_attributes_req_table IS NULL THEN
16800                 px_attributes_req_table := EGO_USER_ATTR_TABLE();
16801              END IF;
16802 
16803              px_attributes_req_table.EXTEND();
16804              px_attributes_req_table(px_attributes_req_table.LAST) :=
16805                 EGO_USER_ATTR_OBJ(
16806                    req_attr_rec.application_id                -- APPLICATION_ID
16807                   ,req_attr_rec.attr_group_type              -- ATTR_GROUP_TYPE
16808                   ,req_attr_rec.attr_group_name              -- ATTR_GROUP_NAME
16809                   ,req_attr_rec.attr_group_disp_name    -- ATTR_GROUP_DISP_NAME
16810                   ,req_attr_rec.attr_name                          -- ATTR_NAME
16811                   ,req_attr_rec.attr_display_name             -- ATTR_DISP_NAME
16812                 );
16813 
16814 Debug_Msg(l_api_name|| req_attr_rec.attr_name || ' does not have a value', 2);
16815           ELSE
16816 Debug_Msg(l_api_name|| req_attr_rec.attr_name || ' has a value', 2);
16817           END IF; -- NOT l_has_value
16818        END LOOP; --fetch_required_attr
16819     END LOOP; --p_request_table
16820 
16821 Debug_Msg('Process_Req_Attr_Results, done', 2);
16822 
16823 END Process_Req_Attr_Results;
16824 
16825 ----------------------------------------------------------------------
16826 
16827 --
16828 -- NOTES
16829 --   (-) When an attribute that is required has no value, that attribute's
16830 --       details gets added to the output collection 'x_attributes_req_table'.
16831 --       The caller can read the entries in this table to find out which
16832 --       attributes violate their madatory property.
16833 --
16834 PROCEDURE Validate_Required_Attrs (
16835         p_api_version                   IN   NUMBER
16836        ,p_object_name                   IN   VARCHAR2
16837        ,p_pk_column_name_value_pairs    IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
16838        ,p_class_code_name_value_pairs   IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
16839        ,p_data_level_name               IN   EGO_DATA_LEVEL_B.DATA_LEVEL_NAME%TYPE := NULL
16840        ,p_data_level_name_value_pairs   IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
16841        ,p_attr_group_type_table         IN   EGO_VARCHAR_TBL_TYPE
16842        ,p_entity_id                     IN   NUMBER     DEFAULT NULL
16843        ,p_entity_index                  IN   NUMBER     DEFAULT NULL
16844        ,p_entity_code                   IN   VARCHAR2   DEFAULT NULL
16845        ,p_debug_level                   IN   NUMBER     DEFAULT 0
16846        ,p_init_error_handler            IN   VARCHAR2   DEFAULT FND_API.G_TRUE
16847        ,p_write_to_concurrent_log       IN   VARCHAR2   DEFAULT FND_API.G_FALSE
16848        ,p_init_fnd_msg_list             IN   VARCHAR2   DEFAULT FND_API.G_FALSE
16849        ,p_log_errors                    IN   VARCHAR2   DEFAULT FND_API.G_FALSE
16850        ,p_add_errors_to_fnd_stack       IN   VARCHAR2   DEFAULT FND_API.G_FALSE
16851        ,x_attributes_req_table          OUT NOCOPY EGO_USER_ATTR_TABLE
16852        ,x_return_status                 OUT NOCOPY VARCHAR2
16853        ,x_errorcode                     OUT NOCOPY NUMBER
16854        ,x_msg_count                     OUT NOCOPY NUMBER
16855        ,x_msg_data                      OUT NOCOPY VARCHAR2
16856 )IS
16857     l_api_name              CONSTANT VARCHAR2(30) := 'Validate_Required_Attrs';
16858     l_batch_size            CONSTANT NUMBER := 5;
16859     l_attributes_row_table  EGO_USER_ATTR_ROW_TABLE;
16860     l_attributes_data_table EGO_USER_ATTR_DATA_TABLE;
16861     l_request_table         EGO_ATTR_GROUP_REQUEST_TABLE;
16862                         -- request table for ALL attribute groups of the object
16863     l_request_table_batch_iter    EGO_ATTR_GROUP_REQUEST_TABLE;
16864                              -- request table for one batch of attribute groups
16865     l_attributes_req_table  EGO_USER_ATTR_TABLE;
16866     l_token_table           ERROR_HANDLER.Token_Tbl_Type;
16867 
16868   BEGIN
16869 
16870     Debug_Msg(l_api_name ||' starting', 2);
16871 
16872     --------------------------------------------------------------------------
16873     -- Build a Request Table for all attribute groups of the object to be   --
16874     -- validated.                                                           --
16875     --------------------------------------------------------------------------
16876 
16877     Build_Request_Table_For_Obj(
16878         p_object_name                   => p_object_name
16879        ,p_class_code_name_value_pairs   => p_class_code_name_value_pairs
16880        ,p_data_level_name               => p_data_level_name
16881        ,p_data_level_name_value_pairs   => p_data_level_name_value_pairs
16882        ,p_attr_group_type_table         => p_attr_group_type_table
16883        ,x_attr_group_request_table      => l_request_table
16884     );
16885 
16886     Debug_Msg(l_api_name||' Request Table for object has been built.', 2);
16887 
16888     IF l_request_table IS NULL THEN
16889        Debug_Msg(l_api_name||' Request Table for object is null so Returning.', 2);
16890        RETURN;
16891     END IF;
16892 
16893     --------------------------------------------------------------------------
16894     -- Build a Request Table which will contain the requests for just one   --
16895     -- batch of attribute groups per iteration                              --
16896     --------------------------------------------------------------------------
16897 
16898     l_request_table_batch_iter   := EGO_ATTR_GROUP_REQUEST_TABLE();
16899 
16900     IF l_request_table.COUNT = 0 THEN
16901        Debug_Msg(l_api_name||' Request Table for attribute group is empty so Returning', 2);
16902        RETURN;
16903     END IF;
16904 
16905     --------------------------------------------------------------------------
16906     -- Iterate through the request objects, and validate the attributes at  --
16907     -- the data level that particular request object specifies              --
16908     --------------------------------------------------------------------------
16909 
16910     FOR i IN 1 .. l_request_table.COUNT
16911     LOOP
16912 
16913        -----------------------------------------------------------------------
16914        -- Collect the request rows that belong to a single attribute group  --
16915        -----------------------------------------------------------------------
16916 
16917        l_request_table_batch_iter.EXTEND();
16918 
16919        IF mod(i, l_batch_size) = 0 THEN
16920           -- Start a new batch
16921           l_request_table_batch_iter(l_batch_size) := l_request_table(i);
16922        ELSE
16923           -- Append this request row to the current batch
16924           l_request_table_batch_iter(mod(i, l_batch_size)) := l_request_table(i);
16925        END IF;
16926 
16927        IF mod(i, l_batch_size) = 0 OR
16928           i = l_request_table.COUNT
16929        THEN
16930 
16931           --------------------------------------------------------------------
16932           -- Fetch the attribute values in this batch of attribute groups   --
16933           --------------------------------------------------------------------
16934           Get_User_Attrs_Data (
16935               p_api_version                   => p_api_version
16936              ,p_object_name                   => p_object_name
16937              ,p_pk_column_name_value_pairs    => p_pk_column_name_value_pairs
16938              ,p_attr_group_request_table      => l_request_table_batch_iter
16939              ,p_user_privileges_on_object     => NULL
16940              ,p_entity_id                     => p_entity_id
16941              ,p_entity_index                  => p_entity_index
16942              ,p_entity_code                   => p_entity_code
16943              ,p_debug_level                   => p_debug_level
16944              ,p_init_error_handler            => p_init_error_handler
16945              ,p_init_fnd_msg_list             => p_init_fnd_msg_list
16946              ,p_add_errors_to_fnd_stack       => p_add_errors_to_fnd_stack
16947              ,x_attributes_row_table          => l_attributes_row_table
16948              ,x_attributes_data_table         => l_attributes_data_table
16949              ,x_return_status                 => x_return_status
16950              ,x_errorcode                     => x_errorcode
16951              ,x_msg_count                     => x_msg_count
16952              ,x_msg_data                      => x_msg_data
16953           );
16954 
16955           IF l_attributes_data_table IS NULL THEN
16956 Debug_Msg(l_api_name||' l_attributes_data_table = NULL', 3);
16957           ELSE
16958 Debug_Msg(l_api_name||' l_attributes_data_table.COUNT = ' || l_attributes_data_table.COUNT, 3);
16959           END IF;
16960 
16961           -------------------------------------
16962           -- Populate result data structure  --
16963           -------------------------------------
16964           Process_Req_Attr_Results(
16965              p_request_table          => l_request_table_batch_iter
16966             ,p_attributes_row_table   => l_attributes_row_table
16967             ,p_attributes_data_table  => l_attributes_data_table
16968             ,px_attributes_req_table  => l_attributes_req_table
16969           );
16970 
16971           x_attributes_req_table := l_attributes_req_table;
16972 
16973           --reset transient variables
16974           l_request_table_batch_iter.DELETE;
16975 
16976           IF l_attributes_row_table IS NOT NULL THEN
16977              l_attributes_row_table.DELETE;
16978           END IF;
16979 
16980           IF l_attributes_data_table IS NOT NULL THEN
16981              l_attributes_data_table.DELETE;
16982           END IF;
16983 
16984        END IF;
16985 
16986     END LOOP;
16987 
16988     Debug_Msg(l_api_name||' done', 2);
16989 
16990   EXCEPTION
16991     WHEN FND_API.G_EXC_ERROR THEN
16992       x_return_status := FND_API.G_RET_STS_ERROR;
16993 
16994     WHEN OTHERS THEN
16995       x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
16996       l_token_table.DELETE();
16997       l_token_table(1).TOKEN_NAME := 'PKG_NAME';
16998       l_token_table(1).TOKEN_VALUE := G_PKG_NAME;
16999       l_token_table(2).TOKEN_NAME := 'API_NAME';
17000       l_token_table(2).TOKEN_VALUE := l_api_name;
17001       l_token_table(3).TOKEN_NAME := 'SQL_ERR_MSG';
17002       l_token_table(3).TOKEN_VALUE := SQLERRM;
17003 
17004       ERROR_HANDLER.Add_Error_Message(
17005         p_message_name              => 'EGO_PLSQL_ERR'
17006        ,p_application_id            => 'EGO'
17007        ,p_token_tbl                 => l_token_table
17008        ,p_message_type              => FND_API.G_RET_STS_ERROR
17009        ,p_row_identifier            => G_USER_ROW_IDENTIFIER
17010        ,p_entity_id                 => p_entity_id
17011        ,p_entity_index              => p_entity_index
17012        ,p_entity_code               => p_entity_code
17013        ,p_addto_fnd_stack           => G_ADD_ERRORS_TO_FND_STACK
17014       );
17015 
17016 END Validate_Required_Attrs;
17017 
17018 
17019 -----------------------------------------------
17020 -- Wrappers for Add_Bind and Init
17021 -----------------------------------------------
17022 
17023 PROCEDURE Add_Bind ( p_bind_identifier   IN VARCHAR2 DEFAULT NULL
17024                     ,p_value             IN VARCHAR2)
17025   IS
17026 BEGIN
17027    G_BIND_INDEX := G_BIND_INDEX + 1;
17028    G_BIND_IDENTIFIER_TBL(G_BIND_INDEX) := p_bind_identifier;
17029    G_BIND_DATATYPE_TBL(G_BIND_INDEX) := 'C';
17030    G_BIND_TEXT_TBL(G_BIND_INDEX) := p_value;
17031    FND_DSQL.Add_Bind(p_value);
17032 END Add_Bind; --VARCHAR2
17033 
17034 ----------------------------------------------------------------------
17035 
17036 PROCEDURE Add_Bind ( p_bind_identifier   IN VARCHAR2 DEFAULT NULL
17037                     ,p_value             IN DATE)
17038   IS
17039 BEGIN
17040    G_BIND_INDEX := G_BIND_INDEX + 1;
17041    G_BIND_IDENTIFIER_TBL(G_BIND_INDEX) := p_bind_identifier;
17042    G_BIND_DATATYPE_TBL(G_BIND_INDEX) := 'D';
17043    G_BIND_DATE_TBL(G_BIND_INDEX) := p_value;
17044    FND_DSQL.Add_Bind(p_value);
17045 END Add_Bind; --DATE
17046 
17047 ----------------------------------------------------------------------
17048 
17049 PROCEDURE Add_Bind ( p_bind_identifier   IN VARCHAR2 DEFAULT NULL
17050                     ,p_value             IN NUMBER)
17051   IS
17052 BEGIN
17053    G_BIND_INDEX := G_BIND_INDEX + 1;
17054    G_BIND_IDENTIFIER_TBL(G_BIND_INDEX) := p_bind_identifier;
17055    G_BIND_DATATYPE_TBL(G_BIND_INDEX) := 'N';
17056    G_BIND_NUMBER_TBL(G_BIND_INDEX) := p_value;
17057    FND_DSQL.Add_Bind(p_value);
17058 END Add_Bind; --NUMBER
17059 
17060 ----------------------------------------------------------------------
17061 
17062 PROCEDURE Set_Binds_And_Dml (p_sql IN VARCHAR2
17063                             ,p_mode IN VARCHAR2)
17064  IS
17065 BEGIN
17066 
17067  IF(p_mode = 'B') THEN
17068    G_B_TABLE_DML           := p_sql;
17069    G_B_BIND_INDEX          := G_BIND_INDEX;
17070    G_B_BIND_IDENTIFIER_TBL   := G_BIND_IDENTIFIER_TBL;
17071    G_B_BIND_DATATYPE_TBL   := G_BIND_DATATYPE_TBL;
17072    G_B_BIND_TEXT_TBL       := G_BIND_TEXT_TBL;
17073    G_B_BIND_DATE_TBL       := G_BIND_DATE_TBL;
17074    G_B_BIND_NUMBER_TBL     := G_BIND_NUMBER_TBL;
17075  ELSIF (p_mode='TL') THEN
17076    G_TL_TABLE_DML          := p_sql;
17077    G_TL_BIND_INDEX         := G_BIND_INDEX;
17078    G_TL_BIND_IDENTIFIER_TBL   := G_BIND_IDENTIFIER_TBL;
17079    G_TL_BIND_DATATYPE_TBL  := G_BIND_DATATYPE_TBL;
17080    G_TL_BIND_TEXT_TBL      := G_BIND_TEXT_TBL;
17081    G_TL_BIND_DATE_TBL      := G_BIND_DATE_TBL;
17082    G_TL_BIND_NUMBER_TBL    := G_BIND_NUMBER_TBL;
17083  END IF;
17084 
17085 END Set_Binds_And_Dml;
17086 
17087 ----------------------------------------------------------------------
17088 
17089 PROCEDURE Init
17090   IS
17091 BEGIN
17092    G_BIND_INDEX   := 0;
17093    FND_DSQL.Init();
17094 
17095    FOR i IN 1 .. 100 LOOP
17096 
17097     G_BIND_IDENTIFIER_TBL(i) := NULL;
17098     G_BIND_DATATYPE_TBL(i) := NULL;
17099     G_BIND_TEXT_TBL(i) := NULL;
17100     G_BIND_DATE_TBL(i) := NULL;
17101     G_BIND_NUMBER_TBL(i) := NULL;
17102 
17103    END LOOP;
17104 
17105 END init;
17106 
17107 ---------------------------------------------------------------
17108 
17109 /*
17110  * Apply_Default_Vals_For_Entity
17111  * -----------------------------
17112  * Apply_Default_Vals_For_Entity : This API should be called after the entity creation
17113  * is successfuly done. This API would set the default values for attributes in the all
17114  * the single row attribute groups not having a required attribute for the given entity.
17115  */
17116 
17117 PROCEDURE Apply_Default_Vals_For_Entity (
17118         p_object_name                   IN   VARCHAR2
17119        ,p_application_id                IN   NUMBER
17120        ,p_attr_group_type               IN   VARCHAR2
17121        ,p_attr_groups_to_exclude        IN   VARCHAR2   DEFAULT NULL
17122        ,p_pk_column_name_value_pairs    IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
17123        ,p_class_code_name_value_pairs   IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
17124        ,p_data_level                    IN   VARCHAR2   DEFAULT NULL
17125        ,p_data_level_values             IN   EGO_COL_NAME_VALUE_PAIR_ARRAY
17126        ,p_additional_class_Code_list    IN   VARCHAR2   DEFAULT NULL
17127        ,p_entity_id                     IN   NUMBER     DEFAULT NULL
17128        ,p_entity_index                  IN   NUMBER     DEFAULT NULL
17129        ,p_entity_code                   IN   VARCHAR2   DEFAULT NULL
17130        ,p_debug_level                   IN   NUMBER     DEFAULT 0
17131        ,p_init_error_handler            IN   VARCHAR2   DEFAULT FND_API.G_FALSE
17132        ,p_write_to_concurrent_log       IN   VARCHAR2   DEFAULT FND_API.G_FALSE
17133        ,p_init_fnd_msg_list             IN   VARCHAR2   DEFAULT FND_API.G_FALSE
17134        ,p_log_errors                    IN   VARCHAR2   DEFAULT FND_API.G_FALSE
17135        ,p_add_errors_to_fnd_stack       IN   VARCHAR2   DEFAULT FND_API.G_FALSE
17136        ,p_commit                        IN   VARCHAR2   DEFAULT FND_API.G_FALSE
17137        ,x_failed_row_id_list            OUT NOCOPY VARCHAR2
17138        ,x_return_status                 OUT NOCOPY VARCHAR2
17139        ,x_errorcode                     OUT NOCOPY NUMBER
17140        ,x_msg_count                     OUT NOCOPY NUMBER
17141        ,x_msg_data                      OUT NOCOPY VARCHAR2
17142        )
17143   IS
17144     l_api_name                    VARCHAR2(30) := 'Apply_Default_Vals_For_Entity';
17145     l_object_id                   NUMBER;
17146     l_ext_b_table_name            VARCHAR2(30);
17147     l_ext_vl_name                 VARCHAR2(30);
17148     l_ext_where_clause            VARCHAR2(600);
17149     l_ag_id_col_exists            BOOLEAN;
17150     l_dynamic_sql                 VARCHAR2(10000);
17151     l_related_class_Code_list     VARCHAR2(5000);
17152     l_excluded_ag_list            VARCHAR2(1000);
17153     l_previous_ag_id              NUMBER;
17154     l_counter1                    NUMBER;
17155     l_counter2                    NUMBER;
17156     l_dummy_number                NUMBER;
17157     l_ext_row_exists              BOOLEAN;
17158     l_base_data_level             VARCHAR2(30);
17159     l_data_level_1                VARCHAR2(150);
17160     l_data_level_2                VARCHAR2(150);
17161     l_data_level_3                VARCHAR2(150);
17162     l_data_level_4                VARCHAR2(150);
17163     l_data_level_5                VARCHAR2(150);
17164     l_number_val                  NUMBER;
17165     l_str_val                     VARCHAR2(1000);
17166     l_date_val                    DATE;
17167     l_attr_row_table              EGO_USER_ATTR_ROW_TABLE;
17168     l_attr_data_table             EGO_USER_ATTR_DATA_TABLE;
17169     l_transaction_type            VARCHAR2(10);
17170     l_temp_date_str               VARCHAR2(200);
17171     l_temp_attr_row_table         EGO_USER_ATTR_ROW_TABLE;
17172     l_temp_attr_data_table        EGO_USER_ATTR_DATA_TABLE;
17173     l_cc_name_value_pairs         EGO_COL_NAME_VALUE_PAIR_ARRAY;
17174     l_has_data_level_id           BOOLEAN;
17175     l_data_level_id               NUMBER;
17176 
17177     TYPE DYNAMIC_CUR              IS REF CURSOR;
17178     attr_rec_cursor               DYNAMIC_CUR;
17179 
17180     TYPE LOCAL_USER_ATTR_DATA_REC IS RECORD
17181     (
17182         ATTR_GROUP_ID             NUMBER
17183        ,ATTR_GROUP_NAME           VARCHAR2(30)
17184        ,ATTR_NAME                 VARCHAR2(30)
17185        ,REQUIRED_FLAG             VARCHAR2(1)
17186        ,DEFAULT_VALUE             VARCHAR2(1000)
17187        ,DATA_LEVEL                VARCHAR2(30)
17188        ,DATA_TYPE                 VARCHAR2(1)
17189     );
17190 
17191     l_attr_record                 LOCAL_USER_ATTR_DATA_REC;
17192 
17193   BEGIN
17194 
17195     Debug_Msg(l_api_name ||' Starting with params ',1);
17196     Debug_Msg(l_api_name ||' object_name: '||p_object_name||' application id: '||p_application_id);
17197     Debug_Msg(l_api_name ||' attr group type: '||p_attr_group_type||' attr grp to exclude '||p_attr_groups_to_exclude);
17198     IF p_pk_column_name_value_pairs IS NULL THEN
17199       Debug_Msg(l_api_name ||' p_pk_column_name_value_pairs is NULL ');
17200     ELSIF p_pk_column_name_value_pairs.COUNT = 0 THEN
17201       Debug_Msg(l_api_name ||' p_pk_column_name_value_pairs count is 0 ');
17202     ELSE
17203       FOR i IN 1 .. p_pk_column_name_value_pairs.COUNT LOOP
17204         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);
17205       END LOOP;
17206     END IF;
17207     IF p_class_code_name_value_pairs IS NULL THEN
17208       Debug_Msg(l_api_name ||' p_class_code_name_value_pairs is NULL ');
17209     ELSIF p_class_code_name_value_pairs.COUNT = 0 THEN
17210       Debug_Msg(l_api_name ||' p_class_code_name_value_pairs count is 0 ');
17211     ELSE
17212       FOR i IN 1 .. p_class_code_name_value_pairs.COUNT LOOP
17213         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);
17214       END LOOP;
17215     END IF;
17216     Debug_Msg(l_api_name ||' data level: '||p_data_level);
17217     IF p_data_level_values IS NULL THEN
17218       Debug_Msg(l_api_name ||' p_data_level_values is NULL ');
17219     ELSIF p_data_level_values.COUNT = 0 THEN
17220       Debug_Msg(l_api_name ||' p_data_level_values count is 0 ');
17221     ELSE
17222       FOR i IN 1 .. p_data_level_values.COUNT LOOP
17223         debug_msg(l_api_name||' name('||i||'): '||p_data_level_values(i).NAME ||' value('||i||'): '||p_data_level_values(i).value);
17224       END LOOP;
17225     END IF;
17226     Debug_Msg(l_api_name ||' addl class codes: '||p_additional_class_Code_list);
17227     Debug_Msg(l_api_name ||' entity id: '||p_entity_id||' entity index: '||p_entity_index);
17228     Debug_Msg(l_api_name ||' entity code: '||p_entity_code||' debug level: '||p_debug_level);
17229     Debug_Msg(l_api_name ||' init error handler: '||p_init_error_handler||' write conc log: '||p_write_to_concurrent_log);
17230     Debug_Msg(l_api_name ||' init msg list: '||p_init_fnd_msg_list||' log errors: '||p_log_errors);
17231     Debug_Msg(l_api_name ||' add error to stack: '||p_add_errors_to_fnd_stack||' commit flag: '||p_commit);
17232 
17233     SELECT FLEX.APPLICATION_TABLE_NAME        EXT_TABLE_NAME,
17234            FLEX_EXT.APPLICATION_VL_NAME       EXT_VL_NAME
17235       INTO l_ext_b_table_name,
17236            l_ext_vl_name
17237       FROM FND_DESCRIPTIVE_FLEXS              FLEX,
17238            EGO_FND_DESC_FLEXS_EXT             FLEX_EXT
17239      WHERE FLEX.APPLICATION_ID = FLEX_EXT.APPLICATION_ID(+)
17240        AND FLEX.DESCRIPTIVE_FLEXFIELD_NAME = FLEX_EXT.DESCRIPTIVE_FLEXFIELD_NAME(+)
17241        AND FLEX.APPLICATION_ID = p_application_id
17242        AND FLEX.DESCRIPTIVE_FLEXFIELD_NAME = p_attr_group_type;
17243 
17244     IF( l_ext_vl_name IS NULL ) THEN
17245       l_ext_vl_name := l_ext_b_table_name;
17246     END IF;
17247     Debug_Msg(l_api_name ||' b table: '||l_ext_b_table_name||' tl table: '||l_ext_vl_name);
17248 
17249     l_object_id := Get_Object_Id_From_Name(p_object_name);
17250 
17251     -------------------------------------------------------------
17252     -- Find out weather the ATTR_GROUP_ID column exists in the --
17253     -- table where attribute data is to be uploaded or not     --
17254     -------------------------------------------------------------
17255     l_ag_id_col_exists := FND_API.TO_BOOLEAN(EGO_USER_ATTRS_COMMON_PVT.has_column_in_table(
17256                                     p_table_name  => l_ext_b_table_name
17257                                    ,p_column_name => 'ATTR_GROUP_ID')
17258                                              );
17259 
17260     l_has_data_level_id := FND_API.TO_BOOLEAN(EGO_USER_ATTRS_COMMON_PVT.has_column_in_table(
17261                                     p_table_name  => l_ext_b_table_name
17262                                    ,p_column_name => 'DATA_LEVEL_ID')
17263                                              );
17264 
17265     IF l_has_data_level_id THEN
17266       SELECT data_level_id
17267         INTO l_data_level_id
17268         FROM ego_data_level_b
17269        WHERE application_id = p_application_id
17270          AND attr_group_type = p_attr_group_type
17271          AND data_level_name = p_data_level;
17272     END IF;
17273 
17274     l_ext_where_clause := p_class_code_name_value_pairs(1).NAME ||' = '||p_class_code_name_value_pairs(1).VALUE||' ';
17275     IF (l_ag_id_col_exists) THEN
17276       l_ext_where_clause := l_ext_where_clause || ' AND EXT.ATTR_GROUP_ID = :ag_id ';
17277     END IF;
17278 
17279     FOR i IN p_pk_column_name_value_pairs.FIRST .. p_pk_column_name_value_pairs.LAST
17280     LOOP
17281       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 ;
17282     END LOOP;
17283 
17284     IF l_has_data_level_id THEN
17285       l_ext_where_clause := l_ext_where_clause || ' AND data_level_id = '||l_data_level_id;
17286       IF p_data_level_values IS NOT NULL AND p_data_level_values.COUNT <> 0 THEN
17287         FOR i IN 1 .. p_data_level_values.COUNT LOOP
17288           l_ext_where_clause := l_ext_where_clause || ' AND '||p_data_level_values(i).name ||' = '||p_data_level_values(i).value;
17289         END LOOP;
17290       END IF;
17291     END IF;
17292 
17293     IF (p_additional_class_Code_list IS NULL) THEN
17294       l_related_class_Code_list := ' -2910 '; --any random negative number since cc wont be negative.
17295     ELSE
17296       l_related_class_Code_list := p_additional_class_Code_list;
17297     END IF;
17298 
17299     ----------------------
17300     -- Building the SQL --
17301     ----------------------
17302     l_dynamic_sql := ' SELECT ATTR_GROUP_TBL.ATTR_GROUP_ID, ATTR_TBL.DESCRIPTIVE_FLEX_CONTEXT_CODE ATTR_GROUP_NAME,'||
17303                             ' ATTR_TBL.END_USER_COLUMN_NAME ATTR_NAME, REQUIRED_FLAG, DEFAULT_VALUE , ASSOC_TBL.DATA_LEVEL,'||
17304                             ' ATTR_EXT_TBL.DATA_TYPE'||
17305                        ' FROM FND_DESCR_FLEX_COLUMN_USAGES ATTR_TBL,'||
17306                             ' EGO_FND_DSC_FLX_CTX_EXT ATTR_GROUP_TBL,'||
17307                             ' EGO_OBJ_AG_ASSOCS_B ASSOC_TBL,'||
17308                             ' EGO_FND_DF_COL_USGS_EXT ATTR_EXT_TBL'||
17309                       ' WHERE ATTR_TBL.APPLICATION_ID = ATTR_GROUP_TBL.APPLICATION_ID ';
17310 
17311     IF (p_attr_groups_to_exclude IS NOT NULL) THEN
17312        l_dynamic_sql := l_dynamic_sql||
17313                         ' AND ATTR_GROUP_TBL.ATTR_GROUP_ID NOT IN ('||p_attr_groups_to_exclude||') ';
17314     END IF;
17315 
17316     l_dynamic_sql := l_dynamic_sql||
17317                         ' AND ATTR_TBL.DESCRIPTIVE_FLEXFIELD_NAME = ATTR_GROUP_TBL.DESCRIPTIVE_FLEXFIELD_NAME'||
17318                         ' AND ATTR_TBL.DESCRIPTIVE_FLEX_CONTEXT_CODE = ATTR_GROUP_TBL.DESCRIPTIVE_FLEX_CONTEXT_CODE '||
17319                         ' AND (ATTR_TBL.DEFAULT_VALUE IS NOT NULL OR ATTR_TBL.REQUIRED_FLAG = ''Y'')'||
17320                         ' AND ATTR_TBL.ENABLED_FLAG = ''Y'''||
17321                         ' AND ATTR_EXT_TBL.APPLICATION_ID = :app_id '||
17322                         ' AND ATTR_EXT_TBL.DESCRIPTIVE_FLEXFIELD_NAME = :attr_group_type '||
17323                         ' AND ATTR_EXT_TBL.DESCRIPTIVE_FLEX_CONTEXT_CODE = ATTR_TBL.DESCRIPTIVE_FLEX_CONTEXT_CODE'||
17324                         ' AND ATTR_EXT_TBL.APPLICATION_COLUMN_NAME = ATTR_TBL.APPLICATION_COLUMN_NAME'||
17325                         ' AND ATTR_GROUP_TBL.DESCRIPTIVE_FLEXFIELD_NAME = :attr_group_type '||
17326                         ' AND ATTR_GROUP_TBL.APPLICATION_ID = :app_id '||
17327                         ' AND ATTR_GROUP_TBL.ATTR_GROUP_ID = ASSOC_TBL.ATTR_GROUP_ID'||
17328                         ' AND ASSOC_TBL.OBJECT_ID = :object_id '||
17329                         ' AND ATTR_GROUP_TBL.MULTI_ROW = ''N'''||
17330                         ' AND (    ASSOC_TBL.CLASSIFICATION_CODE IN ('||l_related_class_Code_list||')'||
17331                         '       OR ASSOC_TBL.CLASSIFICATION_CODE = :class_Code  )';
17332     IF l_has_data_level_id THEN
17333       l_dynamic_sql := l_dynamic_sql||
17334                         ' AND ASSOC_TBL.data_level_id = '||l_data_level_id;
17335     END IF;
17336       l_dynamic_sql := l_dynamic_sql||
17337                         ' ORDER BY ATTR_GROUP_TBL.ATTR_GROUP_ID';
17338 
17339    IF l_has_data_level_id THEN
17340      l_base_data_level := p_data_level;
17341    ELSE
17342      -----------------------------------------------
17343      -- Getting the base data level for the entity
17344      -----------------------------------------------
17345      SELECT data_level_name
17346        INTO l_base_data_level
17347        FROM ( SELECT MIN(data_level_id) data_level_id
17348                 FROM ego_data_level_b
17349                WHERE application_id = p_application_id
17350                  AND attr_group_type = p_attr_group_type
17351             ) min_dl, ego_data_level_b dl
17352       WHERE dl.data_level_id = min_dl.data_level_id;
17353    END IF;
17354 
17355    IF p_data_level_values IS NOT NULL THEN
17356      l_dummy_number := p_data_level_values.COUNT;
17357    ELSE
17358      l_dummy_number := 0;
17359    END IF;
17360 
17361    IF l_dummy_number > 4 THEN
17362      l_data_level_5 := p_data_level_values(5).VALUE;
17363    ELSE
17364      l_data_level_5 := NULL;
17365    END IF;
17366 
17367    IF l_dummy_number > 3 THEN
17368      l_data_level_4 := p_data_level_values(4).VALUE;
17369    ELSE
17370      l_data_level_4 := NULL;
17371    END IF;
17372 
17373    IF l_dummy_number > 2 THEN
17374      l_data_level_3 := p_data_level_values(3).VALUE;
17375    ELSE
17376      l_data_level_3 := NULL;
17377    END IF;
17378 
17379    IF l_dummy_number > 1 THEN
17380      l_data_level_2 := p_data_level_values(2).VALUE;
17381    ELSE
17382      l_data_level_2 := NULL;
17383    END IF;
17384 
17385    IF l_dummy_number > 0 THEN
17386      l_data_level_1 := p_data_level_values(1).VALUE;
17387    ELSE
17388      l_data_level_1 := NULL;
17389    END IF;
17390 
17391    -------------------------------------
17392    -- Looping through the attr records
17393    -- for building the attr data object
17394    -------------------------------------
17395     -- initializing all the variables...
17396     l_excluded_ag_list := ' ';
17397     l_previous_ag_id := -1;
17398     l_counter1 := 0;
17399     l_counter2 := 0;
17400 
17401     l_attr_row_table := EGO_USER_ATTR_ROW_TABLE();
17402     l_attr_data_table := EGO_USER_ATTR_DATA_TABLE();
17403     l_temp_attr_row_table := EGO_USER_ATTR_ROW_TABLE();
17404     l_temp_attr_data_table := EGO_USER_ATTR_DATA_TABLE();
17405 
17406     Debug_Msg(l_api_name ||' attr rec cursor: '||l_dynamic_sql);
17407     Debug_Msg(l_api_name ||' binds are 1: '|| p_application_id ||' 2: '|| p_attr_group_type||
17408               ' 3: '||p_attr_group_type ||' 4: '||p_application_id ||' 5: '||l_object_id ||
17409               ' 6: '||p_class_code_name_value_pairs(1).VALUE);
17410 
17411      OPEN attr_rec_cursor
17412       FOR  l_dynamic_sql
17413     USING  p_application_id,
17414            p_attr_group_type,
17415            p_attr_group_type,
17416            p_application_id,
17417            l_object_id,
17418            p_class_code_name_value_pairs(1).VALUE;
17419 
17420     ------------------------------------------------------------------------------------------
17421     --Looping through the cursor fetched records to get the attributes with default values  --
17422     --and no corresponding AG row in the ext data table.                                    --
17423     ------------------------------------------------------------------------------------------
17424     LOOP
17425     FETCH attr_rec_cursor INTO l_attr_record;
17426     EXIT WHEN attr_rec_cursor%NOTFOUND;
17427 
17428       IF(l_attr_record.DATA_TYPE = EGO_EXT_FWK_PUB.G_NUMBER_DATA_TYPE)THEN
17429          l_number_val := TO_NUMBER(l_attr_record.DEFAULT_VALUE);
17430          l_str_val    := NULL;
17431          l_date_val   := NULL;
17432       ELSIF (l_attr_record.DATA_TYPE = EGO_EXT_FWK_PUB.G_TRANS_TEXT_DATA_TYPE OR
17433              l_attr_record.DATA_TYPE = EGO_EXT_FWK_PUB.G_CHAR_DATA_TYPE) THEN
17434          l_number_val := NULL;
17435          l_str_val    := l_attr_record.DEFAULT_VALUE;
17436          l_date_val   := NULL;
17437       ELSIF(l_attr_record.DATA_TYPE = EGO_EXT_FWK_PUB.G_DATE_DATA_TYPE OR
17438              l_attr_record.DATA_TYPE = EGO_EXT_FWK_PUB.G_DATE_TIME_DATA_TYPE) THEN
17439          l_number_val := NULL;
17440          l_str_val    := NULL;
17441          IF(INSTR(UPPER(l_attr_record.DEFAULT_VALUE),'$SYSDATE$') <> 0) THEN
17442            l_temp_date_str := REPLACE(UPPER(l_attr_record.DEFAULT_VALUE),'$'); --bugfix:5228308
17443            EXECUTE IMMEDIATE 'SELECT '||l_temp_date_str||' FROM DUAL '
17444            INTO l_date_val;
17445          ELSE
17446            l_date_val := TO_DATE(l_attr_record.DEFAULT_VALUE,EGO_USER_ATTRS_COMMON_PVT.G_DATE_FORMAT);
17447          END IF;
17448       END IF;
17449 
17450       IF (l_attr_record.REQUIRED_FLAG = 'Y' AND l_attr_record.DEFAULT_VALUE IS NULL) THEN
17451          l_excluded_ag_list := l_excluded_ag_list || '   '||l_attr_record.ATTR_GROUP_ID||'   ';
17452       END IF;
17453 
17454       IF (l_previous_ag_id = -1 OR l_previous_ag_id <> l_attr_record.ATTR_GROUP_ID) THEN
17455 
17456         l_temp_attr_row_table.EXTEND();
17457         l_counter1 := l_counter1+1;
17458 
17459         IF (l_ag_id_col_exists) THEN
17460            l_transaction_type := 'CREATE';
17461         ELSE
17462            l_transaction_type := 'SYNC';
17463         END IF;
17464 
17465         IF l_has_data_level_id THEN -- R12C code
17466           Debug_Msg(l_api_name ||' creating attr row object for R12C ');
17467           l_temp_attr_row_table(l_counter1) :=
17468                      EGO_USER_ATTR_ROW_OBJ( l_attr_record.ATTR_GROUP_ID,      --ROW_IDENTIFIER
17469                                             l_attr_record.ATTR_GROUP_ID,      --ATTR_GROUP_ID
17470                                             p_application_id,                 --ATTR_GROUP_APP_ID
17471                                             p_attr_group_type,                --ATTR_GROUP_TYPE
17472                                             l_attr_record.ATTR_GROUP_NAME,    --ATTR_GROUP_NAME
17473                                             p_data_level,                     --DATA_LEVEL
17474                                             l_data_level_1,                   --DATA_LEVEL_1
17475                                             l_data_level_2,                   --DATA_LEVEL_2
17476                                             l_data_level_3,                   --DATA_LEVEL_3
17477                                             l_data_level_4,                   --DATA_LEVEL_4
17478                                             l_data_level_5,                   --DATA_LEVEL_5
17479                                             l_transaction_type                --TRANSACTION_TYPE
17480                                            );
17481         ELSE -- R12 code
17482           IF(l_base_data_level = l_attr_record.DATA_LEVEL) THEN
17483             Debug_Msg(l_api_name ||' creating attr row object for R12 base data level ');
17484             l_temp_attr_row_table(l_counter1) :=
17485                      EGO_USER_ATTR_ROW_OBJ( l_attr_record.ATTR_GROUP_ID,      --ROW_IDENTIFIER
17486                                             l_attr_record.ATTR_GROUP_ID,      --ATTR_GROUP_ID
17487                                             p_application_id,                 --ATTR_GROUP_APP_ID
17488                                             p_attr_group_type,                --ATTR_GROUP_TYPE
17489                                             l_attr_record.ATTR_GROUP_NAME,    --ATTR_GROUP_NAME
17490                                             null,                             --DATA_LEVEL
17491                                             null,                             --DATA_LEVEL_1
17492                                             null,                             --DATA_LEVEL_2
17493                                             null,                             --DATA_LEVEL_3
17494                                             null,                             --DATA_LEVEL_4
17495                                             null,                             --DATA_LEVEL_5
17496                                             l_transaction_type                --TRANSACTION_TYPE
17497                                            );
17498           ELSE
17499             Debug_Msg(l_api_name ||' creating attr row object for R12 NON base data level ');
17500             l_temp_attr_row_table(l_counter1) :=
17501                      EGO_USER_ATTR_ROW_OBJ( l_attr_record.ATTR_GROUP_ID,      --ROW_IDENTIFIER
17502                                             l_attr_record.ATTR_GROUP_ID,      --ATTR_GROUP_ID
17503                                             p_application_id,                 --ATTR_GROUP_APP_ID
17504                                             p_attr_group_type,                --ATTR_GROUP_TYPE
17505                                             l_attr_record.ATTR_GROUP_NAME,    --ATTR_GROUP_NAME
17506                                             null,                             --DATA_LEVEL
17507                                             l_data_level_1,                   --DATA_LEVEL_1
17508                                             l_data_level_2,                   --DATA_LEVEL_2
17509                                             l_data_level_3,                   --DATA_LEVEL_3
17510                                             null,                             --DATA_LEVEL_4
17511                                             null,                             --DATA_LEVEL_5
17512                                             l_transaction_type                --TRANSACTION_TYPE
17513                                            );
17514 
17515           END IF;
17516         END IF;
17517         l_previous_ag_id := l_attr_record.ATTR_GROUP_ID;
17518       END IF;
17519 
17520       l_temp_attr_data_table.EXTEND();
17521       l_counter2 := l_counter2 + 1;
17522       l_temp_attr_data_table(l_counter2) :=
17523                  EGO_USER_ATTR_DATA_OBJ( l_attr_record.ATTR_GROUP_ID,   --ROW_IDENTIFIER
17524                                          l_attr_record.ATTR_NAME,       --ATTR_NAME
17525                                          l_str_val,                     --ATTR_VALUE_STR
17526                                          l_number_val,                  --ATTR_VALUE_NUM
17527                                          l_date_val,                    --ATTR_VALUE_DATE
17528                                          l_attr_record.DEFAULT_VALUE,   --ATTR_DISP_VALUE
17529                                          null,                          --ATTR_UNIT_OF_MEASURE
17530                                          null                           --USER_ROW_IDENTIFIER
17531                                         );
17532     END LOOP;
17533     Debug_Msg(l_api_name ||' completed data for AG cursor ');
17534     ------------------------------------------------------------------------------------
17535     --Here we clean up the attr group defination table to filter out the ag's with
17536     --required attributes or having a record in the ext data table.
17537     ------------------------------------------------------------------------------------
17538 
17539     l_dynamic_sql := 'SELECT 1 FROM '||l_ext_vl_name||' EXT WHERE '||l_ext_where_clause;
17540     Debug_Msg(l_api_name ||' dynamic sql for ext row check: '||l_dynamic_sql);
17541 
17542     IF(l_temp_attr_row_table.COUNT > 0 AND l_temp_attr_row_table.COUNT > 0) THEN
17543 
17544        FOR i in l_temp_attr_row_table.FIRST .. l_temp_attr_row_table.LAST
17545        LOOP
17546 
17547          IF ( INSTR(l_excluded_ag_list,l_temp_attr_row_table(i).ATTR_GROUP_ID) = 0 ) THEN
17548 
17549            l_ext_row_exists := TRUE;
17550            BEGIN
17551              IF (l_ag_id_col_exists) THEN
17552                Debug_Msg(l_api_name ||' exec dyn sql for '||l_temp_attr_row_table(i).ATTR_GROUP_ID);
17553                EXECUTE IMMEDIATE l_dynamic_sql
17554                INTO l_dummy_number
17555                USING l_temp_attr_row_table(i).ATTR_GROUP_ID;
17556              ELSE
17557                EXECUTE IMMEDIATE l_dynamic_sql
17558                INTO l_dummy_number;
17559              END IF;
17560            EXCEPTION
17561              WHEN NO_DATA_FOUND THEN
17562                l_ext_row_exists:=FALSE;
17563            END;
17564 
17565            IF (NOT l_ext_row_exists ) THEN
17566              l_attr_row_table.EXTEND();
17567              l_attr_row_table(l_attr_row_table.LAST) :=
17568                   EGO_USER_ATTR_ROW_OBJ (  l_temp_attr_row_table(i).ROW_IDENTIFIER
17569                                           ,l_temp_attr_row_table(i).ATTR_GROUP_ID
17570                                           ,l_temp_attr_row_table(i).ATTR_GROUP_APP_ID
17571                                           ,l_temp_attr_row_table(i).ATTR_GROUP_TYPE
17572                                           ,l_temp_attr_row_table(i).ATTR_GROUP_NAME
17573                                           ,l_temp_attr_row_table(i).DATA_LEVEL
17574                                           ,l_temp_attr_row_table(i).DATA_LEVEL_1
17575                                           ,l_temp_attr_row_table(i).DATA_LEVEL_2
17576                                           ,l_temp_attr_row_table(i).DATA_LEVEL_3
17577                                           ,l_temp_attr_row_table(i).DATA_LEVEL_4
17578                                           ,l_temp_attr_row_table(i).DATA_LEVEL_5
17579                                           ,l_temp_attr_row_table(i).TRANSACTION_TYPE
17580                                          );
17581            ELSE
17582              l_excluded_ag_list := l_excluded_ag_list||'  '||l_temp_attr_row_table(i).ATTR_GROUP_ID||'   ';
17583            END IF;
17584          END IF;
17585        END LOOP;
17586        Debug_Msg(l_api_name ||' 1st level of filtering ');
17587        ----------------------------------------------------------------------------
17588        --Here we filter out the attributes belonging to attr groups which have
17589        --required attributes or have a row in the ext table for the given item.
17590        ----------------------------------------------------------------------------
17591 
17592        l_counter1 := 0;
17593        FOR i in l_temp_attr_data_table.FIRST .. l_temp_attr_data_table.LAST
17594        LOOP
17595          IF ( INSTR(l_excluded_ag_list,l_temp_attr_data_table(i).ROW_IDENTIFIER) = 0 ) THEN
17596 
17597            l_counter1 := l_counter1+1;
17598            l_attr_data_table.EXTEND();
17599            l_attr_data_table(l_counter1) :=
17600                 EGO_USER_ATTR_DATA_OBJ (  l_temp_attr_data_table(i).ROW_IDENTIFIER
17601                                          ,l_temp_attr_data_table(i).ATTR_NAME
17602                                          ,l_temp_attr_data_table(i).ATTR_VALUE_STR
17603                                          ,l_temp_attr_data_table(i).ATTR_VALUE_NUM
17604                                          ,l_temp_attr_data_table(i).ATTR_VALUE_DATE
17605                                          ,l_temp_attr_data_table(i).ATTR_DISP_VALUE
17606                                          ,l_temp_attr_data_table(i).ATTR_UNIT_OF_MEASURE
17607                                          ,l_temp_attr_data_table(i).USER_ROW_IDENTIFIER
17608                                         );
17609          END IF;
17610        END LOOP;
17611        Debug_Msg(l_api_name ||' 2nd level of filtering ');
17612 
17613     END IF; --if the generated tables are not null
17614     ------------------------------------------------------------
17615     -- Now we call Process_user_attrs_data for processing the
17616     -- data we have extracted above ...
17617     ------------------------------------------------------------
17618 
17619     x_failed_row_id_list := NULL;
17620     x_return_status := 'S';
17621     x_errorcode := NULL;
17622     x_msg_count := 0;
17623     x_msg_data := NULL;
17624 
17625 
17626     IF(l_attr_data_table.COUNT > 0 AND l_attr_row_table.COUNT > 0 ) THEN
17627 
17628       l_cc_name_value_pairs := p_class_code_name_value_pairs;
17629       l_cc_name_value_pairs.EXTEND();
17630       l_cc_name_value_pairs(2) := EGO_COL_NAME_VALUE_PAIR_OBJ('RELATED_CLASS_CODE_LIST',l_related_class_Code_list);
17631       Debug_Msg(l_api_name ||' Calling Process_User_Attrs_Data ');
17632       Process_User_Attrs_Data(
17633           p_api_version                   => 1.0
17634          ,p_object_name                   => p_object_name
17635          ,p_attributes_row_table          => l_attr_row_table
17636          ,p_attributes_data_table         => l_attr_data_table
17637          ,p_pk_column_name_value_pairs    => p_pk_column_name_value_pairs
17638          ,p_class_code_name_value_pairs   => l_cc_name_value_pairs
17639          ,p_entity_id                     => p_entity_id
17640          ,p_entity_index                  => p_entity_index
17641          ,p_entity_code                   => p_entity_code
17642          ,p_debug_level                   => p_debug_level
17643          ,p_init_error_handler            => p_init_error_handler
17644          ,p_write_to_concurrent_log       => p_write_to_concurrent_log
17645          ,p_init_fnd_msg_list             => p_init_fnd_msg_list
17646          ,p_log_errors                    => p_log_errors
17647          ,p_add_errors_to_fnd_stack       => p_add_errors_to_fnd_stack
17648          ,p_commit                        => p_commit
17649          ,x_failed_row_id_list            => x_failed_row_id_list
17650          ,x_return_status                 => x_return_status
17651          ,x_errorcode                     => x_errorcode
17652          ,x_msg_count                     => x_msg_count
17653          ,x_msg_data                      => x_msg_data
17654        );
17655       Debug_Msg(l_api_name ||' returned Process_User_Attrs_Data with status: '||x_return_status);
17656       Debug_Msg(l_api_name ||' returned Process_User_Attrs_Data with msg: '||x_msg_data);
17657     END IF;
17658     Debug_Msg(l_api_name ||' Exit ');
17659 EXCEPTION
17660   WHEN OTHERS THEN
17661     Debug_Msg(l_api_name ||' EXCEPTION: '||SQLERRM);
17662     x_return_status := G_RET_STS_UNEXP_ERROR;
17663     x_msg_count := 1;
17664     x_msg_data := SQLERRM;
17665 
17666 END Apply_Default_Vals_For_Entity;
17667 
17668 
17669 ----------------------------
17670 -- Package Initialization --
17671 ----------------------------
17672 BEGIN
17673 
17674     G_BIND_DATATYPE_TBL := VARCHAR2_TBL_TYPE();
17675     G_BIND_TEXT_TBL := VARCHAR2_TBL_TYPE();
17676     G_BIND_DATE_TBL := DATE_TBL_TYPE();
17677     G_BIND_NUMBER_TBL := NUMBER_TBL_TYPE();
17678     G_BIND_IDENTIFIER_TBL := VARCHAR2_TBL_TYPE();
17679 
17680 
17681     G_B_BIND_DATATYPE_TBL := VARCHAR2_TBL_TYPE();
17682     G_B_BIND_TEXT_TBL := VARCHAR2_TBL_TYPE();
17683     G_B_BIND_DATE_TBL := DATE_TBL_TYPE();
17684     G_B_BIND_NUMBER_TBL := NUMBER_TBL_TYPE();
17685     G_B_BIND_IDENTIFIER_TBL := VARCHAR2_TBL_TYPE();
17686 
17687 
17688     G_TL_BIND_DATATYPE_TBL := VARCHAR2_TBL_TYPE();
17689     G_TL_BIND_TEXT_TBL := VARCHAR2_TBL_TYPE();
17690     G_TL_BIND_DATE_TBL := DATE_TBL_TYPE();
17691     G_TL_BIND_NUMBER_TBL := NUMBER_TBL_TYPE();
17692     G_TL_BIND_IDENTIFIER_TBL := VARCHAR2_TBL_TYPE();
17693 
17694 
17695     G_BIND_IDENTIFIER_TBL.EXTEND(100);
17696     G_BIND_DATATYPE_TBL.EXTEND(100);
17697     G_BIND_TEXT_TBL.EXTEND(100);
17698     G_BIND_DATE_TBL.EXTEND(100);
17699     G_BIND_NUMBER_TBL.EXTEND(100);
17700 
17701     G_B_BIND_IDENTIFIER_TBL.EXTEND(100);
17702     G_B_BIND_DATATYPE_TBL.EXTEND(100);
17703     G_B_BIND_TEXT_TBL.EXTEND(100);
17704     G_B_BIND_DATE_TBL.EXTEND(100);
17705     G_B_BIND_NUMBER_TBL.EXTEND(100);
17706 
17707     G_TL_BIND_IDENTIFIER_TBL.EXTEND(100);
17708     G_TL_BIND_DATATYPE_TBL.EXTEND(100);
17709     G_TL_BIND_TEXT_TBL.EXTEND(100);
17710     G_TL_BIND_DATE_TBL.EXTEND(100);
17711     G_TL_BIND_NUMBER_TBL.EXTEND(100);
17712 
17713 END EGO_USER_ATTRS_DATA_PVT;
17714