DBA Data[Home] [Help]

PACKAGE BODY: APPS.MRP_KANBAN_SNAPSHOT_PK

Source


1 PACKAGE BODY MRP_KANBAN_SNAPSHOT_PK AS
2 /* $Header: MRPKSNPB.pls 120.4 2005/12/29 19:11:57 ksuleman noship $  */
3 
4 
5 -- ========================================================================
6 --  This function checks if the from locations (from subinventory and from
7 --  locator ) are null in the mrp_low_level_codes table and populates them
8 -- ========================================================================
9 FUNCTION CHECK_ITEM_LOCATIONS RETURN BOOLEAN IS
10 
11 l_count		number;
12 l_item		varchar2(40);
13 
14 -- declare a cursor for detailed debug information. This will be used
15 -- only if debug is turned on.
16 CURSOR cur_debug is
17 SELECT distinct msi.concatenated_segments
18 FROM   mtl_system_items_kfv msi, mrp_low_level_codes mllc
19 WHERE  mllc.plan_id = mrp_kanban_plan_pk.g_kanban_info_rec.kanban_plan_id
20 AND    mllc.organization_id =
21 		mrp_kanban_plan_pk.g_kanban_info_rec.organization_id
22 AND    mllc.from_subinventory IS NULL
23 AND    mllc.from_locator_id IS NULL
24 AND    mllc.kanban_item_flag = 'Y'
25 AND    mllc.assembly_item_id <> mllc.component_item_id
26 AND    msi.organization_id = mllc.organization_id
27 AND    msi.inventory_item_id = mllc.component_item_id;
28 
29 
30 BEGIN
31 
32   mrp_kanban_plan_pk.g_stmt_num := 120;
33   IF mrp_kanban_plan_pk.g_debug THEN
34     mrp_kanban_plan_pk.g_log_message := 'Debug Statement Number : '
35 				|| to_char (mrp_kanban_plan_pk.g_stmt_num);
36     MRP_UTIL.MRP_LOG (mrp_kanban_plan_pk.g_log_message);
37   mrp_kanban_plan_pk.g_log_message := 'Entering Check_Item_Locations Procedure';
38     MRP_UTIL.MRP_LOG (mrp_kanban_plan_pk.g_log_message);
39   END IF;
40 
41 
42   -- first check if any of the kanban items have null locations
43   SELECT count(*)
44   INTO   l_count
45   FROM   mrp_low_level_codes
46   WHERE  plan_id = mrp_kanban_plan_pk.g_kanban_info_rec.kanban_plan_id
47   AND    organization_id = mrp_kanban_plan_pk.g_kanban_info_rec.organization_id
48   AND    from_subinventory IS NULL
49   AND    from_locator_id IS NULL
50   AND    kanban_item_flag = 'Y'
51   AND    assembly_item_id <> component_item_id;
52 
53 
54 /*  This section will be enabled for R12, We will not have any data in
55 bom_inventory_backflush_subinv for R11
56 
57 
58   -- this is the first thing we do to get the sub and locator information
59   IF l_count > 0 THEN
60 
61     UPDATE mrp_low_level_codes mllc
62     SET    (mllc.from_subinventory, mllc.from_locator_id) =
63     	   (SELECT bibs.SUBINVENTORY_NAME, bibs.LOCATOR_ID
64     	    FROM   bom_inventory_backflush_subinv bibs
65     	    AND    bibs.inventory_item_id = mllc.component_item_id
66     	    AND	   bibs.organization_id = mllc.organization_id
67     	    AND    bibs.location_type = 1)  --  ??
68     WHERE  mllc.plan_id = mrp_kanban_plan_pk.g_kanban_info_rec.kanban_plan_id
69     AND    mllc.organization_id =
70 		mrp_kanban_plan_pk.g_kanban_info_rec.organization_id
71     AND    mllc.from_subinventory IS NULL
72     AND	   mllc.from_locator_id IS NULL
73     AND	   mllc.kanban_item_flag = 'Y'
74     AND	   mllc.assembly_item_id <> mllc.component_item_id;
75 
76   END IF;
77 
78 
79   -- now check again to see if we have any kanban items with null locations
80   SELECT count(*)
81   INTO   l_count
82   FROM   mrp_low_level_codes
83   WHERE  plan_id = mrp_kanban_plan_pk.g_kanban_info_rec.kanban_plan_id
84   AND    organization_id = mrp_kanban_plan_pk.g_kanban_info_rec.organization_id
85   AND    from_subinventory IS NULL
86   AND    from_locator_id IS NULL
87   AND    kanban_item_flag = 'Y'
88   AND    assembly_item_id <> component_item_id;
89 
90 end  of section - enable for R12  */
91 
92   -- if we now still have some records with null sub and locator
93   -- we go after the item master for the information
94 
95   IF l_count > 0 THEN
96 
97     UPDATE mrp_low_level_codes mllc
98     SET    (mllc.from_subinventory, mllc.from_locator_id) =
99     	   (SELECT msi.wip_supply_subinventory,
100   	   	   msi.wip_supply_locator_id
101     	    FROM   mtl_system_items msi
102             WHERE  msi.organization_id = mllc.organization_id
103     	    AND	   msi.inventory_item_id = mllc.component_item_id)
104     WHERE  mllc.plan_id =
105 		mrp_kanban_plan_pk.g_kanban_info_rec.kanban_plan_id
106     AND    mllc.organization_id =
107                 mrp_kanban_plan_pk.g_kanban_info_rec.organization_id
108     AND    mllc.from_subinventory IS NULL
109     AND    mllc.from_locator_id IS NULL
110     AND    mllc.kanban_item_flag = 'Y'
111     AND    mllc.assembly_item_id <> mllc.component_item_id;
112 
113   END IF;
114 
115   -- now check again if we have any kanban items with incomplete from
116   -- location information.  If so error out
117   SELECT count(*)
118   INTO   l_count
119   FROM   mrp_low_level_codes
120   WHERE  plan_id = mrp_kanban_plan_pk.g_kanban_info_rec.kanban_plan_id
121   AND    organization_id = mrp_kanban_plan_pk.g_kanban_info_rec.organization_id
122   AND    from_subinventory IS NULL
123   AND    from_locator_id IS NULL
124   AND    kanban_item_flag = 'Y'
125   AND    assembly_item_id <> component_item_id;
126 
127   IF l_count > 0 THEN
128   IF mrp_kanban_plan_pk.g_debug THEN
129     mrp_kanban_plan_pk.g_log_message := 'End of CHECK_ITEM_LOCATIONS function';
130     MRP_UTIL.MRP_LOG (mrp_kanban_plan_pk.g_log_message);
131   END IF;
132 
133     l_count := 0;
134     OPEN cur_debug;
135 
136     WHILE TRUE LOOP
137 
138       FETCH cur_debug INTO l_item;
139 
140       EXIT WHEN cur_debug%NOTFOUND;
141 
142   IF mrp_kanban_plan_pk.g_debug THEN
143       FND_MESSAGE.SET_NAME ('MRP','MRP_KANBAN_ITEM_INCOMP_LOC');
144       FND_MESSAGE.SET_TOKEN ('ITEMNAME', l_item);
145       mrp_kanban_plan_pk.g_log_message := FND_MESSAGE.GET;
146       MRP_UTIL.MRP_LOG (mrp_kanban_plan_pk.g_log_message);
147   END IF;
148 
149       l_count := l_count + 1;
150 
151     END LOOP;
152 
153   IF mrp_kanban_plan_pk.g_debug THEN
154     FND_MESSAGE.SET_NAME ('MRP','MRP_KANBAN_INCOMP_LOC');
155     FND_MESSAGE.SET_TOKEN ('NUMITEMS', to_char(l_count));
156     mrp_kanban_plan_pk.g_log_message := FND_MESSAGE.GET;
157     MRP_UTIL.MRP_LOG (mrp_kanban_plan_pk.g_log_message);
158   END IF;
159 
160     --set the flag to return warning here
161     MRP_KANBAN_PLAN_PK.g_raise_warning := TRUE;
162 
163   END IF;
164 
165   RETURN TRUE;
166 
167 --Exception handling
168 EXCEPTION
169 
170   WHEN OTHERS THEN
171     mrp_kanban_plan_pk.g_log_message := 'CHECK_ITEM_LOCATIONS Sql Error ';
172     MRP_UTIL.MRP_LOG (mrp_kanban_plan_pk.g_log_message);
173     mrp_kanban_plan_pk.g_log_message := sqlerrm;
174     MRP_UTIL.MRP_LOG (mrp_kanban_plan_pk.g_log_message);
175     RETURN FALSE;
176 
177 END CHECK_ITEM_LOCATIONS;
178 
179 -- ========================================================================
180 --  This function checks for presence of loops in the bill structure
181 --  build in the mrp_low_level_codes table and errors out if we find one
182 -- ========================================================================
183 FUNCTION CHECK_FOR_LOOPS RETURN BOOLEAN IS
184 
185 l_count			number;
186 exc_loop_error		exception;
187 l_loop_found		boolean := FALSE;
188 l_logged_loop_err_msg	boolean := FALSE;
189 
190 l_assembly_item_id	number;
191 l_to_subinventory	varchar2(10);
192 l_to_locator_id		number;
193 l_component_item_id	number;
194 l_from_subinventory	varchar2(10);
195 l_from_locator_id	number;
196 l_parent_item		varchar2(40);
197 l_child_item		varchar2(40);
198 l_parent_loc		number;
199 l_child_loc		number;
200 
201 CURSOR cur_loop_check IS
202 SELECT 	parent.concatenated_segments assembly_item,
203 	mllc.to_subinventory,
204 	parent_loc.inventory_location_id to_location,
205 	child.concatenated_segments component_item,
206 	mllc.from_subinventory,
207 	child_loc.inventory_location_id from_location
208 FROM
209       	mtl_item_locations parent_loc,
210       	mtl_item_locations child_loc,
211       	mtl_system_items_kfv parent,
212 	mtl_system_items_kfv child,
213 	mrp_low_level_codes mllc
214 WHERE   mllc.plan_id = mrp_kanban_plan_pk.g_kanban_info_rec.kanban_plan_id
215 AND     mllc.organization_id =
216 			mrp_kanban_plan_pk.g_kanban_info_rec.organization_id
217 AND     mllc.low_level_code IS NULL
218 AND     parent.inventory_item_id = mllc.assembly_item_id
219 AND     parent.organization_id = mllc.organization_id
220 AND     child.inventory_item_id = mllc.component_item_id
221 AND     child.organization_id = mllc.organization_id
222 AND     parent_loc.inventory_location_id (+)  = mllc.to_locator_id
223 AND     parent_loc.organization_id (+)  = mllc.organization_id
224 AND     child_loc.inventory_location_id (+)  = mllc.from_locator_id
225 AND     child_loc.organization_id (+)  = mllc.organization_id
226 ORDER BY
227 	assembly_item,
228 	component_item;
229 
230 BEGIN
231 
232   IF mrp_kanban_plan_pk.g_debug THEN
233     mrp_kanban_plan_pk.g_log_message := 'In Check_For_Loops Procedure';
234     fnd_file.put_line (fnd_file.log, mrp_kanban_plan_pk.g_log_message);
235   END IF;
236 
237   -- We just go and check if we have assigned a low level code value
238   -- to every entry for the current plan.  If we have at least one
239   -- record without a low level code, this indicates the presence of
240   -- a loop and we error out
241 
242   l_logged_loop_err_msg := FALSE; -- flag to help us log the loop check
243 				  -- error message only once in the log file
244 
245   OPEN cur_loop_check;
246 
247   WHILE TRUE LOOP
248     FETCH cur_loop_check
249     INTO  l_parent_item,
250 	  l_to_subinventory,
251 	  l_parent_loc,
252 	  l_child_item,
253 	  l_from_subinventory,
254 	  l_child_loc;
255 
256     EXIT WHEN cur_loop_check%NOTFOUND;
257 
258     l_loop_found := TRUE;
259 
260     IF not l_logged_loop_err_msg THEN
261     IF mrp_kanban_plan_pk.g_debug THEN
262       FND_MESSAGE.SET_NAME ('MRP','MRP_KANBAN_LOOP_ERROR');
263       mrp_kanban_plan_pk.g_log_message := FND_MESSAGE.GET;
264       MRP_UTIL.MRP_LOG (mrp_kanban_plan_pk.g_log_message);
265 
266       FND_MESSAGE.SET_NAME ('MRP','MRP_KANBAN_LOOP_INFO_START');
267       mrp_kanban_plan_pk.g_log_message := FND_MESSAGE.GET;
268       MRP_UTIL.MRP_LOG (mrp_kanban_plan_pk.g_log_message);
269     END IF;
270 
271       l_logged_loop_err_msg := TRUE;
272 
273     END IF;
274 
275     -- now go ahead and log messages giving details of the loop found
276 
277   IF mrp_kanban_plan_pk.g_debug THEN
278     FND_MESSAGE.SET_NAME ('MRP','MRP_KANBAN_LOOP_INFO');
279     FND_MESSAGE.SET_TOKEN ('PARENT_ITEM', l_parent_item);
280     FND_MESSAGE.SET_TOKEN ('PARENT_SUB', l_to_subinventory);
281     FND_MESSAGE.SET_TOKEN ('PARENT_LOC', to_char(l_parent_loc));
282     FND_MESSAGE.SET_TOKEN ('CHILD_ITEM', l_child_item);
283     FND_MESSAGE.SET_TOKEN ('CHILD_SUB', l_from_subinventory);
284     FND_MESSAGE.SET_TOKEN ('CHILD_LOC', to_char(l_child_loc));
285     mrp_kanban_plan_pk.g_log_message := FND_MESSAGE.GET;
286     MRP_UTIL.MRP_LOG (mrp_kanban_plan_pk.g_log_message);
287   END IF;
288 
289   END LOOP;
290 
291   CLOSE cur_loop_check;
292 
293   IF l_loop_found THEN
294 
295   IF mrp_kanban_plan_pk.g_debug THEN
296     FND_MESSAGE.SET_NAME ('MRP','MRP_KANBAN_LOOP_INFO_END');
297     mrp_kanban_plan_pk.g_log_message := FND_MESSAGE.GET;
298     MRP_UTIL.MRP_LOG (mrp_kanban_plan_pk.g_log_message);
299   END IF;
300 
301     raise exc_loop_error;
302   END IF;
303 
304   RETURN TRUE;
305 
306 EXCEPTION
307   WHEN exc_loop_error THEN
308     RETURN FALSE;
309 
310   WHEN OTHERS THEN
311     mrp_kanban_plan_pk.g_log_message := 'CHECK_FOR_LOOPS Sql Error ';
312     MRP_UTIL.MRP_LOG (mrp_kanban_plan_pk.g_log_message);
313     mrp_kanban_plan_pk.g_log_message := sqlerrm;
314     MRP_UTIL.MRP_LOG (mrp_kanban_plan_pk.g_log_message);
315     RETURN FALSE;
316 
317 
318 END CHECK_FOR_LOOPS;
319 
320 -- ========================================================================
321 --  location combinations in mrp_low_level_codes table
322 -- ========================================================================
323 
324 FUNCTION CALC_LOW_LEVEL_CODE RETURN BOOLEAN
325 IS
326 
327 l_low_level_code  	number;
328 
329 BEGIN
330 
331   IF mrp_kanban_plan_pk.g_debug THEN
332     mrp_kanban_plan_pk.g_log_message := 'In Calc_Low_Level_Codes Procedure';
333     fnd_file.put_line (fnd_file.log, mrp_kanban_plan_pk.g_log_message);
334   END IF;
335 
336   -- start calculating the low level codes
337   -- we start by assigning a low_level_code of 1000 to the lowest level
338   -- item/location combinations in the bill structure and then go up the
339   -- bill structure in a loop.
340   -- Note that the item for which low level code is being assigned is
341   -- the component_item_id NOT the assembly_item_id
342 
343   l_low_level_code := 1000;  /* initialize */
344 
345   WHILE TRUE LOOP
346 
347     UPDATE mrp_low_level_codes mllc1
348     SET	mllc1.low_level_code = l_low_level_code
349     WHERE mllc1.plan_id = mrp_kanban_plan_pk.g_kanban_info_rec.kanban_plan_id
350     AND   mllc1.organization_id =
351 		mrp_kanban_plan_pk.g_kanban_info_rec.organization_id
352     AND   mllc1.low_level_code IS NULL
353     AND  	NOT EXISTS
354 	(SELECT /*+index(mllc2 MRP_LOW_LEVEL_CODES_N1)*/ 'Exists as parent' /* Bug 4608294 - added hint*/
355 	 FROM	mrp_low_level_codes mllc2
356 	 WHERE 		mllc2.plan_id = mllc1.plan_id
357          AND		mllc2.organization_id = mllc1.organization_id
358          AND		mllc2.low_level_code IS NULL
359          AND		( mllc2.assembly_item_id = mllc1.component_item_id AND
360             		 ((((mllc2.to_subinventory = mllc1.from_subinventory AND
361 	 		   nvl(mllc2.to_locator_id,-1) =
362 					nvl(mllc1.from_locator_id, -1) ) OR
363 			   mllc2.to_subinventory is NULL  ) AND
364 			   nvl(mllc1.kanban_item_flag,'N') = 'Y') OR
365 			   nvl(mllc1.kanban_item_flag,'N') = 'N'))
366 
367 	);
368 
369     EXIT WHEN SQL%ROWCOUNT = 0;
370 
371     l_low_level_code := l_low_level_code - 1;
372 
373   END LOOP;  /* end while loop */
374 
375   RETURN TRUE;
376 
377 -- exception handling
378 EXCEPTION
379   WHEN OTHERS THEN
380     mrp_kanban_plan_pk.g_log_message := 'CALC_LOW_LEVEL_CODE Sql Error ';
381     MRP_UTIL.MRP_LOG (mrp_kanban_plan_pk.g_log_message);
382     mrp_kanban_plan_pk.g_log_message := sqlerrm;
383     MRP_UTIL.MRP_LOG (mrp_kanban_plan_pk.g_log_message);
384     RETURN FALSE;
385 
386 END CALC_LOW_LEVEL_CODE;
387 
388 -- ========================================================================
389 --  This function builds the where clause for the item range specified
390 --  The where clause is used in the first select statement while
391 --  snapshotting kanban items
392 -- ========================================================================
393 FUNCTION Item_Where_Clause( p_item_lo 		IN 	VARCHAR2,
394                              p_item_hi 		IN 	VARCHAR2,
395                              p_table_name 	IN 	VARCHAR2,
396                              p_where   		OUT 	NOCOPY	VARCHAR2 )
397 RETURN BOOLEAN IS
398 
399    /* This function is obsoleted since we now use the same-named function in
400       package 'flm_util', where we use bind variables. */
401 
402 BEGIN
403 
404   RETURN TRUE;
405 
406 --exception handling
407 EXCEPTION
408   WHEN OTHERS THEN
409     RETURN FALSE;
410 
411 END Item_Where_Clause;
412 
413 
414 -- ========================================================================
415 --  This function builds the where clause for the category range specified
416 --  The where clause is used in the first select statement while
417 --  snapshotting kanban items
418 -- ========================================================================
419 FUNCTION Category_Where_Clause (  p_cat_lo 	IN 	VARCHAR2,
420                              	  p_cat_hi 	IN 	VARCHAR2,
421                              	  p_table_name 	IN 	VARCHAR2,
422                              	  p_where   	OUT 	NOCOPY	VARCHAR2 )
423 RETURN BOOLEAN IS
424 
425    /* This function is obsoleted since we now use the same-named function in
426       package 'flm_util', where we use bind variables. */
427 
428 BEGIN
429 
430   RETURN TRUE;
431 
432 --exception handling
433 EXCEPTION
434   WHEN OTHERS THEN
435     RETURN FALSE;
436 
437 END Category_Where_Clause;
438 
439 -- ========================================================================
440 --  This function returns 1 if the alternate designator passed corresponds
441 --  to the alternate_routing_designator with the highest priority, else
442 --  it returns -1
443 -- ========================================================================
444 FUNCTION Check_Min_Priority
445 ( p_assembly_item_id            IN NUMBER,
446   p_organization_id             IN NUMBER,
447   p_line_id                     IN NUMBER,
448   p_alternate_designator        IN VARCHAR2)
449 RETURN NUMBER IS
450 
451 l_dummy          		VARCHAR2(30);
452 l_highest_priority              NUMBER := NULL;
453 l_num_routings			NUMBER := 0;
454 
455 BEGIN
456 
457   IF p_assembly_item_id IS NULL OR p_organization_id IS NULL
458                 OR p_line_id IS NULL THEN
459     IF p_alternate_designator IS NULL THEN
460       RETURN 1;
461     ELSE
462       RETURN -1;
463     END IF;
464   END IF;
465 
466   -- ---------------------------------------------------
467   -- Find the number of routings for this given line
468   -- Also find the highest priority among the routings
469   -- ---------------------------------------------------
470   SELECT min(bor.priority), count(*)
471   INTO   l_highest_priority, l_num_routings
472   FROM   bom_operational_routings bor
473   WHERE  bor.organization_id = p_organization_id
474   AND    bor.assembly_item_id = p_assembly_item_id
475   AND    bor.cfm_routing_flag = 1
476   AND    bor.line_id  = p_line_id;
477 
478   -- ---------------------------------------------------
479   -- If there no routings for this given line
480   -- we return true if p_alternate_designator is the primary
481   -- routing designator (ie IS NULL)
482   -- ---------------------------------------------------
483   IF l_num_routings = 0 THEN
484     IF p_alternate_designator IS NULL THEN
485       RETURN 1;
486     ELSE
487       RETURN -1;
488     END IF;
489   END IF;
490 
491   -- ---------------------------------------------------
492   -- IF there are multiple routings for this given line
493   -- all of which has NULL for the priority, we return
494   -- false
495   -- ---------------------------------------------------
496   IF ((l_highest_priority IS NULL) AND (l_num_routings > 1) AND (p_alternate_designator IS NOT NULL) ) THEN
497     RETURN -1;
498   END IF;
499 
500 
501   SELECT 'Condition Satisfied'
502   INTO   l_dummy
503   FROM   bom_operational_routings bor
504   WHERE  bor.organization_id  = p_organization_id
505   AND    bor.assembly_item_id  = p_assembly_item_id
506   AND    bor.line_id  = p_line_id
507   AND    bor.cfm_routing_flag  = 1
508   AND    NVL(bor.priority,-1) = NVL(l_highest_priority,-1)
509   AND    NVL(bor.alternate_routing_designator,'xx') =
510              NVL(p_alternate_designator, 'xx');
511 
512   RETURN 1;
513 
514 Exception
515   WHEN NO_DATA_FOUND THEN
516     RETURN -1;
517 
518   WHEN OTHERS THEN
519     RETURN -1;
520 
521 END Check_Min_Priority;
522 
523 FUNCTION Check_assy_cfgitem
524   (p_assembly_item_id           IN NUMBER,
525    p_comp_item_id               IN NUMBER,
526    p_organization_id            IN NUMBER)
527 RETURN NUMBER IS
528 
529 /* Declare cursor for assembly item to check whether it is a configured item */
530 
531 CURSOR config_item_flag(p_assemply_item_id IN NUMBER,
532                         p_organization_id IN NUMBER) IS
533 
534 SELECT msi.base_item_id,msi.bom_item_type
535 FROM   mtl_system_items msi
536 WHERE  msi.inventory_item_id = p_assembly_item_id
537 AND    msi.organization_id = p_organization_id;
538 
539 config_item_flag_rec config_item_flag%ROWTYPE;
540 
541 /* Declare cursor to determine if the component is a Model or an Option class */
542 
543 CURSOR comp_type(p_comp_item_id IN NUMBER,
544                  p_organization_id IN NUMBER) IS
545 
546 SELECT msi.bom_item_type
547 FROM   mtl_system_items msi
548 WHERE  msi.inventory_item_id = p_comp_item_id
549 AND    msi.organization_id = p_organization_id;
550 
551 comp_type_rec comp_type%ROWTYPE;
552 
553 
554 BEGIN
555 
556 
557    OPEN config_item_flag(p_assembly_item_id,
558                          p_organization_id);
559    FETCH config_item_flag into config_item_flag_rec;
560 
561 -- If the assembly item is not a configured item, return 1
562 
563    IF (config_item_flag_rec.base_item_id IS NULL) THEN
564       RETURN 1;
565    ELSE
566       OPEN comp_type(p_comp_item_id ,
567                      p_organization_id );
568       FETCH comp_type into comp_type_rec;
569 
570      -- If assembly is a configured item and the component is Model or Option class,
571      --   do not create demand for the item
572 
573       IF(comp_type_rec.bom_item_type IN (1,2)) THEN
574          RETURN -1;
575       ELSE
576          RETURN 1;
577       END IF;
578    END IF;
579 
580 EXCEPTION
581    WHEN OTHERS THEN
582      RETURN -1;
583 
584 END check_assy_cfgitem;
585 
586 -- ========================================================================
587 --
588 --  This procedure will identify the list of items that need to be included
589 --  in the current kanban plan run.  User can limit thelist of items by
590 --  specifying an item range or item categroy.  It will select the bill
591 --  structure of these items and insert them into the table mrp_kanban_ll_code.
592 --
593 -- ========================================================================
594 FUNCTION SNAPSHOT_ITEM_LOCATIONS RETURN BOOLEAN IS
595 
596 l_level_count 		number;
597 l_sql_stmt		varchar2(5000):= NULL;
598 l_item_where_clause  	varchar2(750) := NULL;
599 l_cat_where_clause 	varchar2(750) := NULL;
600 l_additional_tables     varchar2(150) := NULL;
601 l_additional_where	varchar2(2000):= NULL;
602 l_cursor		integer;
603 l_rows_processed 	integer;
604 l_quote             	varchar2(1) := '''';
605 l_ret_val		boolean;
606 l_eco_profile	boolean := TRUE;
607 l_error_buf       varchar2(2000);
608 
609 BEGIN
610 
611   mrp_kanban_plan_pk.g_stmt_num := 30;
612   IF mrp_kanban_plan_pk.g_debug THEN
613     mrp_kanban_plan_pk.g_log_message := 'Debug Statement Number : '
614 				|| to_char (mrp_kanban_plan_pk.g_stmt_num);
615     MRP_UTIL.MRP_LOG (mrp_kanban_plan_pk.g_log_message);
616     mrp_kanban_plan_pk.g_log_message :=
617 		'Entering Snapshot_Item_Locations function';
618     MRP_UTIL.MRP_LOG (mrp_kanban_plan_pk.g_log_message);
619   END IF;
620 
621 
622   l_eco_profile :=  FND_PROFILE.VALUE('FLM_KANBAN_ECO') = 'Y';
623 
624   if (l_eco_profile is null)
625   then
626      l_eco_profile := TRUE ;
627   end if ;
628 
629   -- ------------------------------------------------------------------------
630   -- if we are not replanning, then go ahead and get the initial set of items
631   -- based on the parameters passed to the concurrent program
632   -- ------------------------------------------------------------------------
633 
634   IF nvl(mrp_kanban_plan_pk.g_kanban_info_rec.replan_flag, 2 ) = 2 THEN
635 
636     -- now lets go ahead and build our dynamic sql statement based on
637     -- the item/category range and category set parameter values
638 
639      flm_util.init_bind;
640 
641     -- include category set in the sql stmt
642     l_additional_tables := ' mtl_item_categories mic, ';
643     l_additional_where :=
644     ' AND mic.category_set_id (+) = :b_category_set_id' ||
645     ' AND mic.inventory_item_id (+) = msi.inventory_item_id' ||
646     ' AND mic.organization_id (+) = msi.organization_id ';
647 
648     -- now check if item range has been specified and add the extra condition
649     -- if necessary
650 
651     mrp_kanban_plan_pk.g_stmt_num := 40;
652     IF mrp_kanban_plan_pk.g_debug THEN
653       mrp_kanban_plan_pk.g_log_message := 'Debug Statement Number : '
654 				|| to_char (mrp_kanban_plan_pk.g_stmt_num);
655       MRP_UTIL.MRP_LOG (mrp_kanban_plan_pk.g_log_message);
656     END IF;
657 
658     IF mrp_kanban_plan_pk.g_kanban_info_rec.from_item IS NOT NULL OR
659        mrp_kanban_plan_pk.g_kanban_info_rec.to_item IS NOT NULL THEN
660 
661       -- call the function that builds the item where clause
662       l_ret_val := flm_util.Item_Where_Clause(
663 			mrp_kanban_plan_pk.g_kanban_info_rec.from_item,
664 		      	mrp_kanban_plan_pk.g_kanban_info_rec.to_item,
665 		      	'msi',
666 			l_item_where_clause,
667 			l_error_buf);
668 
669       IF NOT l_ret_val THEN
670         RETURN FALSE;
671       END IF;
672 
673       IF l_item_where_clause IS NOT NULL THEN
674         l_additional_where := ' AND ' || l_item_where_clause ||
675 						l_additional_where;
676 
677         IF mrp_kanban_plan_pk.g_debug THEN
678           mrp_kanban_plan_pk.g_log_message := 'Item Where Clause is : ';
679           MRP_UTIL.MRP_LOG (mrp_kanban_plan_pk.g_log_message);
680          mrp_kanban_plan_pk.g_log_message := substr(l_item_where_clause,1,2000);
681           MRP_UTIL.MRP_LOG (mrp_kanban_plan_pk.g_log_message);
682         END IF;
683       END IF;
684 
685     END IF;
686 
687     -- similarly check if category range has been specified and add the extra
688     -- condition if necessary
689 
690     mrp_kanban_plan_pk.g_stmt_num := 50;
691     IF mrp_kanban_plan_pk.g_debug THEN
692       mrp_kanban_plan_pk.g_log_message := 'Debug Statement Number : '
693 				|| to_char (mrp_kanban_plan_pk.g_stmt_num);
694       MRP_UTIL.MRP_LOG (mrp_kanban_plan_pk.g_log_message);
695     END IF;
696 
697     IF (mrp_kanban_plan_pk.g_kanban_info_rec.from_category IS NOT NULL OR
698        mrp_kanban_plan_pk.g_kanban_info_rec.to_category IS NOT NULL) AND
699        mrp_kanban_plan_pk.g_kanban_info_rec.category_set_id IS NOT NULL THEN
700 
701       l_ret_val := flm_util.Category_Where_Clause(
702 			mrp_kanban_plan_pk.g_kanban_info_rec.from_category,
703 		        mrp_kanban_plan_pk.g_kanban_info_rec.to_category,
704 			'mcat',
705 			mrp_kanban_plan_pk.g_kanban_info_rec.category_structure_id,
706 			l_cat_where_clause,
707 			l_error_buf);
708 
709       IF NOT l_ret_val THEN
710         RETURN FALSE;
711       END IF;
712 
713       IF l_cat_where_clause IS NOT NULL THEN
714         l_additional_tables := 'mtl_categories mcat, ' || l_additional_tables;
715         l_additional_where := l_additional_where || ' AND ' ||
716 			    ' mcat.category_id = mic.category_id AND ' ||
717 			    l_cat_where_clause||' ';
718         IF mrp_kanban_plan_pk.g_debug THEN
719           mrp_kanban_plan_pk.g_log_message := 'Category Where Clause is : ';
720           MRP_UTIL.MRP_LOG (mrp_kanban_plan_pk.g_log_message);
721           mrp_kanban_plan_pk.g_log_message := substr(l_cat_where_clause,1,2000);
722           MRP_UTIL.MRP_LOG (mrp_kanban_plan_pk.g_log_message);
723         END IF;
724       END IF;
725 
726     END IF;
727 
728     -- now here goes the 'cool' sql statement that gets all the kanban planned
729     -- items based on our constraints specified above and inserts into
730     -- mrp_low_codes table
731 
732     -- Probably this sql statement needs a little explanation.  We are driving
733     -- off of mrp_kanban_plans table where we get the organization id in which
734     -- this plan is defined, then we hit mtl_system_items table to get the
735     -- list of kanban items (here if category set or item/category range is
736     -- is specified, then we impose extra where conditions and join a couple
737     -- of more tables as seen in the sql statement we just built). As we get
738     -- the inventory item id from mtl_system_items , we also get location
739     -- information for this item by joining to bom_inventory_components.  We
740     -- are not satisfied with that.  So we join bom_bill_of_materials
741     -- to get the assembly_item_id and its location information which is
742     -- (if its a kanban item) stored (hopefully) in mtl_kanban_pull_sequences
743     -- table.  The catch here is that for a production kind of source type in
744     -- in the replenishment chain we specify a line for the source.  We want
745     -- this to be the line that's specified in the CFM routing with priority = 1
746     -- so we end up joining bom_operational_routings table also.
747 
748     mrp_kanban_plan_pk.g_stmt_num := 60;
749     IF mrp_kanban_plan_pk.g_debug THEN
750       mrp_kanban_plan_pk.g_log_message := 'Debug Statement Number : '
751 				|| to_char (mrp_kanban_plan_pk.g_stmt_num);
752       MRP_UTIL.MRP_LOG (mrp_kanban_plan_pk.g_log_message);
753     END IF;
754 
755     l_sql_stmt :=
756     'INSERT INTO mrp_low_level_codes ( ' ||
757     'plan_id,' ||
758     'organization_id,' ||
759     'assembly_item_id,' ||
760     'to_subinventory,' ||
761     'to_locator_id,' ||
762     'component_item_id,' ||
763     'from_subinventory,' ||
764     'from_locator_id,' ||
765     'component_usage,' ||
766     'component_yield,' ||
767 /* Updated by Liye Ma  4/30/2001
768    Add two more columns, to fix bug 1745046 and 1757798. */
769     'planning_factor,' ||
770     'item_num,' ||
771 /* End of update */
772 /*  Modified for lot based material support. Adding query of basis_type and wip_supply_type */
773     'basis_type,' ||
774     'wip_supply_type,' ||
775     'alternate_designator,' ||
776     'kanban_item_flag,' ||
777     'component_category_id,' ||
778     'levels_below,' ||
779     'request_id,' ||
780     'program_application_id,' ||
781     'program_id,' ||
782     'program_update_date,' ||
783     'last_updated_by,' ||
784     'last_update_date,' ||
785     'created_by,' ||
786     'creation_date )' ||
787     'SELECT  /*+ ordered */' ||
788     'mkp.kanban_plan_id,' ||
789     'mkp.organization_id,' ||
790     'bbom.assembly_item_id,' ||
791     'ps.subinventory_name,' ||
792     'ps.locator_id,' ||
793     'msi.inventory_item_id,' ||
794     'mrp_bic.supply_subinventory,' ||
795     'mrp_bic.supply_locator_id,' ||
796     'mrp_bic.component_quantity,' ||
797     'mrp_bic.component_yield_factor,' ||
798 /* Updated by Liye Ma  4/30/2001
799    Add two more columns, to fix bug 1745046 and 1757798. */
800     'mrp_bic.planning_factor,' ||
801     'mrp_bic.item_num,' ||
802 /* End of Update */
803 /*  Modified for lot based material support. Adding query of basis_type and wip_supply_type */
804 /*  Basis type of 1 = WIP_CONSTANTS.ITEM_BASED_MTL */
805     'nvl(mrp_bic.basis_type,1),' ||
806 /*  Supply type of 1 = WIP_CONSTANTS.PUSH */
807     'nvl(mrp_bic.wip_supply_type,1),' ||
808     'bbom.alternate_bom_designator,' ||
809     l_quote || 'Y' || l_quote || ',' ||
810     'mic.category_id,' ||
811     '1,' ||
812     'fnd_global.conc_request_id,' ||
813     'fnd_global.prog_appl_id,' ||
814     'fnd_global.conc_program_id,' ||
815     'sysdate,' ||
816     'fnd_global.user_id,' ||
817     'sysdate,' ||
818     'fnd_global.user_id,' ||
819     'sysdate ' ||
820     'FROM ' ||
821     'mrp_kanban_plans mkp, ' ||
822     'mtl_system_items msi, ' ||
823     '( SELECT /*+ no_merge */  distinct inventory_item_id ,organization_id ' ||
824     '  FROM mtl_kanban_pull_sequences ' ||
825     '  WHERE kanban_plan_id = :b_PRODUCTION_KANBAN ) iv, ' ||
826     'bom_inventory_components mrp_bic, ' ||
827     'bom_bill_of_materials bbom, ' ||
828     'mtl_kanban_pull_sequences ps, ' ||
829     l_additional_tables ||
830     'mtl_system_items msi2 ' ||
831     'WHERE mkp.kanban_plan_id = :b_kanban_plan_id ' ||
832     'AND mkp.organization_id = :b_organization_id ' ||
833     'AND msi.organization_id = mkp.organization_id ' ||
834     'AND iv.inventory_item_id= msi.inventory_item_id ' ||
835     'AND iv.organization_id = msi.organization_id ' ||
836     l_additional_where ||
837     'AND mrp_bic.component_item_id = msi.inventory_item_id ' ||
838     'AND nvl(mrp_bic.disable_date,:b_bom_effectivity) + 1 >= :b_bom_effectivity ' ||
839     'AND mrp_bic.effectivity_date <= :b_bom_effectivity ';
840 
841 	if (l_eco_profile = TRUE)
842 	then
843 		l_sql_stmt := l_sql_stmt ||
844 			'AND NOT EXISTS ( ' ||
845 			'SELECT /*+ INDEX(bic2 BOM_INVENTORY_COMPONENTS_N1) */ '||
846 			'NULL ' ||
847 			'FROM bom_inventory_components bic2 ' ||
848 			'WHERE  bic2.bill_sequence_id = mrp_bic.bill_sequence_id ' ||
849 			'AND    bic2.component_item_id = mrp_bic.component_item_id ' ||
850 			'AND    (decode(bic2.implementation_date, null, ' ||
851 			'bic2.old_component_sequence_id, ' ||
852 			'bic2.component_sequence_id) = ' ||
853 			'decode(mrp_bic.implementation_date, null, ' ||
854 			'mrp_bic.old_component_sequence_id, ' ||
855 			'mrp_bic.component_sequence_id) ' ||
856 			'OR bic2.operation_seq_num = mrp_bic.operation_seq_num) ' ||
857 			'AND    bic2.effectivity_date <= :b_bom_effectivity ' ||
858 			'AND    bic2.effectivity_date > mrp_bic.effectivity_date ' ||
859 			'AND    (bic2.implementation_date is not null OR ' ||
860 			'(bic2.implementation_date is null AND EXISTS ' ||
861 			'(SELECT NULL ' ||
862 			'FROM   eng_revised_items eri ' ||
863 			'WHERE  bic2.revised_item_sequence_id = ' ||
864 			'eri.revised_item_sequence_id ' ||
865 			'AND    eri.mrp_active = 1 )))) ' ||
866 			'AND   (mrp_bic.implementation_date is not null OR ' ||
867 			'(mrp_bic.implementation_date is null AND EXISTS ' ||
868 			'(SELECT NULL ' ||
869 			'FROM   eng_revised_items eri ' ||
870 			'WHERE  mrp_bic.revised_item_sequence_id = ' ||
871 			'eri.revised_item_sequence_id '  ||
872 			'AND eri.mrp_active = 1 ))) ';
873 	end if;
874 	l_sql_stmt := l_sql_stmt ||
875     'AND bbom.organization_id = msi.organization_id ' ||
876     'AND bbom.common_bill_sequence_id = mrp_bic.bill_sequence_id ' ||
877     'AND ps.kanban_plan_id (+) = :b_PRODUCTION_KANBAN ' ||
878     'AND ps.organization_id (+) = bbom.organization_id ' ||
879     'AND ps.inventory_item_id (+) = bbom.assembly_item_id ' ||
880     'AND msi2.inventory_item_id = bbom.assembly_item_id ' ||
881     'AND msi2.organization_id = bbom.organization_id ' ||
882     'AND msi2.planning_make_buy_code = 1 ' ||
883     'AND ps.source_type (+) = :b_PRODUCTION_SOURCE_TYPE ';
884 /* Updated by Liye Ma. 1/23/2001
885    This check_min_priority serves no purposes...
886    ||
887     'AND 1 =  MRP_KANBAN_SNAPSHOT_PK.Check_Min_Priority ( ' ||
888     				'ps.inventory_item_id, ' ||
889     				'ps.organization_id, ' ||
890     				'ps.wip_line_id, ' ||
891     				'bbom.alternate_bom_designator ) '; */
892 
893     -- get a cursor handle
894     l_cursor := dbms_sql.open_cursor;
895 
896     -- parse the sql statement that we just built
897     dbms_sql.parse (l_cursor, l_sql_stmt, dbms_sql.native);
898 
899     -- put values into all the bind variables
900     flm_util.add_bind (':b_kanban_plan_id',
901   			mrp_kanban_plan_pk.g_kanban_info_rec.kanban_plan_id);
902     flm_util.add_bind (':b_organization_id',
903   			mrp_kanban_plan_pk.g_kanban_info_rec.organization_id);
904     flm_util.add_bind (':b_bom_effectivity',
905   			mrp_kanban_plan_pk.g_kanban_info_rec.bom_effectivity);
906     flm_util.add_bind (':b_PRODUCTION_KANBAN',
907   			mrp_kanban_plan_pk.G_PRODUCTION_KANBAN);
908     flm_util.add_bind (':b_PRODUCTION_SOURCE_TYPE',
909   			mrp_kanban_plan_pk.G_PRODUCTION_SOURCE_TYPE);
910     flm_util.add_bind (':b_category_set_id',
911   			mrp_kanban_plan_pk.g_kanban_info_rec.category_set_id);
912     flm_util.do_binds(l_cursor);
913 
914     -- now execute the sql stmt
915     l_rows_processed := dbms_sql.execute(l_cursor);
916 
917     -- close the cursor
918     dbms_sql.close_cursor (l_cursor);
919 
920   IF mrp_kanban_plan_pk.g_debug THEN
921     mrp_kanban_plan_pk.g_log_message :=
922   		'----------------------------------------------';
923     MRP_UTIL.MRP_LOG (mrp_kanban_plan_pk.g_log_message);
924     mrp_kanban_plan_pk.g_log_message :=
925   		'Successfully executed the Dynamic Sql Statement';
926     MRP_UTIL.MRP_LOG (mrp_kanban_plan_pk.g_log_message);
927     mrp_kanban_plan_pk.g_log_message := 'Inserted ' ||
928 		to_char(l_rows_processed) || ' into mrp_low_level_codes table';
929     MRP_UTIL.MRP_LOG (mrp_kanban_plan_pk.g_log_message);
930   END IF;
931 
932   END IF; -- so we basically did all the above only if we are not replanning
933 
934   ---------------------------------------------------------------------------
935   -- Now go ahead and get all the other items that are required for planning
936   -- from the bill structure
937   -- ------------------------------------------------------------------------
938 
939   IF mrp_kanban_plan_pk.g_debug THEN
940     mrp_kanban_plan_pk.g_log_message := 'Debug Statement Number : '
941 				|| to_char (mrp_kanban_plan_pk.g_stmt_num);
942     MRP_UTIL.MRP_LOG (mrp_kanban_plan_pk.g_log_message);
943   END IF;
944 
945   l_level_count := 1;
946 
947   WHILE TRUE LOOP
948 
949   -- ------------------------------------------------------------------------
950   -- Select parent of the current level items and insert into
951   -- mrp_low_level_codes table if not already present. So basically once
952   -- we got our initial list of items into mrp_low_level_codes, it becomes
953   -- driver for our select statement for insert. The rest of the logic is
954   -- similar to the above built sql statement. Notice how we are using
955   -- the levels_below column to walk our way up the bill
956   -- ------------------------------------------------------------------------
957 
958 	if l_eco_profile = FALSE  then
959 
960 		INSERT INTO mrp_low_level_codes (
961 		plan_id,
962 		organization_id,
963 		assembly_item_id,
964 		to_subinventory,
965 		to_locator_id,
966 		component_item_id,
967 		from_subinventory,
968 		from_locator_id,
969 		component_usage,
970 		component_yield,
971 /* Updated by Liye Ma  4/30/2001
972    Add two more columns, to fix bug 1745046 and 1757798. */
973                 planning_factor,
974 		item_num,
975 /* End of Update */
976 /*  Modified for lot based material support. Adding query of basis_type and wip_supply_type */
977                 basis_type,
978 		wip_supply_type,
979 		alternate_designator,
980 		levels_below,
981 		kanban_item_flag,
982 		component_category_id,
983 			request_id,
984 			program_application_id,
985 			program_id,
986 			program_update_date,
987 			last_updated_by,
988 			last_update_date,
989 			created_by,
990 			creation_date)
991 		SELECT /*+
992                     LEADING(MLLC)
993                     USE_NL(MLLC MRP_BIC BBOM MIC PS)
994                   */ DISTINCT
995 		mllc.plan_id,
996 		mllc.organization_id,
997 		bbom.assembly_item_id,
998 		ps.subinventory_name,
999 		ps.locator_id,
1000 		mrp_bic.component_item_id,
1001 		mrp_bic.supply_subinventory,
1002 		mrp_bic.supply_locator_id,
1003 		mrp_bic.component_quantity,
1004 		mrp_bic.component_yield_factor,
1005 /* Updated by Liye Ma  4/30/2001
1006    Add two more columns, to fix bug 1745046 and 1757798. */
1007                 mrp_bic.planning_factor,
1008 		mrp_bic.item_num,
1009 /* End of Update */
1010 /*  Modified for lot based material support. Adding query of basis_type and wip_supply_type */
1011                 nvl(mrp_bic.basis_type,WIP_CONSTANTS.ITEM_BASED_MTL),
1012 		nvl(mrp_bic.wip_supply_type,WIP_CONSTANTS.PUSH),
1013 		bbom.alternate_bom_designator,
1014 		l_level_count + 1,
1015 		NULL,		-- set it to NULL and update it next stmt
1016 		mic.category_id,
1017 			fnd_global.conc_request_id,
1018 			fnd_global.prog_appl_id,
1019 			fnd_global.conc_program_id,
1020 			sysdate,
1021 			fnd_global.user_id,
1022 			sysdate,
1023 			fnd_global.user_id,
1024 			sysdate
1025 		FROM
1026 		mtl_kanban_pull_sequences ps,
1027 		bom_bill_of_materials bbom,
1028 		mtl_item_categories mic,
1029 		bom_inventory_components mrp_bic,
1030 		mrp_low_level_codes mllc
1031 		WHERE	mllc.plan_id =
1032 			mrp_kanban_plan_pk.g_kanban_info_rec.kanban_plan_id
1033 		AND	mllc.organization_id =
1034 			mrp_kanban_plan_pk.g_kanban_info_rec.organization_id
1035 		AND		mllc.levels_below = l_level_count
1036 		AND		mrp_bic.component_item_id = mllc.assembly_item_id
1037 		AND		(nvl(mrp_bic.disable_date,
1038 		mrp_kanban_plan_pk.g_kanban_info_rec.bom_effectivity)) +1 >=
1039 			mrp_kanban_plan_pk.g_kanban_info_rec.bom_effectivity
1040 		AND         mrp_bic.effectivity_date <=
1041 			mrp_kanban_plan_pk.g_kanban_info_rec.bom_effectivity
1042 		AND	bbom.common_bill_sequence_id = mrp_bic.bill_sequence_id
1043 		AND     bbom.organization_id = mllc.organization_id
1044 		AND    	ps.kanban_plan_id (+) =
1045 		decode(mrp_kanban_plan_pk.g_kanban_info_rec.replan_flag,
1046 		2, mrp_kanban_plan_pk.G_PRODUCTION_KANBAN,
1047 		1, mrp_kanban_plan_pk.g_kanban_info_rec.kanban_plan_id,
1048 		mrp_kanban_plan_pk.G_PRODUCTION_KANBAN)
1049 		AND       	ps.organization_id (+) = bbom.organization_id
1050 		AND       	ps.inventory_item_id (+) = bbom.assembly_item_id
1051 		AND       	ps.source_type (+) = 4 /* KANBAN_PRODUCTION */
1052 /* Fix bug 2090054
1053 		AND         1 =  Check_Min_Priority (
1054 	        ps.inventory_item_id,
1055 	        ps.organization_id,
1056 	        ps.wip_line_id,
1057 		bbom.alternate_bom_designator)
1058 */
1059 		AND    	mic.organization_id (+)  =
1060 		mrp_kanban_plan_pk.g_kanban_info_rec.organization_id
1061 		AND    	mic.inventory_item_id (+) = mllc.assembly_item_id
1062 		AND    	mic.category_set_id (+) =
1063 			mrp_kanban_plan_pk.g_kanban_info_rec.category_set_id
1064 		/*  Avoid re-selecting items already in mrp_low_level_codes */
1065 		AND	 NOT EXISTS
1066 		( SELECT 'Exists'
1067 		 FROM 	mrp_low_level_codes mllc2
1068 		 WHERE  mllc2.plan_id =
1069 			mrp_kanban_plan_pk.g_kanban_info_rec.kanban_plan_id
1070 		 AND	mllc2.organization_id =
1071 			mrp_kanban_plan_pk.g_kanban_info_rec.organization_id
1072 		 AND    mllc2.component_item_id = mrp_bic.component_item_id )
1073          AND    EXISTS(
1074             SELECT  /*+no_unnest*/ 1
1075              FROM mtl_system_items msi
1076             WHERE msi.organization_id = bbom.organization_id
1077               AND msi.inventory_item_id = bbom.assembly_item_id
1078               AND msi.planning_make_buy_code = 1);
1079 	else
1080 		INSERT INTO mrp_low_level_codes (
1081 		plan_id,
1082 		organization_id,
1083 		assembly_item_id,
1084 		to_subinventory,
1085 		to_locator_id,
1086 		component_item_id,
1087 		from_subinventory,
1088 		from_locator_id,
1089 		component_usage,
1090 		component_yield,
1091 /* Updated by Liye Ma  4/30/2001
1092    Add two more columns, to fix bug 1745046 and 1757798. */
1093                 planning_factor,
1094 		item_num,
1095 /* End of Update */
1096 /*  Modified for lot based material support. Adding query of basis_type and wip_supply_type */
1097                 basis_type,
1098 		wip_supply_type,
1099 		alternate_designator,
1100 		levels_below,
1101 		kanban_item_flag,
1102 		component_category_id,
1103 			request_id,
1104 			program_application_id,
1105 			program_id,
1106 			program_update_date,
1107 			last_updated_by,
1108 			last_update_date,
1109 			created_by,
1110 			creation_date)
1111 		SELECT /*+ INDEX(PS MTL_KANBAN_PULL_SEQUENCES_N1) */ DISTINCT
1112 		mllc.plan_id,
1113 		mllc.organization_id,
1114 		bbom.assembly_item_id,
1115 		ps.subinventory_name,
1116 		ps.locator_id,
1117 		mrp_bic.component_item_id,
1118 		mrp_bic.supply_subinventory,
1119 		mrp_bic.supply_locator_id,
1120 		mrp_bic.component_quantity,
1121 		mrp_bic.component_yield_factor,
1122 /* Updated by Liye Ma  4/30/2001
1123    Add two more columns, to fix bug 1745046 and 1757798. */
1124                 mrp_bic.planning_factor,
1125 		mrp_bic.item_num,
1126 /* End of Update */
1127 /*  Modified for lot based material support. Adding query of basis_type and wip_supply_type */
1128                 nvl(mrp_bic.basis_type,WIP_CONSTANTS.ITEM_BASED_MTL),
1129 		nvl(mrp_bic.wip_supply_type,WIP_CONSTANTS.PUSH),
1130 		bbom.alternate_bom_designator,
1131 		l_level_count + 1,
1132 		NULL,		-- set it to NULL and update it next stmt
1133 		mic.category_id,
1134 			fnd_global.conc_request_id,
1135 			fnd_global.prog_appl_id,
1136 			fnd_global.conc_program_id,
1137 			sysdate,
1138 			fnd_global.user_id,
1139 			sysdate,
1140 			fnd_global.user_id,
1141 			sysdate
1142 		FROM
1143 		mtl_kanban_pull_sequences ps,
1144 		bom_bill_of_materials bbom,
1145 			mtl_item_categories mic,
1146 		bom_inventory_components mrp_bic,
1147 		mrp_low_level_codes mllc
1148 		WHERE	mllc.plan_id =
1149 			mrp_kanban_plan_pk.g_kanban_info_rec.kanban_plan_id
1150 		AND	mllc.organization_id =
1151 			mrp_kanban_plan_pk.g_kanban_info_rec.organization_id
1152 		AND		mllc.levels_below = l_level_count
1153 		AND		mrp_bic.component_item_id = mllc.assembly_item_id
1154 		AND		(nvl(mrp_bic.disable_date,
1155 		mrp_kanban_plan_pk.g_kanban_info_rec.bom_effectivity)) +1 >=
1156 		mrp_kanban_plan_pk.g_kanban_info_rec.bom_effectivity
1157 		AND         mrp_bic.effectivity_date <=
1158 			mrp_kanban_plan_pk.g_kanban_info_rec.bom_effectivity
1159 		AND         NOT EXISTS (
1160 		SELECT /*+ INDEX(bic2 BOM_INVENTORY_COMPONENTS_N1) */
1161 		NULL
1162 		FROM   bom_inventory_components bic2
1163 		WHERE  bic2.bill_sequence_id = mrp_bic.bill_sequence_id
1164 		AND    bic2.component_item_id = mrp_bic.component_item_id
1165 		AND    (decode(bic2.implementation_date, null,
1166 	        bic2.old_component_sequence_id,
1167 	        bic2.component_sequence_id) =
1168 		decode(mrp_bic.implementation_date, null,
1169 		mrp_bic.old_component_sequence_id,
1170 		mrp_bic.component_sequence_id)
1171 		OR bic2.operation_seq_num = mrp_bic.operation_seq_num)
1172 		AND    bic2.effectivity_date <=
1173 		mrp_kanban_plan_pk.g_kanban_info_rec.bom_effectivity
1174 		AND    bic2.effectivity_date > mrp_bic.effectivity_date
1175 		AND    (bic2.implementation_date is not null OR
1176 		(bic2.implementation_date is null AND EXISTS
1177 		(SELECT NULL
1178 		  FROM   eng_revised_items eri
1179 		  WHERE  bic2.revised_item_sequence_id =
1180 		  eri.revised_item_sequence_id
1181 		  AND    eri.mrp_active = 1 ))))
1182 		AND 	(mrp_bic.implementation_date is not null OR
1183 		(mrp_bic.implementation_date is null AND EXISTS
1184 		(SELECT NULL
1185 		 FROM   eng_revised_items eri
1186 		 WHERE  mrp_bic.revised_item_sequence_id =
1187 			eri.revised_item_sequence_id
1188 		 AND    eri.mrp_active = 1 )))
1189 		 AND	bbom.common_bill_sequence_id = mrp_bic.bill_sequence_id
1190 		AND     bbom.organization_id = mllc.organization_id
1191 		AND     ps.kanban_plan_id (+) =
1192 			decode(mrp_kanban_plan_pk.g_kanban_info_rec.replan_flag,
1193 		        2, mrp_kanban_plan_pk.G_PRODUCTION_KANBAN,
1194 			1, mrp_kanban_plan_pk.g_kanban_info_rec.kanban_plan_id,
1195 			mrp_kanban_plan_pk.G_PRODUCTION_KANBAN)
1196 		AND     ps.organization_id (+) = bbom.organization_id
1197 		AND     ps.inventory_item_id (+) = bbom.assembly_item_id
1198 		AND     ps.source_type (+) = 4 /* KANBAN_PRODUCTION */
1199 /* Fix bug 2090054
1200 		AND     1 =  Check_Min_Priority (
1201 			ps.inventory_item_id,
1202 			ps.organization_id,
1203 			ps.wip_line_id,
1204 			bbom.alternate_bom_designator)
1205 */
1206 		AND     mic.organization_id (+)  =
1207 			mrp_kanban_plan_pk.g_kanban_info_rec.organization_id
1208 		AND     mic.inventory_item_id (+) = mllc.assembly_item_id
1209 		AND     mic.category_set_id (+) =
1210 			mrp_kanban_plan_pk.g_kanban_info_rec.category_set_id
1211 		/*  Avoid re-selecting items already in mrp_low_level_codes */
1212 		AND	 NOT EXISTS
1213 		( SELECT 'Exists'
1214 		 FROM 	mrp_low_level_codes mllc2
1215 		 WHERE  mllc2.plan_id =
1216 			mrp_kanban_plan_pk.g_kanban_info_rec.kanban_plan_id
1217 		 AND	mllc2.organization_id =
1218 			mrp_kanban_plan_pk.g_kanban_info_rec.organization_id
1219 		 AND    mllc2.component_item_id = mrp_bic.component_item_id )
1220          AND    EXISTS(
1221             SELECT  /*+no_unnest*/ 1
1222              FROM mtl_system_items msi
1223             WHERE msi.organization_id = bbom.organization_id
1224               AND msi.inventory_item_id = bbom.assembly_item_id
1225               AND msi.planning_make_buy_code = 1);
1226 
1227 	end if;
1228 
1229 
1230     EXIT WHEN SQL%ROWCOUNT = 0;
1231 
1232     l_level_count := l_level_count + 1;
1233 
1234   END LOOP;
1235 
1236 
1237   -- The purpose of this statment is to improve the performance
1238   -- The above insert stmt has performance problems and
1239   -- to avoid two outer join in mtl_kanban_pull_sequences
1240   -- we decide to break it down.
1241   UPDATE mrp_low_level_codes mllc
1242   SET (mllc.kanban_item_flag) =
1243       (select nvl(max(decode(kbn_items.release_kanban_flag, 1, 'Y', 'Y')), 'N')
1244        from   mtl_kanban_pull_sequences kbn_items
1245        where kbn_items.kanban_plan_id =
1246 	     mrp_kanban_plan_pk.g_kanban_info_rec.kanban_plan_id
1247        and   kbn_items.organization_id =
1248 	     mrp_kanban_plan_pk.g_kanban_info_rec.organization_id
1249        and   kbn_items.inventory_item_id = mllc.assembly_item_id)
1250   WHERE mllc.plan_id =
1251           mrp_kanban_plan_pk.g_kanban_info_rec.kanban_plan_id
1252   AND mllc.organization_id =
1253           mrp_kanban_plan_pk.g_kanban_info_rec.organization_id
1254   AND mllc.kanban_item_flag is null;
1255 
1256 
1257   mrp_kanban_plan_pk.g_stmt_num := 80;
1258   IF mrp_kanban_plan_pk.g_debug THEN
1259     mrp_kanban_plan_pk.g_log_message := 'Debug Statement Number : '
1260 				|| to_char (mrp_kanban_plan_pk.g_stmt_num);
1261     MRP_UTIL.MRP_LOG (mrp_kanban_plan_pk.g_log_message);
1262   END IF;
1263 
1264   -- now update the mrp_low_level_codes table with operation_yield
1265   -- and net_planning_percent from the bom_operation_sequences table.
1266   -- We did this separately after inserting all that we wanted to
1267   -- insert only to make the code a little cleaner.  We tried doing
1268   -- this in the above sql statement itself but obviously if got
1269   -- kinda ugly trying to achieve it.
1270 
1271   -- bom_inventory_components and bom_operation_sequences are linked
1272   -- by the operation sequence number and for a particular operation
1273   -- sequence we have the net_planning_percent and the operation_yield
1274   -- (actually the reverse_cumulative_yield column) stored in
1275   -- bom_operation_sequences table
1276 
1277   UPDATE  mrp_low_level_codes mllc
1278   SET	  (mllc.operation_yield,mllc.net_planning_percent) =
1279 	  (SELECT min(bos.reverse_cumulative_yield),
1280 	 	  min(bos.net_planning_percent)
1281 	   FROM	  bom_operation_sequences bos,
1282 		  bom_operational_routings bor,
1283 		  bom_inventory_components mrp_bic,
1284 		  bom_bill_of_materials bbom
1285 	   WHERE  bbom.assembly_item_id = mllc.assembly_item_id
1286 	   AND	  bbom.organization_id = mllc.organization_id
1287 	   AND	  nvl(bbom.alternate_bom_designator, 'xxx') =
1288                	  nvl(mllc.alternate_designator, 'xxx')
1289 	   AND	  mrp_bic.bill_sequence_id = bbom.common_bill_sequence_id
1290 	   AND	  mrp_bic.component_item_id = mllc.component_item_id
1291     	   AND	  (nvl(mrp_bic.disable_date,
1292 		   mrp_kanban_plan_pk.g_kanban_info_rec.bom_effectivity) +1) >=
1293 		   mrp_kanban_plan_pk.g_kanban_info_rec.bom_effectivity
1294     	   AND     mrp_bic.effectivity_date <=
1295 		   mrp_kanban_plan_pk.g_kanban_info_rec.bom_effectivity
1296       	   AND    NOT EXISTS (
1297                	  SELECT NULL
1298                   FROM   bom_inventory_components bic2
1299                   WHERE  bic2.bill_sequence_id = mrp_bic.bill_sequence_id
1300                   AND    bic2.component_item_id = mrp_bic.component_item_id
1301                   AND    (decode(bic2.implementation_date, null,
1302                                bic2.old_component_sequence_id,
1303                                bic2.component_sequence_id) =
1304                        decode(mrp_bic.implementation_date, null,
1305                               mrp_bic.old_component_sequence_id,
1306                               mrp_bic.component_sequence_id)
1307                        OR bic2.operation_seq_num = mrp_bic.operation_seq_num)
1308                   AND    bic2.effectivity_date <=
1309 			mrp_kanban_plan_pk.g_kanban_info_rec.bom_effectivity
1310                   AND    bic2.effectivity_date > mrp_bic.effectivity_date
1311                   AND    (bic2.implementation_date is not null OR
1312                          (bic2.implementation_date is null AND EXISTS
1313                          (SELECT NULL
1314                           FROM   eng_revised_items eri
1315                           WHERE  bic2.revised_item_sequence_id =
1316                                                 eri.revised_item_sequence_id
1317                           AND    eri.mrp_active = 1 ))))
1318            AND    (mrp_bic.implementation_date is not null OR
1319                          (mrp_bic.implementation_date is null AND EXISTS
1320                          (SELECT NULL
1321                           FROM   eng_revised_items eri
1322                           WHERE  mrp_bic.revised_item_sequence_id =
1323                                                 eri.revised_item_sequence_id
1324                           AND    eri.mrp_active = 1 )))
1325 	   AND	  bor.organization_id = bbom.organization_id
1326 	   AND	  bor.assembly_item_id = bbom.assembly_item_id
1327 	   AND	  nvl(bor.alternate_routing_designator, 'xxx') =
1328                	  nvl(bbom.alternate_bom_designator, 'xxx')
1329 	   AND	  bos.routing_sequence_id = bor.routing_sequence_id
1330 	   AND	  bos.operation_seq_num = mrp_bic.operation_seq_num
1331 	   AND	  nvl(bos.operation_type, 1) = 1
1332 	   AND	  nvl(bos.disable_date,
1333 		    mrp_kanban_plan_pk.g_kanban_info_rec.bom_effectivity) + 1
1334 			>= mrp_kanban_plan_pk.g_kanban_info_rec.bom_effectivity
1335 	   AND	  bos.effectivity_date <=
1336 		  mrp_kanban_plan_pk.g_kanban_info_rec.bom_effectivity)
1337   WHERE	   mllc.plan_id = mrp_kanban_plan_pk.g_kanban_info_rec.kanban_plan_id;
1338 
1339   mrp_kanban_plan_pk.g_stmt_num := 90;
1340 
1341 
1342   IF mrp_kanban_plan_pk.g_debug THEN
1343     mrp_kanban_plan_pk.g_log_message := 'Debug Statement Number : '
1344 				|| to_char (mrp_kanban_plan_pk.g_stmt_num);
1345     MRP_UTIL.MRP_LOG (mrp_kanban_plan_pk.g_log_message);
1346     mrp_kanban_plan_pk.g_log_message := 'Updated mrp_low_level_codes ' ||
1347 			'with net planning percent and yield information';
1348     MRP_UTIL.MRP_LOG (mrp_kanban_plan_pk.g_log_message);
1349   END IF;
1350 
1351 
1352   -- ------------------------------------------------------------------------
1353   -- Now insert the top level assembly item
1354   -- Since the top level assembly item does not have a parent, it would not
1355   -- gotten into mrp_low_level_codes table as a component item (which is
1356   -- what we use to plan).  So, we create a dummy parent of -1 for him and
1357   -- insert him into the mrp_low_level_codes table
1358   -- ------------------------------------------------------------------------
1359 
1360     INSERT INTO mrp_low_level_codes (
1361 	plan_id,
1362 	organization_id,
1363 	assembly_item_id,
1364 	component_item_id,
1365         from_subinventory,
1366 	from_locator_id,
1367 	levels_below,
1368 	kanban_item_flag,
1369 	component_category_id,
1370     	request_id,
1371     	program_application_id,
1372     	program_id,
1373     	program_update_date,
1374         last_updated_by,
1375         last_update_date,
1376         created_by,
1377         creation_date )
1378     SELECT DISTINCT
1379 	mllc1.plan_id,
1380 	mllc1.organization_id,
1381 	-1,
1382 	mllc1.assembly_item_id,
1383 	mllc1.to_subinventory,
1384 	mllc1.to_locator_id,
1385 	l_level_count + 1,
1386 	decode(kbn_items.release_kanban_flag, 1, 'Y', 2, 'Y', 'N'),
1387 	mic.category_id,
1388         fnd_global.conc_request_id,
1389         fnd_global.prog_appl_id,
1390         fnd_global.conc_program_id,
1391         sysdate,
1392         fnd_global.user_id,
1393         sysdate,
1394         fnd_global.user_id,
1395         sysdate
1396     FROM
1397  	mtl_item_categories mic,
1398  	mtl_kanban_pull_sequences kbn_items,
1399 	mrp_low_level_codes mllc1
1400     WHERE
1401     	mllc1.plan_id = mrp_kanban_plan_pk.g_kanban_info_rec.kanban_plan_id AND
1402     	mllc1.organization_id =
1403 	   mrp_kanban_plan_pk.g_kanban_info_rec.organization_id AND
1404 	kbn_items.inventory_item_id (+) =
1405 				mrp_kanban_plan_pk.G_PRODUCTION_KANBAN AND
1406 	kbn_items.inventory_item_id (+) = mllc1.assembly_item_id AND
1407 	kbn_items.organization_id (+) = mllc1.organization_id AND
1408 	mic.inventory_item_id (+) = mllc1.assembly_item_id AND
1409 	mic.organization_id (+) = mllc1.organization_id AND
1410 	mic.category_set_id (+) =
1411 		mrp_kanban_plan_pk.g_kanban_info_rec.category_set_id AND
1412     	--select only the assembly items that do not exist as components
1413      	NOT EXISTS
1414 	(SELECT 'Exists'
1415 	 FROM 	mrp_low_level_codes mllc2
1416 	 WHERE  mllc2.plan_id = mllc1.plan_id AND
1417 	 	mllc2.organization_id = mllc1.organization_id AND
1418 	     	mllc2.component_item_id = mllc1.assembly_item_id );
1419 
1420 
1421 
1422   mrp_kanban_plan_pk.g_stmt_num := 100;
1423   IF mrp_kanban_plan_pk.g_debug THEN
1424     mrp_kanban_plan_pk.g_log_message := 'Debug Statement Number : '
1425 				|| to_char (mrp_kanban_plan_pk.g_stmt_num);
1426     MRP_UTIL.MRP_LOG (mrp_kanban_plan_pk.g_log_message);
1427   END IF;
1428 
1429   -- ------------------------------------------------------------------------
1430   -- Now find information in mtl_kanban_pull_sequences about inter-org and
1431   -- intra-org transfers and insert into mrp_low_level_codes
1432   -- Note here that replan flag drives whether I pull infomation from the
1433   -- production kanban plan or the current kanban plan itself.  Replan_flag
1434   -- = 2 is not a replan and if its 1 then its a replan run.
1435   -- We are not including supplier kind of replenishment here because we
1436   -- can afford to not calculate the low_level_code for a supplier source type
1437   -- (since we know that's the end point in the chain, we can stop one point
1438   -- before that).
1439   -- ------------------------------------------------------------------------
1440 
1441   INSERT INTO mrp_low_level_codes (
1442         plan_id,
1443         organization_id,
1444         assembly_item_id,
1445         to_subinventory,
1446         to_locator_id,
1447         component_item_id,
1448         from_subinventory,
1449         from_locator_id,
1450         component_usage,
1451         component_yield,
1452 	supply_source_type,
1453 	replenishment_lead_time,
1454 	kanban_item_flag,
1455 	component_category_id,
1456     	request_id,
1457     	program_application_id,
1458     	program_id,
1459     	program_update_date,
1460         last_updated_by,
1461         last_update_date,
1462         created_by,
1463         creation_date )
1464   SELECT DISTINCT
1465 	mrp_kanban_plan_pk.g_kanban_info_rec.kanban_plan_id,
1466 	ps.organization_id,
1467 	ps.inventory_item_id,
1468 	ps.subinventory_name,
1469 	ps.locator_id,
1470 	ps.inventory_item_id,
1471 	ps.source_subinventory,
1472 	ps.source_locator_id,
1473 	1,
1474 	1,
1475 	ps.source_type,
1476 	ps.replenishment_lead_time,
1477 	'Y',
1478 	mllc.component_category_id,
1479         fnd_global.conc_request_id,
1480         fnd_global.prog_appl_id,
1481         fnd_global.conc_program_id,
1482         sysdate,
1483         fnd_global.user_id,
1484         sysdate,
1485         fnd_global.user_id,
1486         sysdate
1487   FROM  mtl_kanban_pull_sequences ps,
1488 	mrp_low_level_codes mllc
1489   WHERE	ps.source_type = 3 -- only intra org replenishments
1490   AND   ps.kanban_plan_id =
1491 		decode(mrp_kanban_plan_pk.g_kanban_info_rec.replan_flag,
1492                 2, mrp_kanban_plan_pk.G_PRODUCTION_KANBAN,
1493                 1, mrp_kanban_plan_pk.g_kanban_info_rec.kanban_plan_id,
1494                 mrp_kanban_plan_pk.G_PRODUCTION_KANBAN)
1495   AND	ps.organization_id = mllc.organization_id
1496   AND	ps.inventory_item_id = mllc.component_item_id
1497   AND	mllc.organization_id =
1498 		mrp_kanban_plan_pk.g_kanban_info_rec.organization_id
1499   AND	mllc.plan_id = mrp_kanban_plan_pk.g_kanban_info_rec.kanban_plan_id
1500   AND   mllc.kanban_item_flag = 'Y';
1501 
1502 
1503   IF mrp_kanban_plan_pk.g_debug THEN
1504     mrp_kanban_plan_pk.g_log_message :=
1505 		'Completed inserting into mrp_low_level_codes table';
1506     MRP_UTIL.MRP_LOG (mrp_kanban_plan_pk.g_log_message);
1507   END IF;
1508   mrp_kanban_plan_pk.g_stmt_num := 110;
1509   IF mrp_kanban_plan_pk.g_debug THEN
1510     mrp_kanban_plan_pk.g_log_message := 'Debug Statement Number : '
1511 				|| to_char (mrp_kanban_plan_pk.g_stmt_num);
1512     MRP_UTIL.MRP_LOG (mrp_kanban_plan_pk.g_log_message);
1513   END IF;
1514 
1515   -- call the check_item_locations procedure to ensure that
1516   -- kanban items have the from-locations populated in the
1517   -- mrp_low_level_codes table.  If the kanban items do not have
1518   -- the from locations populated, we can run into issues while
1519   -- calculating low_level_codes
1520 
1521   IF NOT Check_Item_Locations THEN
1522     RETURN FALSE;
1523   END IF;
1524 
1525   mrp_kanban_plan_pk.g_stmt_num := 130;
1526   IF mrp_kanban_plan_pk.g_debug THEN
1527     mrp_kanban_plan_pk.g_log_message := 'Debug Statement Number : '
1528 				|| to_char (mrp_kanban_plan_pk.g_stmt_num);
1529     MRP_UTIL.MRP_LOG (mrp_kanban_plan_pk.g_log_message);
1530   END IF;
1531 
1532   -- now we are ready for our low level code calculation
1533   -- so call that procedure
1534 
1535   IF mrp_kanban_plan_pk.g_debug THEN
1536     mrp_kanban_plan_pk.g_log_message := 'Calling CALC_LOW_LEVEL_code function';
1537     MRP_UTIL.MRP_LOG (mrp_kanban_plan_pk.g_log_message);
1538   END IF;
1539 
1540   IF NOT Calc_Low_Level_code THEN
1541     RETURN FALSE;
1542   END IF;
1543 
1544   mrp_kanban_plan_pk.g_stmt_num := 140;
1545   IF mrp_kanban_plan_pk.g_debug THEN
1546     mrp_kanban_plan_pk.g_log_message := 'Debug Statement Number : ' ||
1547 				   to_char (mrp_kanban_plan_pk.g_stmt_num);
1548     MRP_UTIL.MRP_LOG (mrp_kanban_plan_pk.g_log_message);
1549     mrp_kanban_plan_pk.g_log_message := 'Calling CHECK_FOR_LOOPS function';
1550     MRP_UTIL.MRP_LOG (mrp_kanban_plan_pk.g_log_message);
1551   END IF;
1552 
1553 
1554   -- after low level code calculation, if we have component items
1555   -- in mrp_low_level_code table with no low level code assigned
1556   -- then we have loop in the bill. Call the procedure to check this
1557 
1558   IF NOT Check_For_Loops THEN
1559     RETURN FALSE;
1560   END IF;
1561 
1562   RETURN TRUE;
1563 
1564 EXCEPTION
1565 
1566   WHEN OTHERS THEN
1567     mrp_kanban_plan_pk.g_log_message := 'SNAPSHOT_ITEM_LOCATIONS Sql Error ';
1568     MRP_UTIL.MRP_LOG (mrp_kanban_plan_pk.g_log_message);
1569     mrp_kanban_plan_pk.g_log_message := sqlerrm;
1570     MRP_UTIL.MRP_LOG (mrp_kanban_plan_pk.g_log_message);
1571     RETURN FALSE;
1572 
1573 END SNAPSHOT_ITEM_LOCATIONS;
1574 
1575 
1576 END MRP_KANBAN_SNAPSHOT_PK;
1577