4 --| Copyright (c) 2000 Oracle Corporation Belmont, California, USA |
1 PACKAGE BODY INV_ITEM_ATTRIBUTES_PKG AS
2 /* $Header: INVGIAPB.pls 120.2.12020000.2 2012/11/14 09:36:08 liswang ship $ */
3 --/*==========================================================================+
5 --| All rights reserved. |
6 --+===========================================================================+
7 --| |
8 --| File Name : invgiapb.pls |
12 --| be constructed, based on the pl/sql table of records which |
9 --| Description : Item attribute processor for the Item Attribute copy form. |
10 --| Creates a pl/sql table of records and populates it with |
11 --| information seeded in the AK dictionary. Queries can then |
13 --| retreive the date to populate MTL_ITEM_ATTRIBUTES_TEMP, on |
14 --| which the form is based. |
15 --| |
16 --| Revision |
17 --| 13-Sep-00 dherring Created |
18 --| 17-JUL-01 dherring Updated with performance enhancements |
19 --| 06-NOV-02 vjavli Bug#2643619 fix: more than one SEGMENT in system |
20 --| items flex field - build_item_cursor procedure to|
21 --| build the dynamic cursor to select the items |
22 --| 21-NOV-02 vma Performance: modify code to print to log only if |
23 --| debug profile option is enabled; add NOCOPY to |
24 --| OUT parameters of find_org_list, get_type_struct,|
25 --| call_item_update |
26 --| 20-FEB-03 vjavli Bug#2808261 fix: organization item records is |
27 --| getting repeated. Found that when there is no |
28 --| item for that organization, it should not be |
29 --| inserted in MTL_ITEM_ATTRIBUTES_TEMP |
30 --| 18-MAR-03 vjavli Bug#2855692 fix: all items should be displayed |
31 --| in the items range for all the organizations |
32 --| procedure: populate_temp_table modified with |
33 --| WHILE loop for the item_cursor |
34 --| 09-FEB-04 vjavli GSCC fix: file.sql.47 |
35 --| FND_INSTALLATION.get_app_info used to obtain |
36 --| owner of database schema. This will be used in |
37 --| WHERE condition to compare with owner along with |
38 --| table_name of all_tab_columns |
39 --| 10-FEB-04 nkilleda Bug#3148944 fix: Unapproved items should be |
40 --| excluded from item range when item from and item |
41 --| to fields are input by user. These items are PLM |
42 --| items and should not be visible to an ERPuser. |
43 --| Modified Build_Item_Cursor (l_mstk_w) |
44 --| 11-Mar-04 TMANDA Bug#3497035 : Replaced p_cat_set_id is not null |
45 --| with p_cat_set_id <> -1 in populate_temp_table |
46 --| and Build_Item_Cursor procedures. |
47 --| Commented unncessary ELSE clauses where the |
48 --| variables are being set to null. |
49 --| 21-May-04 vto Bug 3571949: Fixed issue with folder prompts not |
50 --| translated. |
51 --| 14-NOV-04 nesoni Bug# 3770547. Procedure populate_temp_table and |
52 --| Build_Item_Cursor have been modified to |
53 --| incorporate attribute_category as additional IN |
54 --| parameter for filtering items for coping. Added |
55 --| NOCOPY to OUT parameters. |
56 --| 16-DEC-04 nesoni BUG #4025750. Procedure populate_temp_table |
57 --| modified to incorporate CopyDffToNull as |
58 --| additional IN parameter. |
59 --| 20-DEC-04 nesoni BUG #4064005. Procedure populate_temp_table |
60 --| and Build_item_Cursor are modified to accept |
61 --| attribute_category as bind parameter. |
62 --| 20-DEC-04 MYERRAMS BUG #5001785. Modified the Update queries to |
63 --| use bind variables instead of SQL Literals to |
64 --| improve the performance. |
65 --+==========================================================================*/
66
67 --=================
68 -- CONSTANTS
69 --=================
70
71 G_INV_ITEM_ATTRIBUTES_PKG VARCHAR2(30) := 'INV_ITEM_ATTRIBUTES_PKG';
72
73 --==================
74 -- GLOBAL VARIABLES
75 --==================
76
77 g_att_tab att_tbl_type;
78 g_sel_tab sel_tbl_type;
79 g_cho_rec cho_rec_type;
80 g_current_att_index BINARY_INTEGER := 0;
81 g_current_sel_index BINARY_INTEGER := 0;
82 g_empty_att_tab att_tbl_type;
83 g_empty_sel_tab sel_tbl_type;
84 g_itm_rec inv_item_grp.item_rec_type;
85 g_org_tab INV_ORGHIERARCHY_PVT.orgid_tbl_type;
86 g_current_org_index BINARY_INTEGER := 0;
87 g_empty_org_tab INV_ORGHIERARCHY_PVT.orgid_tbl_type;
88 g_count NUMBER := 0;
89 g_unit_test_mode BOOLEAN := FALSE;
90 G_PKG_NAME CONSTANT VARCHAR2(30) := 'INV_ITEM_ATT_MTN';
91 G_SLEEP_TIME NUMBER := 15;
92 G_DEBUG VARCHAR2(1) := NVL(fnd_profile.value('AFLOG_ENABLED'), 'N');
93
94 g_submit_failure_exc EXCEPTION;
95
96 TYPE g_request_tbl_type IS TABLE OF NUMBER
97 INDEX BY BINARY_INTEGER;
98 TYPE g_item_cur_type IS REF CURSOR;
99
100
101 --=========================================================================
102 -- PROCEDURE : get_type_struct PRIVATE
103 -- PARAMETERS :
104 -- COMMENT : initialize the pl/sql table with the list user selected
105 -- attributes
109 -- If the PL/SQL table of records has already been initialized
106 -- This code needed to initialize the pl/sql table with these
107 -- user selected attributes. The pl/sql table is global and it's
108 -- contents can then bew accessed by other apis in this package.
110 -- it's id is simply passed back to the calling procedure.
111 -- PRE-COND : This procedure will be called from the form
112 --=========================================================================
113 PROCEDURE get_type_struct
114 (p_att_tab OUT NOCOPY ATT_TBL_TYPE
115 ,p_cho_rec OUT NOCOPY CHO_REC_TYPE
116 ,p_sel_tab OUT NOCOPY SEL_TBL_TYPE
117 )
118 IS
119
120 --=================
121 -- LOCAL VARIABLES
122 --=================
123
124 BEGIN
125
126 p_att_tab := g_att_tab;
127 p_cho_rec := g_cho_rec;
128 p_sel_tab := g_sel_tab;
129
130 EXCEPTION
131 WHEN OTHERS THEN
132 IF FND_MSG_PUB.Check_Msg_Level(FND_MSG_PUB.G_MSG_LVL_UNEXP_ERROR)
133 THEN
134 FND_MSG_PUB.Add_Exc_Msg( G_INV_ITEM_ATTRIBUTES_PKG
135 , 'get_type_struct'
136 );
137 END IF;
138 RAISE;
139 END get_type_struct;
140
141 --=========================================================================
142 -- PROCEDURE : set_type_struct PRIVATE
143 -- PARAMETERS :
144 -- COMMENT : allows the form to populate
145 -- the two pl/sql tables with the chosen
146 -- record values and the unique id of the
147 -- records to be updated
148 -- PRE-COND : This procedure will be called from the form
149 --=========================================================================
150 PROCEDURE set_type_struct
151 (p_att_tab IN ATT_TBL_TYPE
152 ,p_cho_rec IN CHO_REC_TYPE
153 ,p_sel_tab IN SEL_TBL_TYPE
154 )
155 IS
156
157 --=================
158 -- LOCAL VARIABLES
159 --=================
160
161 BEGIN
162
163 g_att_tab := p_att_tab;
164 g_cho_rec := p_cho_rec;
165 g_sel_tab := p_sel_tab;
166
167 EXCEPTION
168 WHEN OTHERS THEN
169 IF FND_MSG_PUB.Check_Msg_Level(FND_MSG_PUB.G_MSG_LVL_UNEXP_ERROR)
170 THEN
171 FND_MSG_PUB.Add_Exc_Msg( G_INV_ITEM_ATTRIBUTES_PKG
172 , 'set_type_struct'
173 );
174 END IF;
175 RAISE;
176 END set_type_struct;
177
178 --=========================================================================
179 -- PROCEDURE : populate_type_struct PRIVATE
180 -- PARAMETERS :
181 -- COMMENT : populate the pl/sql table of records with approprite
182 -- data to construct the query to feed the populate temp
183 -- table procedure.
184 -- The ak meta model is normalized. Most of the information
185 -- we required is scattered amongst many tables.
186 -- This procedure uses 6 simple queries to populate
187 -- the records. This avoids a costly single query with
188 -- a join involving 6 tables.
189 -- PRE-COND : This procedure must be fed a list of columns selected
190 -- for display by the user using the find canvas of the
191 -- item_attributes_copy form.
192 --=========================================================================
193 PROCEDURE populate_type_struct(p_att_tab IN ATT_TBL_TYPE)
194 IS
195
196 BEGIN
197
198 -- Initialize on the first user selected attribute
199
200 g_att_tab := p_att_tab;
201 g_current_att_index := g_att_tab.FIRST;
202 g_count := g_att_tab.COUNT;
203
204 LOOP
205
206 g_att_tab(g_current_att_index).temp_column_name :=
207 RPAD('ATTRIBUTE',12,LPAD(TO_CHAR(g_current_att_index + 1),3,'0'));
208
209 /* Added for Bug 4064006 */
210 SELECT COLUMN_TYPE
211 ,LOOKUP_TABLE
212 ,LOOKUP_COLUMN
213 ,LOOKUP_TYPE
214 ,LOOKUP_TYPE_VALUE
215 ,REFERENCE_KEY_COLUMN
216 INTO g_att_tab(g_current_att_index).column_type
217 ,g_att_tab(g_current_att_index).lookup_table
218 ,g_att_tab(g_current_att_index).lookup_column
219 ,g_att_tab(g_current_att_index).lookup_type
220 ,g_att_tab(g_current_att_index).lookup_type_value
221 ,g_att_tab(g_current_att_index).reference_key_column
222 FROM MTL_ITEM_ATTRIBUTES_SEED_INFO
223 WHERE attribute_code = g_att_tab(g_current_att_index).item_column_name
224 ORDER BY rowid;
225
226 /*SELECT default_value_varchar2
227 ,display_value_length
228 INTO g_att_tab(g_current_att_index).foreign_key_name
229 ,g_att_tab(g_current_att_index).column_type
230 FROM ak_object_attributes
231 WHERE database_object_name = 'MTL_SYSTEM_ITEMS_VL'
232 AND attribute_code = g_att_tab(g_current_att_index).item_column_name
233 ORDER BY rowid;
234
235 -- If the column is a flexfield then do not overwrite
236 -- the display column entry in the table of records
237 -- because that has already been populated with
238 -- the display name in the forms package
239 -- FND_ATTR_AVAILABLE
240
241 IF g_att_tab(g_current_att_index).column_type <> 4
242 THEN
243
244 SELECT attribute_label_long
245 INTO g_att_tab(g_current_att_index).display_column
246 FROM ak_object_attributes_vl
247 WHERE database_object_name = 'MTL_SYSTEM_ITEMS_VL'
248 AND attribute_code = g_att_tab(g_current_att_index).item_column_name;
249
250 END IF;
251
252 IF g_att_tab(g_current_att_index).foreign_key_name IS NOT NULL
256 SELECT from_to_name
253 AND g_att_tab(g_current_att_index).column_type = 1
254 THEN
255
257 ,to_from_name
258 INTO g_att_tab(g_current_att_index).lookup_table
259 ,g_att_tab(g_current_att_index).lookup_column
260 FROM ak_foreign_keys_tl
261 WHERE foreign_key_name = g_att_tab(g_current_att_index).foreign_key_name
262 AND language = 'US';
263
264 SELECT from_to_description
265 ,to_from_description
266 INTO g_att_tab(g_current_att_index).lookup_type
267 ,g_att_tab(g_current_att_index).lookup_type_value
268 FROM ak_foreign_keys_tl
269 WHERE foreign_key_name = g_att_tab(g_current_att_index).foreign_key_name
270 AND language = 'US';
271
272 SELECT attribute_code
273 INTO g_att_tab(g_current_att_index).foreign_key_column
274 FROM ak_foreign_key_columns
275 WHERE foreign_key_name = g_att_tab(g_current_att_index).foreign_key_name;
276
277 SELECT attribute_code
278 INTO g_att_tab(g_current_att_index).reference_key_column
279 FROM ak_unique_key_columns
280 WHERE unique_key_name = g_att_tab(g_current_att_index).lookup_table;
281
282 ELSIF g_att_tab(g_current_att_index).foreign_key_name IS NOT NULL
283 AND g_att_tab(g_current_att_index).column_type = 2
284 THEN
285
286 SELECT from_to_name
287 ,to_from_name
288 INTO g_att_tab(g_current_att_index).lookup_table
289 ,g_att_tab(g_current_att_index).lookup_column
290 FROM ak_foreign_keys_tl
291 WHERE foreign_key_name = g_att_tab(g_current_att_index).foreign_key_name
292 AND language = 'US';
293
294 SELECT from_to_description
295 ,to_from_description
296 INTO g_att_tab(g_current_att_index).lookup_type
297 ,g_att_tab(g_current_att_index).lookup_type_value
298 FROM ak_foreign_keys_tl
299 WHERE foreign_key_name = g_att_tab(g_current_att_index).foreign_key_name
300 AND language = 'US';
301
302 SELECT attribute_code
303 INTO g_att_tab(g_current_att_index).foreign_key_column
304 FROM ak_foreign_key_columns
305 WHERE foreign_key_name = g_att_tab(g_current_att_index).foreign_key_name;
306
307 END IF;
308 */
309 EXIT WHEN g_current_att_index = g_att_tab.LAST;
310
311 g_current_att_index := g_att_tab.NEXT(g_current_att_index);
312
313 END LOOP;
314
315 EXCEPTION
316 WHEN OTHERS THEN
317 IF FND_MSG_PUB.Check_Msg_Level(FND_MSG_PUB.G_MSG_LVL_UNEXP_ERROR)
318 THEN
319 FND_MSG_PUB.Add_Exc_Msg( G_INV_ITEM_ATTRIBUTES_PKG
320 , 'populate_type_struct'
321 );
322 END IF;
323 RAISE;
324 END populate_type_struct;
325
326 --=========================================================================
327 -- PROCEDURE : clear_type_struct PRIVATE
328 -- PARAMETERS :
329 -- COMMENT : clear the pl/sql table
330 -- PRE-COND : This procedure will be called from the form
331 --=========================================================================
332 PROCEDURE clear_type_struct
333 IS
334
335 BEGIN
336
337 -- clear the pl/sql table before use
338 g_att_tab := g_empty_att_tab;
339
340 -- reset global index
341 g_current_att_index := 0;
342
343 EXCEPTION
344 WHEN OTHERS THEN
345 IF FND_MSG_PUB.Check_Msg_Level(FND_MSG_PUB.G_MSG_LVL_UNEXP_ERROR)
346 THEN
347 FND_MSG_PUB.Add_Exc_Msg( G_INV_ITEM_ATTRIBUTES_PKG
348 , 'clear_type_struct'
349 );
350 END IF;
351 RAISE;
352 END clear_type_struct;
353
354 --========================================================================
355 -- PROCEDURE : Build_Item_Cursor PRIVATE
356 -- PARAMETERS: p_category_id IN Category Id
357 -- p_category_set_id IN Category Set Id
361 -- p_organization_id IN Organization id
358 -- p_item_id IN Inventory Item Id
359 -- p_item_from IN Item Number From
360 -- p_item_to IN Item Number To
362 -- p_sts_code IN Inventory Item Status Code
363 -- p_attribute_category IN VARCHAR2
364 -- p_copy_dff_to_null IN VARCHAR2
365 -- p_attribute_category IN VARCHAR2
366 -- x_item_cursor OUT NOCOPY item cursor statement
367 -- COMMENT : This procedure builds the item cursor statement. This statement
368 -- needs to be built at run time (dynamic SQL) because of the
369 -- dynamic nature of the System Item flexfield.
370 -- This procedure introduced as part of bug#2643619 fix for
371 -- more than one SEGMENT issue
372 --=========================================================================
373 /* Bug: 3770547
374 One more input parameter AttributeCategory added to find items that need to be populated*/
375 /* Bug: 4025750
376 One more filter parameter p_copy_dff_to_null added to find items that need to be populated*/
377 PROCEDURE Build_Item_Cursor
378 ( p_category_id IN NUMBER
379 , p_category_set_id IN NUMBER
380 , p_item_id IN NUMBER
381 , p_item_from IN VARCHAR2
382 , p_item_to IN VARCHAR2
383 , p_organization_id IN NUMBER
384 , p_sts_code IN VARCHAR2
385 , p_attribute_category IN VARCHAR2
386 , p_copy_dff_to_null IN VARCHAR2
387 , x_item_cursor IN OUT NOCOPY VARCHAR2
388 )
389 IS
390 l_flexfield_rec FND_FLEX_KEY_API.flexfield_type;
391 l_structure_rec FND_FLEX_KEY_API.structure_type;
392 l_segment_rec FND_FLEX_KEY_API.segment_type;
393 l_segment_tbl FND_FLEX_KEY_API.segment_list;
394 l_segment_number NUMBER;
395 l_mstk_segs VARCHAR2(850);
396 l_mcat_f VARCHAR2(2000);
397 l_mcat_w1 VARCHAR2(2000);
398 l_mstk_w VARCHAR2(2000);
399 l_sts_w VARCHAR2(2000);
400
401 l_category_id NUMBER;
402 l_category_set_id NUMBER;
403 l_item_id NUMBER;
404 l_item_from VARCHAR2(2000);
405 l_item_to VARCHAR2(2000);
406 l_organization_id NUMBER;
407 l_sts_code VARCHAR2(2000);
408 -- Bug: 3770547.
409 l_dff_w VARCHAR2(2000);
410 BEGIN
411
412 IF G_DEBUG = 'Y' THEN
413 INV_ORGHIERARCHY_PVT.Log
414 ( INV_ORGHIERARCHY_PVT.G_LOG_PROCEDURE
415 , '> Build_Item_Cursor'
416 );
417 END IF;
418
419 FND_FLEX_KEY_API.set_session_mode('customer_data');
420
421 -- retrieve system item concatenated flexfield
422 l_mstk_segs := '';
423 l_flexfield_rec := FND_FLEX_KEY_API.find_flexfield('INV', 'MSTK');
424 l_structure_rec := FND_FLEX_KEY_API.find_structure(l_flexfield_rec, 101);
425 FND_FLEX_KEY_API.get_segments
426 ( flexfield => l_flexfield_rec
427 , structure => l_structure_rec
428 , nsegments => l_segment_number
429 , segments => l_segment_tbl
430 );
431 FOR l_idx IN 1..l_segment_number LOOP
432 l_segment_rec := FND_FLEX_KEY_API.find_segment
433 ( l_flexfield_rec
434 , l_structure_rec
435 , l_segment_tbl(l_idx)
436 );
437 l_mstk_segs := l_mstk_segs ||'itm.'||l_segment_rec.column_name;
438 IF l_idx < l_segment_number THEN
439 l_mstk_segs := l_mstk_segs||'||'||''''||l_structure_rec.segment_separator||''''||'||';
440 END IF;
441 END LOOP;
442
443 IF G_DEBUG = 'Y' THEN
444 INV_ORGHIERARCHY_PVT.Log
445 ( INV_ORGHIERARCHY_PVT.G_LOG_STATEMENT
446 , 'item flexfield segments:'||l_mstk_segs
447 );
448 END IF;
449
450 IF p_item_from IS NOT NULL AND p_item_to IS NOT NULL THEN
451 l_mstk_w := ' AND '||l_mstk_segs||' BETWEEN :l_item_from
452 AND :l_item_to';
453 ELSIF p_item_from IS NOT NULL AND p_item_to IS NULL THEN
454 l_mstk_w := ' AND '||l_mstk_segs||' >= :l_item_from';
455 ELSIF p_item_from IS NULL AND p_item_to IS NOT NULL THEN
456 l_mstk_w := ' AND '||l_mstk_segs||' <= :l_item_to';
457 ELSIF p_item_id <> -1 THEN
458 l_mstk_w := ' AND itm.inventory_item_id = :l_item_id';
459 --Bug#3497035
460 -- ELSE
461 -- l_mstk_w := NULL;
462 END IF;
463 --
464 -- Bug 3418944 : Modified by NKILLEDA
465 --
466 -- Added the check to remove the items that are not approved
467 -- ( => approval_status <> 'A' ) from the range of items.
468 --
469 -- Unapproved items are created in PLM and they should not be
470 -- to be visible to an ERP user.
471 --
472 IF l_mstk_w IS NOT NULL THEN
473 l_mstk_w := l_mstk_w ||' AND NVL(itm.approval_status,''A'') = ''A''';
474 END IF;
475
476 --Bug#3497035
477 -- l_mcat_f := ', mtl_item_categories mic';
478
479 IF p_category_id <> -1 AND p_category_set_id <> -1 THEN
480 --Bug#3497035
481 -- IF p_category_id <> -1 AND p_category_set_id IS NOT NULL THEN
482 l_mcat_f := ', mtl_item_categories mic';
483 l_mcat_w1 := ' AND mic.organization_id = itm.organization_id' ||
484 ' AND mic.inventory_item_id = itm.inventory_item_id' ||
485 ' AND mic.category_set_id = :l_category_set_id' ||
486 ' AND mic.category_id = :l_category_id';
487 --Bug#3497035
488 -- ELSE
489 -- l_mcat_f := NULL;
490 -- l_mcat_w1 := NULL;
491 END IF;
492
493 IF p_sts_code IS NOT NULL THEN
497 -- l_sts_w := NULL;
494 l_sts_w := ' AND itm.inventory_item_status_code LIKE :l_sts_code';
495 --Bug#3497035
496 -- ELSE
498 END IF;
499
500
501 /* Bug: 3770547. Verify if AttributeCategory is present then
502 * construct appropriate where clasue and update query accordingly. */
503 IF p_attribute_category IS NOT NULL THEN
504 --Modified for bug 4025750.
505 IF p_copy_dff_to_null IS NULL OR p_copy_dff_to_null = 'NO' THEN
506 l_dff_w := ' AND itm.attribute_category = :l_attribute_category ';
507 ELSIF p_copy_dff_to_null = 'YES' THEN
508 l_dff_w := ' AND (itm.attribute_category IS NULL OR itm.attribute_category = :l_attribute_category )';
509 END IF;
510 ELSE
511 l_dff_w := NULL;
512 END IF;
513
514 x_item_cursor := 'SELECT DISTINCT
515 par.organization_code
516 , par.organization_id ' ||
517 ', ' || l_mstk_segs ||
518 ', itm.inventory_item_id' ||
519 ' FROM mtl_system_items_b itm' ||
520 ' , mtl_parameters par' ||
521 l_mcat_f ||
522 ' WHERE itm.organization_id = par.organization_id' ||
523 ' AND itm.organization_id = :organization_id' ||
524 l_mstk_w ||
525 l_mcat_w1 ||
526 l_sts_w ||
527 l_dff_w;
528
529 IF G_DEBUG = 'Y' THEN
530 INV_ORGHIERARCHY_PVT.Log
531 ( INV_ORGHIERARCHY_PVT.G_LOG_STATEMENT
532 , SUBSTR(x_item_cursor, 1, 250)
533 );
534 INV_ORGHIERARCHY_PVT.Log
535 ( INV_ORGHIERARCHY_PVT.G_LOG_STATEMENT
536 , SUBSTR(x_item_cursor, 251, 500)
537 );
538 INV_ORGHIERARCHY_PVT.Log
539 ( INV_ORGHIERARCHY_PVT.G_LOG_STATEMENT
540 , SUBSTR(x_item_cursor, 501, 750)
541 );
542
543 INV_ORGHIERARCHY_PVT.Log
544 ( INV_ORGHIERARCHY_PVT.G_LOG_PROCEDURE
545 , '< Build_Item_Cursor'
546 );
547 END IF;
548 EXCEPTION
549 WHEN OTHERS THEN
550 IF G_DEBUG = 'Y' THEN
551 INV_ORGHIERARCHY_PVT.Log
552 ( INV_ORGHIERARCHY_PVT.G_LOG_EXCEPTION
553 , FND_FLEX_KEY_API.message
554 );
555 END IF;
556 RAISE;
557
558 END Build_Item_Cursor;
559
560 --=========================================================================
561 -- PROCEDURE : populate_temp_table PUBLIC
562 -- PARAMETERS :
563 -- COMMENT : contruct queries to populate the temp table
564 -- PRE-COND : the table of records must contain all the info necessary
565 -- : to contruct these queries.
566 --=========================================================================
567 /* Bug: 3770547
568 One more input parameter AttributeCategory added to find items that need to be populated*/
569 /* Bug: 4025750
570 One more filter parameter p_copy_dff_to_null added to find items that need to be populated*/
571 PROCEDURE populate_temp_table
572 (p_item_id IN NUMBER
573 ,p_org_code_list IN INV_ORGHIERARCHY_PVT.orgid_tbl_type
574 ,p_cat_id IN NUMBER
575 ,p_cat_set_id IN NUMBER
576 ,p_item_low IN VARCHAR2
577 ,p_item_high IN VARCHAR2
578 ,p_sts_code IN VARCHAR2
579 ,p_attribute_category IN VARCHAR2
580 ,p_copy_dff_to_null IN VARCHAR2)--Added p_copy_dff_to_null parameter for Bug 4025750.
581 IS
582
583 --=================
584 -- LOCAL VARIABLES
585 --=================
586
587 l_dml_str VARCHAR2(250);
588 l_bu_id NUMBER;
589 l_org_id NUMBER;
590 l_org_index BINARY_INTEGER;
591
592 -- ======================
593 -- Dynamic Cursor Variable
594 -- =======================
595 TYPE g_item_cur_type IS REF CURSOR;
596 l_item_cur g_item_cur_type;
597
598 -- Variable to hold the SELECT statement
599 l_item_cursor VARCHAR2(4000);
600
601 -- =========================================
602 -- Dynamic Cursor SELECT statement variables
603 -- =========================================
604 l_organization_code VARCHAR2(3);
605 l_organization_id NUMBER;
606 l_item_number VARCHAR2(1025);
607 l_inventory_item_id NUMBER;
608 l_scenario_id NUMBER;
609
610 /* Added for Bug 4064005.*/
611 item_low_input boolean;
612 item_high_input boolean;
613 item_id_input boolean;
614 cat_set_id_input boolean;
615 sts_code_input boolean;
616 attribute_category_input boolean;
617
618 BEGIN
619 /* Following code block added for bug 4025750.
620 */
621 IF p_attribute_category IS NOT NULL
622 AND p_copy_dff_to_null IS NOT NULL
623 AND p_copy_dff_to_null = 'YES' THEN
627 RPAD('ATTRIBUTE',12,LPAD(TO_CHAR(g_current_att_index + 1),3,'0'));
624 g_current_att_index := g_att_tab.LAST;
625 g_current_att_index := g_current_att_index + 1;
626 g_att_tab(g_current_att_index).temp_column_name :=
628 g_att_tab(g_current_att_index).column_type := 4;
629 g_att_tab(g_current_att_index).item_column_name := 'Attribute_Category';
630 g_att_tab(g_current_att_index).display_column := 'Attribute_Category';
631 g_count := g_count + 1;
632 END IF;
633
634 -- First make sure there is no left over data from a previous
635 -- navigation to this form
636
637 DELETE FROM MTL_ITEM_ATTRIBUTES_TEMP;
638
639 l_org_index := p_org_code_list.FIRST;
640 l_org_id := p_org_code_list(l_org_index);
641
642 /* Added for Bug 4064005. */
643 IF p_item_low IS NULL THEN
644 item_low_input := FALSE;
645 ELSE
646 item_low_input := TRUE;
647 END IF;
648 IF p_item_high IS NULL THEN
649 item_high_input := FALSE;
650 ELSE
651 item_high_input := TRUE;
652 END IF;
653 IF p_item_id = -1 THEN
654 item_id_input := FALSE;
655 ELSE
656 item_id_input := TRUE;
657 END IF;
658 IF p_cat_set_id = -1 THEN
659 cat_set_id_input := FALSE;
660 ELSE cat_set_id_input := TRUE;
661 END IF;
662 IF p_sts_code IS NULL THEN
663 sts_code_input := FALSE;
664 ELSE
665 sts_code_input := TRUE;
666 END IF;
667 IF p_attribute_category IS NULL THEN
668 attribute_category_input := FALSE;
669 ELSE
670 attribute_category_input := TRUE;
671 END IF;
672
673
674 LOOP
675
676 -- populate the temp table with data context data
677
678 -- Build Dynamic cursor
679 -- p_attribute_category is passed as additional in parameter. Bug: 3770547
680 Build_Item_Cursor
681 ( p_category_id => p_cat_id
682 , p_category_set_id => p_cat_set_id
683 , p_item_id => p_item_id
684 , p_item_from => p_item_low
685 , p_item_to => p_item_high
686 , p_organization_id => l_org_id
687 , p_sts_code => p_sts_code
688 , p_attribute_category => p_attribute_category
689 , p_copy_dff_to_null => p_copy_dff_to_null
690 , x_item_cursor => l_item_cursor
691 );
692
693
694 /* Added for Bug 4064005 */
695 IF item_low_input AND item_high_input AND cat_set_id_input AND sts_code_input AND attribute_category_input THEN
696 OPEN l_item_cur FOR l_item_cursor
697 USING l_org_id, p_item_low, p_item_high, p_cat_set_id, p_cat_id, p_sts_code, p_attribute_category;
698 ELSIF item_low_input AND item_high_input AND cat_set_id_input AND sts_code_input AND NOT attribute_category_input THEN
699 OPEN l_item_cur FOR l_item_cursor
700 USING l_org_id, p_item_low, p_item_high, p_cat_set_id, p_cat_id, p_sts_code;
701 ELSIF item_low_input AND NOT item_high_input AND cat_set_id_input AND sts_code_input AND attribute_category_input THEN
702 OPEN l_item_cur FOR l_item_cursor
703 USING l_org_id, p_item_low, p_cat_set_id, p_cat_id, p_sts_code, p_attribute_category;
704 ELSIF item_low_input AND NOT item_high_input AND cat_set_id_input AND sts_code_input AND NOT attribute_category_input THEN
705 OPEN l_item_cur FOR l_item_cursor
706 USING l_org_id, p_item_low, p_cat_set_id, p_cat_id, p_sts_code;
707 ELSIF NOT item_low_input AND item_high_input AND cat_set_id_input AND sts_code_input AND attribute_category_input THEN
708 OPEN l_item_cur FOR l_item_cursor
709 USING l_org_id, p_item_high, p_cat_set_id, p_cat_id, p_sts_code, p_attribute_category;
710 ELSIF NOT item_low_input AND item_high_input AND cat_set_id_input AND sts_code_input AND NOT attribute_category_input THEN
711 OPEN l_item_cur FOR l_item_cursor
712 USING l_org_id, p_item_high, p_cat_set_id, p_cat_id, p_sts_code;
713 ELSIF item_id_input AND cat_set_id_input AND sts_code_input AND attribute_category_input THEN
714 OPEN l_item_cur FOR l_item_cursor
715 USING l_org_id, p_item_id, p_cat_set_id, p_cat_id, p_sts_code, p_attribute_category;
716 ELSIF item_id_input AND cat_set_id_input AND sts_code_input AND NOT attribute_category_input THEN
717 OPEN l_item_cur FOR l_item_cursor
718 USING l_org_id, p_item_id, p_cat_set_id, p_cat_id, p_sts_code;
719 ELSIF item_low_input AND item_high_input AND cat_set_id_input AND NOT sts_code_input AND attribute_category_input THEN
720 OPEN l_item_cur FOR l_item_cursor
721 USING l_org_id, p_item_low, p_item_high, p_cat_set_id, p_cat_id, p_attribute_category;
722 ELSIF item_low_input AND item_high_input AND cat_set_id_input AND NOT sts_code_input AND NOT attribute_category_input THEN
723 OPEN l_item_cur FOR l_item_cursor
724 USING l_org_id, p_item_low, p_item_high, p_cat_set_id, p_cat_id;
728 ELSIF item_low_input AND NOT item_high_input AND cat_set_id_input AND NOT sts_code_input AND NOT attribute_category_input THEN
725 ELSIF item_low_input AND NOT item_high_input AND cat_set_id_input AND NOT sts_code_input AND attribute_category_input THEN
726 OPEN l_item_cur FOR l_item_cursor
727 USING l_org_id, p_item_low, p_cat_set_id, p_cat_id, p_attribute_category;
729 OPEN l_item_cur FOR l_item_cursor
730 USING l_org_id, p_item_low, p_cat_set_id, p_cat_id;
731 ELSIF NOT item_low_input AND item_high_input AND cat_set_id_input AND NOT sts_code_input AND attribute_category_input THEN
732 OPEN l_item_cur FOR l_item_cursor
733 USING l_org_id, p_item_high, p_cat_set_id, p_cat_id, p_attribute_category;
734 ELSIF NOT item_low_input AND item_high_input AND cat_set_id_input AND NOT sts_code_input AND NOT attribute_category_input THEN
735 OPEN l_item_cur FOR l_item_cursor
736 USING l_org_id, p_item_high, p_cat_set_id, p_cat_id;
737 ELSIF item_id_input AND cat_set_id_input AND NOT sts_code_input AND attribute_category_input THEN
738 OPEN l_item_cur FOR l_item_cursor
739 USING l_org_id, p_item_id, p_cat_set_id, p_cat_id, p_attribute_category;
740 ELSIF item_id_input AND cat_set_id_input AND NOT sts_code_input AND NOT attribute_category_input THEN
741 OPEN l_item_cur FOR l_item_cursor
742 USING l_org_id, p_item_id, p_cat_set_id, p_cat_id;
743 ELSIF item_low_input AND item_high_input AND NOT cat_set_id_input AND sts_code_input AND attribute_category_input THEN
744 OPEN l_item_cur FOR l_item_cursor
745 USING l_org_id, p_item_low, p_item_high, p_sts_code, p_attribute_category;
746 ELSIF item_low_input AND item_high_input AND NOT cat_set_id_input AND sts_code_input AND NOT attribute_category_input THEN
747 OPEN l_item_cur FOR l_item_cursor
748 USING l_org_id, p_item_low, p_item_high, p_sts_code;
749 ELSIF item_low_input AND NOT item_high_input AND NOT cat_set_id_input AND sts_code_input AND attribute_category_input THEN
750 OPEN l_item_cur FOR l_item_cursor
751 USING l_org_id, p_item_low, p_sts_code, p_attribute_category;
752 ELSIF item_low_input AND NOT item_high_input AND NOT cat_set_id_input AND sts_code_input AND NOT attribute_category_input THEN
753 OPEN l_item_cur FOR l_item_cursor
754 USING l_org_id, p_item_low, p_sts_code;
755 ELSIF NOT item_low_input AND item_high_input AND NOT cat_set_id_input AND sts_code_input AND attribute_category_input THEN
756 OPEN l_item_cur FOR l_item_cursor
757 USING l_org_id, p_item_high, p_sts_code, p_attribute_category;
758 ELSIF NOT item_low_input AND item_high_input AND NOT cat_set_id_input AND sts_code_input AND NOT attribute_category_input THEN
759 OPEN l_item_cur FOR l_item_cursor
760 USING l_org_id, p_item_high, p_sts_code;
761 ELSIF item_id_input AND NOT cat_set_id_input AND sts_code_input AND attribute_category_input THEN
762 OPEN l_item_cur FOR l_item_cursor
763 USING l_org_id, p_item_id, p_sts_code, p_attribute_category;
764 ELSIF item_id_input AND NOT cat_set_id_input AND sts_code_input AND NOT attribute_category_input THEN
765 OPEN l_item_cur FOR l_item_cursor
766 USING l_org_id, p_item_id, p_sts_code;
767 ELSIF item_low_input AND item_high_input AND NOT cat_set_id_input AND NOT sts_code_input AND attribute_category_input THEN
768 OPEN l_item_cur FOR l_item_cursor
769 USING l_org_id, p_item_low, p_item_high, p_attribute_category;
770 ELSIF item_low_input AND item_high_input AND NOT cat_set_id_input AND NOT sts_code_input AND NOT attribute_category_input THEN
771 OPEN l_item_cur FOR l_item_cursor
772 USING l_org_id, p_item_low, p_item_high;
773 ELSIF item_low_input AND NOT item_high_input AND NOT cat_set_id_input AND NOT sts_code_input AND attribute_category_input THEN
774 OPEN l_item_cur FOR l_item_cursor
775 USING l_org_id, p_item_low, p_attribute_category;
776 ELSIF item_low_input AND NOT item_high_input AND NOT cat_set_id_input AND NOT sts_code_input AND NOT attribute_category_input THEN
777 OPEN l_item_cur FOR l_item_cursor
778 USING l_org_id, p_item_low;
779 ELSIF NOT item_low_input AND item_high_input AND NOT cat_set_id_input AND NOT sts_code_input AND attribute_category_input THEN
780 OPEN l_item_cur FOR l_item_cursor
781 USING l_org_id, p_item_high, p_attribute_category;
782 ELSIF NOT item_low_input AND item_high_input AND NOT cat_set_id_input AND NOT sts_code_input AND NOT attribute_category_input THEN
783 OPEN l_item_cur FOR l_item_cursor
784 USING l_org_id, p_item_high;
785 ELSIF item_id_input AND NOT cat_set_id_input AND NOT sts_code_input AND attribute_category_input THEN
786 OPEN l_item_cur FOR l_item_cursor
787 USING l_org_id, p_item_id, p_attribute_category;
788 ELSIF item_id_input AND NOT cat_set_id_input AND NOT sts_code_input AND NOT attribute_category_input THEN
789 OPEN l_item_cur FOR l_item_cursor
790 USING l_org_id, p_item_id;
791
792 /* Added for Bug 4064006 */
793 ELSIF NOT item_low_input AND NOT item_high_input AND NOT item_id_input AND cat_set_id_input AND sts_code_input AND attribute_category_input THEN
794 OPEN l_item_cur FOR l_item_cursor
795 USING l_org_id, p_cat_set_id, p_cat_id, p_sts_code , p_attribute_category;
796 ELSIF NOT item_low_input AND NOT item_high_input AND NOT item_id_input AND cat_set_id_input AND sts_code_input AND NOT attribute_category_input THEN
797 OPEN l_item_cur FOR l_item_cursor
798 USING l_org_id, p_cat_set_id, p_cat_id, p_sts_code;
799 ELSIF NOT item_low_input AND NOT item_high_input AND NOT item_id_input AND cat_set_id_input AND NOT sts_code_input AND attribute_category_input THEN
800 OPEN l_item_cur FOR l_item_cursor
801 USING l_org_id, p_cat_set_id, p_cat_id, p_attribute_category;
802 ELSIF NOT item_low_input AND NOT item_high_input AND NOT item_id_input AND cat_set_id_input AND NOT sts_code_input AND NOT attribute_category_input THEN
803 OPEN l_item_cur FOR l_item_cursor
804 USING l_org_id, p_cat_set_id, p_cat_id;
805
806 END IF;
807
808 /* Commented during bug 4064005
812 IF p_item_low IS NOT NULL
809 -- Item Info for the selected category set, category, item range or item id
810 -- with inventory item status code
811
813 AND p_item_high IS NOT NULL
814 AND p_cat_id <> -1
815 --Bug#3497035
816 -- AND p_cat_set_id IS NOT NULL
817 AND p_cat_set_id <> -1
818 AND p_sts_code IS NOT NULL THEN
819
820 OPEN l_item_cur FOR l_item_cursor
821 USING
822 l_org_id, p_item_low, p_item_high, p_cat_set_id, p_cat_id, p_sts_code;
823
824 ELSIF p_item_low IS NOT NULL
825 AND p_item_high IS NULL
826 AND p_cat_id <> -1
827 --Bug#3497035
828 -- AND p_cat_set_id IS NOT NULL
829 AND p_cat_set_id <> -1
830 AND p_sts_code IS NOT NULL THEN
831
832 OPEN l_item_cur FOR l_item_cursor
833 USING
834 l_org_id, p_item_low, p_cat_set_id, p_cat_id, p_sts_code;
835
836 ELSIF p_item_low IS NULL
837 AND p_item_high IS NOT NULL
838 AND p_cat_id <> -1
839 --Bug#3497035
840 -- AND p_cat_set_id IS NOT NULL
841 AND p_cat_set_id <> -1
842 AND p_sts_code IS NOT NULL THEN
843
844 OPEN l_item_cur FOR l_item_cursor
845 USING
846 l_org_id, p_item_high, p_cat_set_id, p_cat_id, p_sts_code;
847
848 ELSIF p_item_id <> -1
849 AND p_cat_id <> -1
850 --Bug#3497035
851 -- AND p_cat_set_id IS NOT NULL
852 AND p_cat_set_id <> -1
853 AND p_sts_code IS NOT NULL THEN
854
855 OPEN l_item_cur FOR l_item_cursor
856 USING
857 l_org_id, p_item_id, p_cat_set_id, p_cat_id, p_sts_code;
858
859 ELSIF p_item_low IS NOT NULL
860 AND p_item_high IS NOT NULL
861 AND p_cat_id <> -1
862 --Bug#3497035
863 -- AND p_cat_set_id IS NOT NULL
864 AND p_cat_set_id <> -1
865 AND p_sts_code IS NULL THEN
866
867 OPEN l_item_cur FOR l_item_cursor
868 USING
869 l_org_id, p_item_low, p_item_high, p_cat_set_id, p_cat_id;
870
871 ELSIF p_item_low IS NOT NULL
872 AND p_item_high IS NULL
873 AND p_cat_id <> -1
874 --Bug#3497035
875 -- AND p_cat_set_id IS NOT NULL
876 AND p_cat_set_id <> -1
877 AND p_sts_code IS NULL THEN
878
879 OPEN l_item_cur FOR l_item_cursor
880 USING
881 l_org_id, p_item_low, p_cat_set_id, p_cat_id;
882
883 ELSIF p_item_low IS NULL
884 AND p_item_high IS NOT NULL
885 AND p_cat_id <> -1
886 --Bug#3497035
887 -- AND p_cat_set_id IS NOT NULL
888 AND p_cat_set_id <> -1
889 AND p_sts_code IS NULL THEN
890
891 OPEN l_item_cur FOR l_item_cursor
892 USING
893 l_org_id, p_item_high, p_cat_set_id, p_cat_id;
894
895 ELSIF p_item_id <> -1
896 AND p_cat_id <> -1
897 --Bug#3497035
898 -- AND p_cat_set_id IS NOT NULL
899 AND p_cat_set_id <> -1
900 AND p_sts_code IS NULL THEN
901
902 OPEN l_item_cur FOR l_item_cursor
903 USING
904 l_org_id, p_item_id, p_cat_set_id, p_cat_id;
905
906 ELSIF p_item_low IS NOT NULL
907 AND p_item_high IS NOT NULL
908 --Bug#3497035
909 AND (p_cat_id = -1 OR p_cat_set_id = -1)
910 -- AND (p_cat_id = -1 OR p_cat_set_id IS NULL)
911 AND p_sts_code IS NOT NULL THEN
912
913 OPEN l_item_cur FOR l_item_cursor
914 USING
915 l_org_id, p_item_low, p_item_high, p_sts_code;
916
917 ELSIF p_item_low IS NOT NULL
918 AND p_item_high IS NULL
919 --Bug#3497035
920 AND (p_cat_id = -1 OR p_cat_set_id = -1)
921 -- AND (p_cat_id = -1 OR p_cat_set_id IS NULL)
922 AND p_sts_code IS NOT NULL THEN
923
924 OPEN l_item_cur FOR l_item_cursor
925 USING
926 l_org_id, p_item_low, p_sts_code;
927
928 ELSIF p_item_low IS NULL
929 AND p_item_high IS NOT NULL
930 --Bug#3497035
931 AND (p_cat_id = -1 OR p_cat_set_id = -1)
932 -- AND (p_cat_id = -1 OR p_cat_set_id IS NULL)
933 AND p_sts_code IS NOT NULL THEN
934
935 OPEN l_item_cur FOR l_item_cursor
936 USING
937 l_org_id, p_item_high, p_sts_code;
938
939 ELSIF p_item_id <> -1
940 --Bug#3497035
941 AND (p_cat_id = -1 OR p_cat_set_id = -1)
942 -- AND (p_cat_id = -1 OR p_cat_set_id IS NULL)
943 AND p_sts_code IS NOT NULL THEN
944
945 OPEN l_item_cur FOR l_item_cursor
946 USING
947 l_org_id, p_item_id, p_sts_code;
948
949 ELSIF p_item_low IS NOT NULL
950 AND p_item_high IS NOT NULL
951 --Bug#3497035
952 AND (p_cat_id = -1 OR p_cat_set_id = -1)
953 -- AND (p_cat_id = -1 OR p_cat_set_id IS NULL)
954 AND p_sts_code IS NULL THEN
955
956 OPEN l_item_cur FOR l_item_cursor
957 USING
958 l_org_id, p_item_low, p_item_high;
959
960 ELSIF p_item_low IS NOT NULL
961 AND p_item_high IS NULL
962 --Bug#3497035
963 AND (p_cat_id = -1 OR p_cat_set_id = -1)
964 -- AND (p_cat_id = -1 OR p_cat_set_id IS NULL)
965 AND p_sts_code IS NULL THEN
966
967 OPEN l_item_cur FOR l_item_cursor
968 USING
969 l_org_id, p_item_low;
970
971 ELSIF p_item_low IS NULL
972 AND p_item_high IS NOT NULL
973 --Bug#3497035
974 AND (p_cat_id = -1 OR p_cat_set_id = -1)
975 -- AND (p_cat_id = -1 OR p_cat_set_id IS NULL)
976 AND p_sts_code IS NULL THEN
977
978 OPEN l_item_cur FOR l_item_cursor
979 USING
980 l_org_id, p_item_high;
981
982 ELSIF p_item_id <> -1
983 --Bug#3497035
987
984 AND (p_cat_id = -1 OR p_cat_set_id = -1)
985 -- AND (p_cat_id = -1 OR p_cat_set_id IS NULL)
986 AND p_sts_code IS NULL THEN
988 OPEN l_item_cur FOR l_item_cursor
989 USING
990 l_org_id, p_item_id;
991
992 END IF;
993 */
994
995
996 FETCH l_item_cur
997 INTO l_organization_code
998 ,l_organization_id
999 ,l_item_number
1000 ,l_inventory_item_id;
1001
1002 WHILE l_item_cur%FOUND LOOP
1003
1004 IF G_DEBUG = 'Y' THEN
1005 INV_ORGHIERARCHY_PVT.Log
1006 ( INV_ORGHIERARCHY_PVT.G_LOG_EVENT
1007 , 'Organization Code:' || l_organization_code || ' ' ||
1008 'Organization Id:' || l_organization_id || ' ' ||
1009 'Item Number:' || l_item_number || ' ' ||
1010 'Inventory Item Id:' || l_inventory_item_id
1011 );
1012 END IF;
1013
1014 -- populate the table
1015 INSERT INTO MTL_ITEM_ATTRIBUTES_TEMP(
1016 organization_code
1017 ,organization_id
1018 ,item_code
1019 ,item_id
1020 )
1021 VALUES
1022 ( l_organization_code
1023 , l_organization_id
1024 , l_item_number
1025 , l_inventory_item_id
1026 );
1027
1028 FETCH l_item_cur
1029 INTO l_organization_code
1030 ,l_organization_id
1031 ,l_item_number
1032 ,l_inventory_item_id;
1033
1034
1035 END LOOP; -- item cursor loop
1036
1037 CLOSE l_item_cur;
1038
1039 EXIT WHEN l_org_index = p_org_code_list.LAST;
1040 l_org_index := p_org_code_list.NEXT(l_org_index);
1041 l_org_id := p_org_code_list(l_org_index);
1042
1043 END LOOP;
1044
1045 g_current_att_index := g_att_tab.FIRST;
1046
1047 LOOP
1048
1049 IF g_att_tab(g_current_att_index).column_type = 1 THEN
1050
1051
1052 l_dml_str := 'UPDATE MTL_ITEM_ATTRIBUTES_TEMP tmp SET ( '
1053 || g_att_tab(g_current_att_index).temp_column_name
1054 || ' ) = '
1055 || ' (SELECT '
1056 || g_att_tab(g_current_att_index).item_column_name
1057 || ' FROM MTL_SYSTEM_ITEMS_VL itm '
1058 || ' WHERE tmp.item_id = itm.inventory_item_id '
1059 || ' AND tmp.organization_id = itm.organization_id '
1060 || ')';
1061
1062 EXECUTE IMMEDIATE l_dml_str;
1063 /*myerrams, Modified the following query to use bind variables. Bug: 5001785*/
1064 l_dml_str := 'UPDATE MTL_ITEM_ATTRIBUTES_TEMP TMP SET ( '
1065 || CONCAT(g_att_tab(g_current_att_index).temp_column_name,'_DSP')
1066 || ' ) = '
1067 || ' (SELECT FND.'
1068 || g_att_tab(g_current_att_index).lookup_column
1069 || ' FROM '
1070 || g_att_tab(g_current_att_index).lookup_table
1071 || ' FND '
1072 || ' WHERE FND.'
1073 || g_att_tab(g_current_att_index).lookup_type
1074 || ' = :1'
1075 || ' AND FND.'
1076 || g_att_tab(g_current_att_index).reference_key_column
1077 || ' = '
1078 || ' TMP.'
1079 || g_att_tab(g_current_att_index).temp_column_name
1080 || ')';
1081
1082 EXECUTE IMMEDIATE l_dml_str
1083 USING g_att_tab(g_current_att_index).lookup_type_value;
1084
1085 ELSIF g_att_tab(g_current_att_index).column_type = 2 THEN
1086
1087 l_dml_str := 'UPDATE MTL_ITEM_ATTRIBUTES_TEMP TMP SET ( '
1088 || g_att_tab(g_current_att_index).temp_column_name
1089 || ' ) = '
1090 || ' (SELECT '
1091 || g_att_tab(g_current_att_index).item_column_name
1092 || ' FROM MTL_SYSTEM_ITEMS_VL ITM '
1093 || ' WHERE TMP.item_id = ITM.inventory_item_id '
1094 || ' AND TMP.organization_id = ITM.organization_id '
1095 || ')';
1096
1097 EXECUTE IMMEDIATE l_dml_str;
1098
1099 l_dml_str := 'UPDATE MTL_ITEM_ATTRIBUTES_TEMP TMP SET ( '
1100 || CONCAT(g_att_tab(g_current_att_index).temp_column_name,'_DSP')
1101 || ' ) = '
1102 || ' (SELECT FND.'
1103 || g_att_tab(g_current_att_index).lookup_column
1104 || ' FROM '
1105 || g_att_tab(g_current_att_index).lookup_table
1106 || ' FND '
1107 || ' WHERE FND.'
1108 || g_att_tab(g_current_att_index).lookup_type_value
1109 || ' = '
1110 || ' TMP.'
1111 || g_att_tab(g_current_att_index).temp_column_name
1112 || ')';
1113
1114 EXECUTE IMMEDIATE l_dml_str;
1115
1116 ELSE
1117
1118 l_dml_str := 'UPDATE MTL_ITEM_ATTRIBUTES_TEMP tmp SET ( '
1119 || g_att_tab(g_current_att_index).temp_column_name
1120 || ' ) = '
1121 || ' (SELECT '
1122 || g_att_tab(g_current_att_index).item_column_name
1123 || ' FROM MTL_SYSTEM_ITEMS_VL itm '
1124 || ' WHERE tmp.item_id = itm.inventory_item_id '
1125 || ' AND tmp.organization_id = itm.organization_id '
1126 || ')';
1127
1128
1129 EXECUTE IMMEDIATE l_dml_str;
1130
1131 l_dml_str := 'UPDATE MTL_ITEM_ATTRIBUTES_TEMP tmp SET ( '
1132 || CONCAT(g_att_tab(g_current_att_index).temp_column_name,'_dsp')
1133 || ' ) = '
1134 || ' (SELECT '
1135 || g_att_tab(g_current_att_index).item_column_name
1136 || ' FROM MTL_SYSTEM_ITEMS_VL itm '
1137 || ' WHERE tmp.item_id = itm.inventory_item_id '
1138 || ' AND tmp.organization_id = itm.organization_id '
1139 || ')';
1140
1141 EXECUTE IMMEDIATE l_dml_str;
1142
1143 END IF;
1144
1148
1145 EXIT WHEN g_current_att_index = g_att_tab.LAST;
1146
1147 g_current_att_index := g_att_tab.NEXT(g_current_att_index);
1149 END LOOP;
1150
1151 COMMIT;
1152
1153 EXCEPTION
1154 WHEN OTHERS THEN
1155 IF FND_MSG_PUB.Check_Msg_Level(FND_MSG_PUB.G_MSG_LVL_UNEXP_ERROR)
1156 THEN
1157 FND_MSG_PUB.Add_Exc_Msg( G_INV_ITEM_ATTRIBUTES_PKG
1158 , 'populate_temp_table'
1159 );
1160 END IF;
1161 RAISE;
1162
1163 END populate_temp_table;
1164
1165 --=========================================================================
1166 -- PROCEDURE : clear_temp_table PUBLIC
1167 -- PARAMETERS :
1168 -- COMMENT : clear MTL_ITEM_ATTRIBUTES_TEMP
1169 -- simple command to purge all records in temp table
1170 -- this may not seem necessary as a temp table loses
1171 -- it's data at the eand of each session.
1172 -- However the session will last until the form is
1173 -- dismissed and the user may query several times
1174 -- before dismissing the form.
1175 -- Each time there is a new query the temp table
1176 -- needs to be purged.
1177
1178 -- PRE-COND : This procedure prior to poulating the temp table
1179 --=========================================================================
1180 PROCEDURE clear_temp_table
1181 IS
1182
1183 BEGIN
1184
1185 delete MTL_ITEM_ATTRIBUTES_TEMP;
1186
1187 commit;
1188
1189 EXCEPTION
1190 WHEN OTHERS THEN
1191 IF FND_MSG_PUB.Check_Msg_Level(FND_MSG_PUB.G_MSG_LVL_UNEXP_ERROR)
1192 THEN
1193 FND_MSG_PUB.Add_Exc_Msg( G_INV_ITEM_ATTRIBUTES_PKG
1194 , 'clear_temp_table'
1195 );
1196 END IF;
1197 RAISE;
1198 END clear_temp_table;
1199
1200 --=========================================================================
1201 -- PROCEDURE : find_org_list PUBLIC
1202 -- PARAMETERS :
1203 -- COMMENT : Find the organizations that exist in the master org
1204 -- PRE-COND : called from form
1205 --=========================================================================
1206 PROCEDURE find_org_list
1207 ( p_org_tab OUT NOCOPY INV_ORGHIERARCHY_PVT.orgid_tbl_type
1208 )
1209 IS
1210
1211 --================
1212 -- CURSORS
1213 --================
1214
1215 CURSOR org_cur IS
1216 SELECT ORGANIZATION_ID
1217 FROM ORG_ORGANIZATION_DEFINITIONS
1218 WHERE ORGANIZATION_ID IN
1219 (SELECT DISTINCT ORGANIZATION_ID_PARENT
1220 FROM PER_ORG_STRUCTURE_ELEMENTS)
1221 OR
1222 ORGANIZATION_ID IN
1223 (SELECT ORGANIZATION_ID_CHILD
1224 FROM PER_ORG_STRUCTURE_ELEMENTS)
1225 ORDER BY ORGANIZATION_NAME;
1226
1227 BEGIN
1228
1229 -- clear the pl/sql table before use
1230 g_org_tab := g_empty_org_tab;
1231
1232 -- open cursor
1233
1234 IF NOT org_cur%ISOPEN
1235 THEN
1236 OPEN org_cur;
1237 END IF;
1238
1239 FETCH org_cur INTO g_org_tab(g_org_tab.COUNT+1);
1240
1241 WHILE org_cur%FOUND
1242 LOOP
1243
1244 FETCH org_cur INTO g_org_tab(g_org_tab.COUNT+1);
1245
1246 END LOOP;
1247
1248 CLOSE org_cur;
1249
1250 p_org_tab := g_org_tab;
1251
1252 EXCEPTION
1253 WHEN OTHERS THEN
1254 IF FND_MSG_PUB.Check_Msg_Level(FND_MSG_PUB.G_MSG_LVL_UNEXP_ERROR)
1255 THEN
1256 FND_MSG_PUB.Add_Exc_Msg( G_INV_ITEM_ATTRIBUTES_PKG
1257 , 'find_org_list'
1258 );
1259 END IF;
1260 END find_org_list;
1261
1262 --=========================================================================
1263 -- PROCEDURE : call_item_update PUBLIC
1264 -- PARAMETERS :
1265 -- COMMENT : This procedure is not currently used.
1266 -- : If the form is enhanced to offer an online
1267 -- : option in the future the code to offer that
1268 -- : functionality should be written here
1269 -- PRE-COND : This procedure will be called from the form
1270 --=========================================================================
1271 PROCEDURE call_item_update
1272 ( p_att_tab IN INV_ITEM_ATTRIBUTES_PKG.att_tbl_type
1273 ,p_sel_tab IN INV_ITEM_ATTRIBUTES_PKG.sel_tbl_type
1274 ,p_inventory_item_id OUT NOCOPY NUMBER
1275 ,p_organization_id OUT NOCOPY NUMBER
1276 ,p_return_status OUT NOCOPY VARCHAR2
1277 ,p_error_tab OUT NOCOPY INV_Item_GRP.Error_tbl_type
1278 )
1279 IS
1280
1281 x_errbuff VARCHAR2(240);
1282 x_retcode NUMBER;
1283
1284 BEGIN
1285
1286 x_errbuff := NULL;
1287 x_retcode := 0;
1288
1289 EXCEPTION
1290 WHEN OTHERS THEN
1291 IF FND_MSG_PUB.Check_Msg_Level(FND_MSG_PUB.G_MSG_LVL_UNEXP_ERROR)
1292 THEN
1293 FND_MSG_PUB.Add_Exc_Msg( G_INV_ITEM_ATTRIBUTES_PKG
1294 , 'call_item_update'
1295 );
1296 END IF;
1297 x_retcode := 2;
1298 x_errbuff := FND_MSG_PUB.Get(p_encoded => FND_API.G_FALSE);
1299 END call_item_update;
1300
1301 --=========================================================================
1302 -- PROCEDURE : Determine_Return_Code PRIVATE
1303 -- PARAMETERS: x_retcode OUT NOCOPY Return code
1304 -- x_errbuff OUT NOCOPY Return message
1305 -- COMMENT : This procedure verifies that all the records have been
1309 PROCEDURE Determine_Return_Code
1306 -- successfully processed by the Item Open Interface program and
1307 -- returns a warning in case of failure.
1308 --=========================================================================
1310 ( x_retcode OUT NOCOPY VARCHAR2
1311 , x_errbuff OUT NOCOPY VARCHAR2
1312 )
1313 IS
1314 l_error_count NUMBER;
1315 BEGIN
1316
1317 IF G_DEBUG = 'Y' THEN
1318 INV_ORGHIERARCHY_PVT.Log
1319 ( INV_ORGHIERARCHY_PVT.G_LOG_PROCEDURE
1320 , '> Determine_Return_Code'
1321 );
1322 END IF;
1323
1324 SELECT COUNT(*)
1325 INTO l_error_count
1326 FROM mtl_system_items_interface
1327 WHERE NVL(request_id, 0) = NVL(FND_GLOBAL.conc_request_id, 0);
1328
1329 IF l_error_count > 0 THEN
1330 x_retcode := RETCODE_WARNING;
1331 FND_MESSAGE.Set_Name('INV', 'INV_MGD_ITEM_ORG_ASSIGN_WARN');
1332 FND_MESSAGE.Set_Token('RECORD_NUMBER', l_error_count);
1333 x_errbuff := FND_MESSAGE.Get;
1334 ELSE
1335 x_retcode := RETCODE_SUCCESS;
1336 x_errbuff := NULL;
1337 END IF;
1338 IF G_DEBUG = 'Y' THEN
1339 INV_ORGHIERARCHY_PVT.Log
1340 ( INV_ORGHIERARCHY_PVT.G_LOG_PROCEDURE
1341 , '< Determine_Return_Code'
1342 );
1343 END IF;
1344
1345 END Determine_Return_Code;
1346
1347 --========================================================================
1348 -- FUNCTION : Has_Worker_Completed PRIVATE
1349 -- PARAMETERS: p_request_id IN NUMBER
1350 -- RETURNS : BOOLEAN
1351 -- COMMENT : Accepts a request ID. TRUE if the corresponding worker
1352 -- has completed; FALSE otherwise
1353 --=========================================================================
1354 FUNCTION Has_Worker_Completed
1355 ( p_request_id IN NUMBER
1356 )
1357 RETURN BOOLEAN
1358 IS
1359 l_count NUMBER;
1360 l_result BOOLEAN;
1361 BEGIN
1362
1363 IF G_DEBUG = 'Y' THEN
1364 INV_ORGHIERARCHY_PVT.Log
1365 ( INV_ORGHIERARCHY_PVT.G_LOG_PROCEDURE
1366 , '> Has_Worker_Completed'
1367 );
1368 END IF;
1369
1370 SELECT COUNT(*)
1371 INTO l_count
1372 FROM fnd_concurrent_requests
1373 WHERE request_id = p_request_id
1374 AND phase_code = 'C';
1375
1376 IF l_count = 1 THEN
1377 l_result := TRUE;
1378 ELSE
1379 l_result := FALSE;
1380 END IF;
1381
1382 IF G_DEBUG = 'Y' THEN
1383 INV_ORGHIERARCHY_PVT.Log
1384 ( INV_ORGHIERARCHY_PVT.G_LOG_PROCEDURE
1385 , '< Has_Worker_Completed'
1386 );
1387 END IF;
1388
1389 RETURN l_result;
1390
1391 END Has_Worker_Completed;
1392
1393 --========================================================================
1394 -- PROCEDURE : Wait_For_Worker PRIVATE
1395 -- PARAMETERS: p_workers IN workers' request ID
1396 -- x_worker_idx OUT position in p_workers of the
1397 -- completed worked
1398 -- COMMENT : This procedure polls the submitted workers and suspend
1399 -- the program till the completion of one of them; it returns
1400 -- the completed worker through x_worker_idx
1401 --=========================================================================
1402 PROCEDURE Wait_For_Worker
1403 ( p_workers IN g_request_tbl_type
1404 , x_worker_idx OUT NOCOPY BINARY_INTEGER
1405 )
1406 IS
1407 l_done BOOLEAN;
1408 BEGIN
1409
1410 IF G_DEBUG = 'Y' THEN
1411 INV_ORGHIERARCHY_PVT.Log
1412 ( INV_ORGHIERARCHY_PVT.G_LOG_PROCEDURE
1413 , '> Wait_For_Worker'
1414 );
1415 END IF;
1416
1417 l_done := FALSE;
1418
1419 WHILE (NOT l_done) LOOP
1420
1421 FOR l_Idx IN 1..p_workers.COUNT LOOP
1422
1423 IF Has_Worker_Completed(p_workers(l_Idx)) THEN
1424 l_done := TRUE;
1425 x_worker_idx := l_Idx;
1426 EXIT;
1427 END IF;
1428
1429 END LOOP;
1430
1431 IF (NOT l_done) THEN
1432 DBMS_LOCK.sleep(G_SLEEP_TIME);
1433 END IF;
1434
1435 END LOOP;
1436
1437 IF G_DEBUG = 'Y' THEN
1438 INV_ORGHIERARCHY_PVT.Log
1439 ( INV_ORGHIERARCHY_PVT.G_LOG_PROCEDURE
1440 , '< Wait_For_Worker'
1441 );
1442 END IF;
1443
1444 END Wait_For_Worker;
1445
1446
1447 --========================================================================
1448 -- PROCEDURE : Wait_For_All_Workers PRIVATE
1449 -- PARAMETERS: p_workers IN workers' request ID
1450 -- COMMENT : This procedure polls the submitted workers and suspend
1451 -- the program till the completion of all of them.
1452 --=========================================================================
1453 PROCEDURE Wait_For_All_Workers
1454 ( p_workers IN g_request_tbl_type
1455 )
1456 IS
1457 l_done BOOLEAN;
1458 BEGIN
1459
1460 IF G_DEBUG = 'Y' THEN
1461 INV_ORGHIERARCHY_PVT.Log
1462 ( INV_ORGHIERARCHY_PVT.G_LOG_PROCEDURE
1463 , '> Wait_For_All_Workers'
1464 );
1465 END IF;
1466
1467 l_done := FALSE;
1468
1469 WHILE (NOT l_done) LOOP
1470
1471 l_done := TRUE;
1472
1473 FOR l_Idx IN 1..p_workers.COUNT LOOP
1474
1475 IF NOT Has_Worker_Completed(p_workers(l_Idx)) THEN
1476 l_done := FALSE;
1477 EXIT;
1478 END IF;
1479
1480 END LOOP;
1481
1482 IF (NOT l_done) THEN
1483 DBMS_LOCK.sleep(G_SLEEP_TIME);
1484 END IF;
1485
1486 END LOOP;
1487
1491 , '< Wait_For_All_Workers'
1488 IF G_DEBUG = 'Y' THEN
1489 INV_ORGHIERARCHY_PVT.Log
1490 ( INV_ORGHIERARCHY_PVT.G_LOG_PROCEDURE
1492 );
1493 END IF;
1494
1495 END Wait_For_All_Workers;
1496
1497 --========================================================================
1498 -- PROCEDURE : Submit_Item_Update PRIVATE
1499 -- PARAMETERS: p_organization_id IN an organization
1500 -- p_set_process_id IN Set process ID
1501 -- x_workers IN OUT NOCOPY workers' request ID
1502 -- p_request_count IN max worker number
1503 -- COMMENT : This procedure submits the Item Update concurrent program.
1504 -- Before submitting the request, it verifies that there are
1505 -- enough workers available and wait for the completion of one
1506 -- if necessary.
1507 -- The list of workers' request ID is updated.
1508 --=========================================================================
1509 PROCEDURE Submit_Item_Update
1510 ( p_organization_id IN NUMBER
1511 , p_set_process_id IN NUMBER
1512 , x_workers IN OUT NOCOPY g_request_tbl_type
1513 , p_request_count IN NUMBER
1514 )
1515 IS
1516 l_worker_idx BINARY_INTEGER;
1517 l_request_id NUMBER;
1518 BEGIN
1519
1520 IF G_DEBUG = 'Y' THEN
1521 INV_ORGHIERARCHY_PVT.Log
1522 ( INV_ORGHIERARCHY_PVT.G_LOG_PROCEDURE
1523 , '> Submit_Item_Update'
1524 );
1525
1526 INV_ORGHIERARCHY_PVT.Log
1527 ( INV_ORGHIERARCHY_PVT.G_LOG_STATEMENT
1528 , 'x_workers.COUNT: '||TO_CHAR(x_workers.COUNT)
1529 );
1530 END IF;
1531
1532 IF NOT g_unit_test_mode THEN
1533
1534 IF x_workers.COUNT < p_request_count THEN
1535 -- number of workers submitted so far does not exceed the maximum
1536 -- number of workers allowed
1537 l_worker_idx := x_workers.COUNT + 1;
1538 ELSE
1539 -- need to wait for a submitted worker to finish
1540 Wait_For_Worker
1541 ( p_workers => x_workers
1542 , x_worker_idx => l_worker_idx
1543 );
1544 END IF;
1545
1546 IF NOT FND_REQUEST.Set_Options
1547 ( implicit => 'WARNING'
1548 , protected => 'YES'
1549 )
1550 THEN
1551 RAISE g_submit_failure_exc;
1552 END IF;
1553
1554 -- argument 7 is the run mode which is 2 for update
1555
1556 x_workers(l_worker_idx):= FND_REQUEST.Submit_Request
1557 ( application => 'INV'
1558 , program => 'INCOIN'
1559 , argument1 => p_organization_id
1560 , argument2 => 1
1561 , argument3 => 1
1562 , argument4 => 1
1563 , argument5 => 1
1564 , argument6 => p_set_process_id
1565 , argument7 => 2
1566 );
1567
1568 IF x_workers(l_worker_idx) = 0 THEN
1569 RAISE g_submit_failure_exc;
1570 END IF;
1571
1572 END IF;
1573
1574 COMMIT;
1575
1576 IF G_DEBUG = 'Y' THEN
1577 INV_ORGHIERARCHY_PVT.Log
1578 ( INV_ORGHIERARCHY_PVT.G_LOG_PROCEDURE
1579 , '< Submit_Item_Update'
1580 );
1581 END IF;
1582
1583 END Submit_Item_Update;
1584
1585 --========================================================================
1586 -- FUNCTION : Get_Set_Process_ID PRIVATE
1587 -- PARAMETERS: None
1588 -- RETURNS : NUMBER
1589 -- COMMENT : This function returns the next set process ID to be used to
1590 -- run the Item Open Interface
1591 --=========================================================================
1592 FUNCTION Get_Set_Process_ID
1593 RETURN NUMBER
1594 IS
1595 l_set_process_id NUMBER;
1596 BEGIN
1597
1598 IF G_DEBUG = 'Y' THEN
1599 INV_ORGHIERARCHY_PVT.Log
1600 ( INV_ORGHIERARCHY_PVT.G_LOG_PROCEDURE
1601 , '> Get_Set_Process_ID'
1602 );
1603 END IF;
1604
1605 SELECT mtl_system_items_intf_sets_s.NEXTVAL
1606 INTO l_set_process_id
1607 FROM dual;
1608
1609 IF G_DEBUG = 'Y' THEN
1610 INV_ORGHIERARCHY_PVT.Log
1611 ( INV_ORGHIERARCHY_PVT.G_LOG_PROCEDURE
1612 , '< Get_Set_Process_ID'
1613 );
1614 END IF;
1615
1616 RETURN l_set_process_id;
1617
1618 END Get_Set_Process_ID;
1619
1620 --========================================================================
1621 -- FUNCTION : Get_Master_Org PRIVATE
1622 -- PARAMETERS: p_org_hier_level_id IN Organization Hierarchy
1623 -- Level Id
1624 -- RETURNS : NUMBER
1625 -- COMMENT : This function returns the ID of the master organization
1626 -- common to all the organizations in the hierarchy.
1627 --=========================================================================
1628 FUNCTION Get_Master_Org
1629 ( p_org_hier_level_id IN NUMBER
1630 )
1631 RETURN NUMBER
1632 IS
1633 l_master_org_id NUMBER;
1634 BEGIN
1635
1636 SELECT master_organization_id
1637 INTO l_master_org_id
1638 FROM mtl_parameters
1639 WHERE organization_id = p_org_hier_level_id;
1640
1641 RETURN l_master_org_id;
1642
1643 END Get_Master_Org;
1644
1645 --========================================================================
1649 -- enables it to run it from SQL*Plus. The Item Interface will
1646 -- PROCEDURE : Set_Unit_Test_Mode PUBLIC
1647 -- COMMENT : This procedure sets the unit test mode that prevents the
1648 -- program from attempting to submit concurrent requests and
1650 -- not be run.
1651 --=========================================================================
1652 PROCEDURE Set_Unit_Test
1653 IS
1654 BEGIN
1655 g_unit_test_mode := TRUE;
1656 END Set_Unit_Test;
1657
1658 --=========================================================================
1659 -- PROCEDURE : batch item update PUBLIC
1660 -- PARAMETERS: x_errbuf error buffer
1661 -- x_retcode 0 success, 1 warning, 2 error
1662 -- p_seq_id sequence number
1663 -- COMMENT : Called from a concurrent program if used
1664 -- this procedure allows the user to work in a
1665 -- no modal fashion.
1666 -- Blanket Update records in the MTL_SYSTEM_ITEMS table
1667 -- The struct att_tab contains the columns that
1668 -- are to be updated and the default values they are
1669 -- to be updated to.
1670 -- The struct sel_tab contains the unique id
1671 -- of the records that are to be updated
1672 -- The procedure constructs the record p_item_rec
1673 -- with the default values
1674 -- It then loops through the selected records
1675 -- and calls the published item update api
1676 -- for each unique record.
1677 -- PRE-COND : This procedure will be called from the form
1678 --=========================================================================
1679 PROCEDURE batch_item_update
1680 ( x_errbuff OUT NOCOPY VARCHAR2
1681 , x_retcode OUT NOCOPY NUMBER
1682 , p_seq_id IN NUMBER
1683 )
1684
1685 IS
1686
1687 --================
1688 -- TYPE
1689 --================
1690
1691 TYPE itm_rec_type IS
1692 RECORD (item_column_name VARCHAR2(240)
1693 ,chosen_value VARCHAR2(240));
1694
1695 TYPE itm_tbl_type IS TABLE OF itm_rec_type
1696 INDEX BY BINARY_INTEGER;
1697
1698 TYPE upd_rec_type IS
1699 RECORD (item_id NUMBER
1700 ,organization_id NUMBER);
1701
1702 TYPE upd_tbl_type IS TABLE OF upd_rec_type
1703 INDEX BY BINARY_INTEGER;
1704
1705 --================
1706 -- CURSORS
1707 --================
1708
1709 CURSOR att_cur IS
1710 SELECT item_column_name
1711 ,chosen_value
1712 FROM mtl_item_values_temp
1713 WHERE item_update_id = p_seq_id
1714 ORDER BY current_att_index;
1715
1716 CURSOR sel_cur IS
1717 SELECT inventory_item_id
1718 ,organization_id
1719 FROM mtl_update_records_temp
1720 WHERE item_update_id = p_seq_id;
1721
1722 --=================
1723 -- LOCAL VARIABLES
1724 --=================
1725 l_current_sel_index BINARY_INTEGER := 0;
1726 l_current_att_index BINARY_INTEGER := 0;
1727 l_att_tab itm_tbl_type;
1728 l_sel_tab upd_tbl_type;
1729
1730 l_commit VARCHAR2(20) := fnd_api.g_FALSE;
1731 l_lock_rows VARCHAR2(20) := fnd_api.g_TRUE;
1732 l_validation_level NUMBER := fnd_api.g_VALID_LEVEL_FULL;
1733 l_item_rec INV_Item_GRP.Item_rec_type;
1734 x_item_rec INV_Item_GRP.Item_rec_type;
1735 x_return_status VARCHAR2(1);
1736 x_Error_tbl INV_Item_GRP.Error_tbl_type;
1737 l_sel_item VARCHAR2(24);
1738 l_org_code VARCHAR2(24);
1739 l_status VARCHAR2(10);
1740 l_dml_str VARCHAR2(250);
1741 l_max_batch_size NUMBER;
1742 l_batch_size NUMBER;
1743 l_master_org_id NUMBER;
1744 l_min_index NUMBER;
1745 l_max_index NUMBER;
1746 l_set_process_id NUMBER;
1747 l_organization_id NUMBER;
1748 l_workers_tbl g_request_tbl_type;
1749 l_request_count NUMBER;
1750 l_count NUMBER;
1751 l_data_type VARCHAR2(24);
1752
1753 -- variables for FND_INSTALLATION procedure
1754 l_app_owner_schema VARCHAR2(30);
1755 l_app_status VARCHAR2(1);
1756 l_app_industry VARCHAR2(1);
1757 l_app_info_status BOOLEAN;
1758
1759 BEGIN
1760
1761 INV_ORGHIERARCHY_PVT.Log_Initialize;
1762
1763 IF G_DEBUG = 'Y' THEN
1764 INV_ORGHIERARCHY_PVT.Log
1765 ( INV_ORGHIERARCHY_PVT.G_LOG_PROCEDURE
1766 , '> Batch Item Update'
1767 );
1768 END IF;
1769
1770 -- the following select and if statement are included
1771 -- to ensure the INV_ITEM_ATTRIBUTES_PKG is compiled
1772 -- system tests found that the dependancy on package
1773 --
1774 SELECT status
1775 INTO l_status
1776 FROM user_objects
1777 WHERE object_name = 'INV_ITEM_ATTRIBUTES_PKG'
1778 AND object_type = 'PACKAGE BODY';
1779
1780 IF l_status = 'INVALID' THEN
1781 DBMS_DDL.ALTER_COMPILE('package','apps','INV_ITEM_ATTRIBUTES_PKG');
1782 END IF;
1783
1784 -- open item attribute cursor
1785
1786 IF NOT att_cur%ISOPEN
1787 THEN
1788 OPEN att_cur;
1789 END IF;
1790
1791 FETCH att_cur INTO l_att_tab(l_att_tab.COUNT);
1792
1793 WHILE att_cur%FOUND
1794 LOOP
1795
1796 FETCH att_cur INTO l_att_tab(l_att_tab.COUNT);
1797
1798 END LOOP;
1799
1800 CLOSE att_cur;
1801
1802 IF NOT sel_cur%ISOPEN
1803 THEN
1804 OPEN sel_cur;
1805 END IF;
1806
1807 FETCH sel_cur INTO l_sel_tab(l_sel_tab.COUNT+1);
1808
1812 FETCH sel_cur INTO l_sel_tab(l_sel_tab.COUNT+1);
1809 WHILE sel_cur%FOUND
1810 LOOP
1811
1813
1814 END LOOP;
1815
1816 CLOSE sel_cur;
1817
1818 -- get the max batch size from the profile option;
1819 -- default it to 1000 if the profile option is not defined.
1820 l_max_batch_size := NVL( TO_NUMBER
1821 ( FND_PROFILE.Value('INV_CCEOI_COMMIT_POINT')
1822 )
1823 , 1000
1824 );
1825
1826 IF G_DEBUG = 'Y' THEN
1827 INV_ORGHIERARCHY_PVT.Log
1828 ( INV_ORGHIERARCHY_PVT.G_LOG_STATEMENT
1829 , 'l_max_batch_size: '||TO_CHAR(l_max_batch_size)
1830 );
1831 END IF;
1832
1833 -- get the max number of workers from the profile option;
1834 -- default it to 1 if the profile option is not defined.
1835 l_request_count := NVL( TO_NUMBER
1836 ( FND_PROFILE.Value('INV_MGD_MAX_WORK')
1837 )
1838 , 1
1839 );
1840
1841 IF G_DEBUG = 'Y' THEN
1842 INV_ORGHIERARCHY_PVT.Log
1843 ( INV_ORGHIERARCHY_PVT.G_LOG_STATEMENT
1844 , 'l_request_count: '||TO_CHAR(l_request_count)
1845 );
1846 END IF;
1847
1848 l_batch_size := 0;
1849 l_set_process_id := Get_Set_Process_ID;
1850
1851 -- Get Application database owner schema
1852 l_app_info_status := FND_INSTALLATION.get_app_info
1853 (application_short_name => 'INV'
1854 ,status => l_app_status
1855 ,industry => l_app_industry
1856 ,oracle_schema => l_app_owner_schema
1857 );
1858
1859 -- get the master organization ID
1860
1861 l_current_sel_index := l_sel_tab.FIRST;
1862
1863 l_master_org_id := Get_Master_Org(l_sel_tab(l_current_sel_index).organization_id);
1864
1865 IF l_sel_tab.COUNT > 0 THEN
1866
1867 l_min_index := 1;
1868
1869 IF l_sel_tab.COUNT > l_max_batch_size THEN
1870 l_max_index := l_max_batch_size;
1871 ELSE
1872 l_max_index := l_sel_tab.COUNT;
1873 END IF;
1874
1875 LOOP
1876
1877 -- loop through all the records to be updated
1878
1879 l_current_att_index := 0;
1880
1881 INSERT INTO mtl_system_items_interface
1882 ( process_flag
1883 , set_process_id
1884 , transaction_type
1885 , inventory_item_id
1886 , organization_id
1887 , last_update_date
1888 , last_updated_by
1889 , creation_date
1890 , created_by
1891 , last_update_login
1892 , request_id
1893 , program_application_id
1894 , program_id
1895 , program_update_date
1896 , copy_item_id
1897 , copy_organization_id
1898 )
1899 VALUES
1900 ( 1
1901 , l_set_process_id
1905 , SYSDATE
1902 , 'UPDATE'
1903 , l_sel_tab(l_current_sel_index).item_id
1904 , l_sel_tab(l_current_sel_index).organization_id
1906 , FND_GLOBAL.user_id
1907 , SYSDATE
1908 , FND_GLOBAL.user_id
1909 , FND_GLOBAL.login_id
1910 , FND_GLOBAL.conc_request_id
1911 , FND_GLOBAL.prog_appl_id
1912 , FND_GLOBAL.conc_program_id
1913 , SYSDATE
1914 , l_sel_tab(l_current_sel_index).item_id
1915 , l_master_org_id
1916 );
1917
1918 IF l_current_sel_index >= l_max_index THEN
1919
1920 -- Update the records in the interface table with
1921 -- the values to copy from
1922
1923 SELECT count(*)
1924 INTO l_count
1925 FROM mtl_item_values_temp
1926 WHERE item_update_id = p_seq_id;
1927
1928 LOOP
1929
1930 -- Update the records in the interface table with
1931 -- the values to copy from
1932
1933 EXIT WHEN l_current_att_index = l_count;
1934
1935 -- Establish if the value is to be updated with null
1936
1937 IF l_att_tab(l_current_att_index).chosen_value IS NULL THEN
1938 -- Bug#2445587 fix: Copy item attribute should not copy item status to NULL
1939 -- column inventory_item_status_code not required to be assigned with !
1940 IF l_att_tab(l_current_att_index).item_column_name <> 'INVENTORY_ITEM_STATUS_CODE'
1941 THEN
1942 /***
1943 -- fix for 12.2 OLP compatible
1944
1945 SELECT data_type
1946 INTO l_data_type
1947 FROM all_tab_columns
1948 WHERE table_name = 'MTL_SYSTEM_ITEMS_INTERFACE'
1949 AND owner = l_app_owner_schema
1950 AND column_name = upper(l_att_tab(l_current_att_index).item_column_name);
1951 ***/
1952
1953 -- bug#15842720 fix for 12.2 OLP compatible
1954 SELECT data_type
1955 INTO l_data_type
1956 FROM user_synonyms syn, dba_tab_columns col
1957 WHERE syn.synonym_name = 'MTL_SYSTEM_ITEMS_INTERFACE'
1958 AND col.owner = syn.table_owner
1959 AND col.table_name = syn.table_name
1960 AND col.owner = l_app_owner_schema
1961 AND col.column_name = upper(l_att_tab(l_current_att_index).item_column_name);
1962
1963 IF l_data_type = 'NUMBER' THEN
1964 UPDATE mtl_item_values_temp tmp
1965 SET tmp.chosen_value = '-999999'
1966 WHERE tmp.current_att_index = l_current_att_index
1967 AND tmp.item_update_id = p_seq_id;
1968 ELSIF l_data_type = 'VARCHAR2' THEN
1969 UPDATE mtl_item_values_temp tmp
1970 SET tmp.chosen_value = '!'
1971 WHERE tmp.current_att_index = l_current_att_index
1972 AND tmp.item_update_id = p_seq_id;
1973 END IF;
1974
1975 ELSE
1976
1977 UPDATE mtl_item_values_temp tmp
1978 SET tmp.chosen_value = FND_PROFILE.VALUE('INV_STATUS_DEFAULT')
1979 WHERE tmp.current_att_index = l_current_att_index
1980 AND tmp.item_update_id = p_seq_id;
1981 END IF; -- inventory_item_status_code check
1982
1983 END IF;
1984
1985 /*myerrams, Modified the following query to use bind variables. Bug: 5001785*/
1986 l_dml_str := 'UPDATE mtl_system_items_interface int SET (int.'
1987 || l_att_tab(l_current_att_index).item_column_name
1988 || ') = ('
1989 || ' SELECT tmp.chosen_value'
1990 || ' FROM mtl_item_values_temp tmp '
1991 || ' WHERE tmp.current_att_index = :1'
1992 || ' AND tmp.item_update_id = :2'
1993 || ') WHERE (int.set_process_id = :3'
1994 || ')';
1995 EXECUTE IMMEDIATE l_dml_str
1996 USING l_current_att_index, p_seq_id, l_set_process_id;
1997
1998 IF G_DEBUG = 'Y' THEN
1999 INV_ORGHIERARCHY_PVT.Log
2000 ( INV_ORGHIERARCHY_PVT.G_LOG_STATEMENT
2001 , 'Update Complete'
2002 );
2003 END IF;
2004
2005 l_current_att_index := l_current_att_index + 1;
2006
2007 l_min_index := l_max_index + 1;
2008 IF l_sel_tab.COUNT > (l_max_index + l_max_batch_size) THEN
2009 l_max_index := l_max_index+l_max_batch_size;
2010 ELSE
2011 l_max_index := l_sel_tab.COUNT;
2012 END IF;
2013
2014 END LOOP;
2015
2016 Submit_Item_Update(l_sel_tab(l_current_sel_index).organization_id
2017 ,l_set_process_id
2018 ,l_workers_tbl
2019 ,l_request_count);
2020
2021 IF G_DEBUG = 'Y' THEN
2022 INV_ORGHIERARCHY_PVT.Log
2023 ( INV_ORGHIERARCHY_PVT.G_LOG_STATEMENT
2024 , 'Submit done'
2025 );
2026 END IF;
2027
2028 l_batch_size := 0;
2029 l_set_process_id := Get_Set_Process_ID;
2030 l_current_att_index := 0;
2031
2032 END IF;
2033
2034 EXIT WHEN l_current_sel_index = l_sel_tab.LAST;
2035
2036 l_current_sel_index := l_current_sel_index + 1;
2037
2038 END LOOP;
2039
2040 END IF;
2041
2042 Wait_For_All_Workers(p_workers => l_workers_tbl);
2043
2044 DELETE mtl_item_values_temp
2045 WHERE item_update_id = p_seq_id;
2046
2047 DELETE mtl_update_records_temp
2048 WHERE item_update_id = p_seq_id;
2049
2050 Determine_Return_Code
2051 ( x_retcode => x_retcode
2055 IF G_DEBUG = 'Y' THEN
2052 , x_errbuff => x_errbuff
2053 );
2054
2056 INV_ORGHIERARCHY_PVT.Log
2057 ( INV_ORGHIERARCHY_PVT.G_LOG_PROCEDURE
2058 , '< Batch Item Update'
2059 );
2060 END IF;
2061
2062 EXCEPTION
2063 WHEN g_submit_failure_exc THEN
2064 FND_MESSAGE.Set_Name('INV', 'INV_UNABLE_TO_SUBMIT_CONC');
2065 x_errbuff := SUBSTR(FND_MESSAGE.Get, 1, 255);
2066 x_retcode := RETCODE_ERROR;
2067 WHEN OTHERS THEN
2068 IF FND_MSG_PUB.Check_Msg_Level(FND_MSG_PUB.G_MSG_LVL_UNEXP_ERROR)
2069 THEN
2070 FND_MSG_PUB.Add_Exc_Msg( G_INV_ITEM_ATTRIBUTES_PKG
2071 , 'batch_item_update'
2072 );
2073 x_retcode := RETCODE_ERROR;
2074 x_errbuff := FND_MSG_PUB.Get(p_encoded => FND_API.G_FALSE);
2075 END IF;
2076
2077 END batch_item_update;
2078
2079 --=========================================================================
2080 -- PROCEDURE : populate_temp_tables PUBLIC
2081 -- PARAMETERS :
2082 -- COMMENT : This procedure is called just before
2083 -- the call to the concurrent program
2084 -- which will update the item attributes.
2085 --
2086 -- PRE-COND : This procedure will be called from the form
2087 --=========================================================================
2088 PROCEDURE populate_temp_tables
2089 (p_att_tab IN INV_ITEM_ATTRIBUTES_PKG.att_tbl_type
2090 ,x_seq_id OUT NOCOPY NUMBER
2091 )
2092 IS
2093
2094 --=================
2095 -- LOCAL VARIABLES
2096 --=================
2097
2098 l_seq_id NUMBER;
2099 l_last NUMBER;
2100
2101 BEGIN
2102
2103 g_att_tab := p_att_tab;
2104 g_current_att_index := g_att_tab.FIRST;
2105
2106 l_last := g_count - 1;
2107
2108 -- generate the sequence id which will identify this update
2109 SELECT mtl_update_session_s.NEXTVAL INTO l_seq_id FROM dual;
2110
2111 -- populate the item values temp table with the names and values
2112 -- of the attributes that need to be copied.
2113 -- This information can not be read directly from
2114 -- the MTL_ITEM_ATTRIBUTES_TEMP table as the attributes names
2115 -- have been assigned dynamically. for more please read the dld
2116
2117 LOOP
2118
2119 INSERT INTO mtl_item_values_temp(item_update_id
2120 ,item_column_name
2121 ,chosen_value
2122 ,current_att_index
2123 )
2124 VALUES(l_seq_id
2125 ,g_att_tab(g_current_att_index).item_column_name
2126 ,g_att_tab(g_current_att_index).chosen_value
2127 ,g_current_att_index
2128 );
2129
2130 EXIT WHEN g_current_att_index = l_last;
2131
2132 g_current_att_index := g_att_tab.NEXT(g_current_att_index);
2133
2134 END LOOP;
2135
2136 -- populate the update records table with the organization id and the
2137 -- item id of all the records to be copied to.
2138 -- This information can be read directly from the table
2139 -- mtl_item_attributes_temp.
2140
2141 INSERT into mtl_update_records_temp(
2142 item_update_id
2143 ,inventory_item_id
2144 ,organization_id)
2145 SELECT
2146 l_seq_id
2147 ,mia.item_id
2148 ,mia.organization_id
2149 FROM
2150 mtl_item_attributes_temp mia
2151 WHERE mia.checkbox = 'Y';
2152
2153 -- return the sequence id
2154 x_seq_id := l_seq_id;
2155
2156 EXCEPTION
2157 WHEN OTHERS THEN
2158 IF FND_MSG_PUB.Check_Msg_Level(FND_MSG_PUB.G_MSG_LVL_UNEXP_ERROR)
2159 THEN
2160 FND_MSG_PUB.Add_Exc_Msg( G_INV_ITEM_ATTRIBUTES_PKG
2161 , 'populate_temp_tables'
2162 );
2163 END IF;
2164 RAISE;
2165 END populate_temp_tables;
2166
2167 END INV_ITEM_ATTRIBUTES_PKG;