DBA Data[Home] [Help]

PACKAGE BODY: APPS.WMS_REPLENISHMENT_PVT

Source


1 PACKAGE BODY wms_replenishment_pvt AS
2 /* $Header: WMSREPVB.pls 120.31.12020000.5 2013/03/18 05:52:51 pramadur ship $  */
3 
4 
5 -- PACKAGE variables
6 g_ordered_psr           psrTabTyp;
7 g_total_pick_criteria       NUMBER := 5;
8 g_conversion_precision      NUMBER := 5;
9 
10 
11 -- replenishment Type
12 g_push_repl NUMBER    := 1;
13 g_dynamic_repl NUMBER := 2;
14 
15 -- This is a function used to retrieve the UOM conversion rate given an inventory item ID,
16 -- from UOM code and to UOM code.  The values retrieved will be cached in a global PLSQL table.
17 
18 PROCEDURE print_debug(p_err_msg VARCHAR2)
19   IS
20 BEGIN
21    inv_mobile_helper_functions.tracelog(p_err_msg => p_err_msg,
22 					p_module => 'WMS_REPLENISHMENT_PVT',
23 					p_level => 4);
24 END print_debug;
25 
26 
27 
28 FUNCTION get_conversion_rate(p_item_id       IN NUMBER,
29 			     p_from_uom_code IN VARCHAR2,
30 			     p_to_uom_code   IN VARCHAR2) RETURN NUMBER
31   IS
32      l_conversion_rate NUMBER;
33      l_debug              NUMBER      := NVL(fnd_profile.VALUE('INV_DEBUG_TRACE'), 0);
34 
35 BEGIN
36    IF (p_from_uom_code = p_to_uom_code) THEN
37       -- No conversion necessary
38       l_conversion_rate := 1;
39     ELSE
40       -- Check if the conversion rate for the item/from UOM/to UOM combination is cached
41       IF (g_item_uom_conversion_tb.EXISTS(p_item_id) AND
42 	  g_item_uom_conversion_tb(p_item_id).EXISTS(p_from_uom_code) AND
43 	  g_item_uom_conversion_tb(p_item_id)(p_from_uom_code).EXISTS(p_to_uom_code)) THEN
44 
45 	 -- Conversion rate is cached so just use the value
46 	 l_conversion_rate := g_item_uom_conversion_tb(p_item_id)(p_from_uom_code)(p_to_uom_code);
47        ELSE
48 	 -- Conversion rate is not cached so query and store the value
49 	 inv_convert.inv_um_conversion(from_unit => p_from_uom_code,
50 				       to_unit   => p_to_uom_code,
51 				       item_id   => p_item_id,
52 				       uom_rate  => l_conversion_rate);
53 	 IF (l_conversion_rate > 0) THEN
54 	    -- Store the conversion rate and also the reverse conversion.
55 	    -- Do this only if the conversion rate returned is valid, i.e. not negative.
56 	    -- {{
57 	    -- Test having an exception when retrieving the UOM conversion rate. }}
58 	    g_item_uom_conversion_tb(p_item_id)(p_from_uom_code)(p_to_uom_code) := l_conversion_rate;
59 	    g_item_uom_conversion_tb(p_item_id)(p_to_uom_code)(p_from_uom_code) := 1 /l_conversion_rate;
60 	 END IF;
61       END IF;
62    END IF;
63 
64    -- Return the conversion rate retrieved
65    RETURN l_conversion_rate;
66 
67 EXCEPTION
68    WHEN OTHERS THEN
69       IF l_debug = 1 THEN
70 	 print_debug('Exception in get_conversion_rate: ' || sqlcode || ', ' || sqlerrm);
71       END IF;
72       -- If an exception occurs, return a negative value.
73       -- The calling program should interpret this as an exception in retrieving
74       -- the UOM conversion rate.
75       RETURN -999;
76 END get_conversion_rate;
77 
78 
79 -- API name : Init_Rules
80 -- Type     : Public
81 -- Pre-reqs : None.
82 -- Procedure: API to retrieves  sequencing information based on sequence rule and
83 --            group information based on grouping rule.
84 -- Parameters :
85 -- IN:
86 --      p_pick_seq_rule_id            IN  pick sequence rule id.
87 -- OUT:
88 --      x_api_status     OUT NOCOPY  Standard to output api status.
89 
90 -- This API gets called from the wms_task_dispatch_gen.pick_drop() API as
91 -- well. Needed to pass x_ordered_psr for this
92 
93 PROCEDURE Init_Rules(p_pick_seq_rule_id     IN NUMBER
94 		     , x_order_id_sort       OUT NOCOPY VARCHAR2
95 		     , x_INVOICE_VALUE_SORT  OUT NOCOPY VARCHAR2
96 		     , x_SCHEDULE_DATE_SORT  OUT NOCOPY VARCHAR2
97 		     , x_trip_stop_date_sort OUT NOCOPY VARCHAR2
98 		     , x_SHIPMENT_PRI_SORT   OUT NOCOPY VARCHAR2
99 		     , x_ordered_psr         OUT nocopy  psrTabTyp
100 		     , x_api_status          OUT NOCOPY VARCHAR2)
101   IS
102 
103 
104      -- cursor to fetch pick sequence rule info
105      l_debug              NUMBER      := NVL(fnd_profile.VALUE('INV_DEBUG_TRACE'), 0);
106      CURSOR pick_seq_rule(v_psr_id NUMBER) IS
107 	SELECT NAME,
108 	  NVL(ORDER_ID_PRIORITY, 999999999),
109 	  DECODE(ORDER_ID_SORT, 'A', 'ASC', 'D', 'DESC', ''),
110 	  NVL(INVOICE_VALUE_PRIORITY, 999999999),
111 	  DECODE(INVOICE_VALUE_SORT, 'A', 'ASC', 'D', 'DESC', ''),
112 	  NVL(SCHEDULE_DATE_PRIORITY, 999999999),
113 	  DECODE(SCHEDULE_DATE_SORT, 'A', 'ASC', 'D', 'DESC', ''),
114 	  NVL(SHIPMENT_PRI_PRIORITY, 999999999),
115 	  DECODE(SHIPMENT_PRI_SORT, 'A', 'ASC', 'D', 'DESC', ''),
116 	  NVL(TRIP_STOP_DATE_PRIORITY, 999999999),
117 	  DECODE(TRIP_STOP_DATE_SORT, 'A', 'ASC', 'D', 'DESC', '')
118 	  FROM WSH_PICK_SEQUENCE_RULES
119 	  WHERE PICK_SEQUENCE_RULE_ID = v_psr_id
120 	  AND SYSDATE BETWEEN TRUNC(NVL(START_DATE_ACTIVE, SYSDATE)) AND
121 	  NVL(END_DATE_ACTIVE, TRUNC(SYSDATE) + 1);
122 
123      l_pick_seq_rule_name      VARCHAR2(30);
124      l_invoice_value_priority  NUMBER;
125      l_order_id_priority       NUMBER;
126      l_schedule_date_priority  NUMBER;
127      l_trip_stop_date_priority NUMBER;
128      l_shipment_pri_priority   NUMBER;
129      l_invoice_value_sort      VARCHAR2(4);
130      l_order_id_sort           VARCHAR2(4);
131      l_schedule_date_sort      VARCHAR2(4);
132      l_trip_stop_date_sort     VARCHAR2(4);
133      l_shipment_pri_sort       VARCHAR2(4);
134      i                         NUMBER;
135      j                         NUMBER;
136      l_temp_psr                psrTyp;
137      l_ordered_psr             psrtabtyp;
138 BEGIN
139    x_api_status := fnd_api.g_ret_sts_success;
140 
141    IF  p_pick_seq_rule_id IS NULL THEN
142       FOR i IN 1 .. g_total_pick_criteria LOOP
143 	 l_ordered_psr(i).attribute_name := 'TEMP';
144 	 l_ordered_psr(i).priority := 999999999;
145 	 l_ordered_psr(i).sort_order := 'ASC';
146       END LOOP;
147 
148       --ASSIGN ANY VALUE
149       x_order_id_sort := 'ASC';
150       x_INVOICE_VALUE_SORT := 'ASC';
151       x_SCHEDULE_DATE_SORT := 'ASC';
152       x_trip_stop_date_sort := 'ASC';
153       x_SHIPMENT_PRI_SORT   := 'ASC';
154 
155     ELSE -- means p_pick_seq_rule_id is not null
156 
157 
158       -- fetch pick sequence rule parameters
159       OPEN pick_seq_rule(p_pick_seq_rule_id);
160       LOOP
161 	 FETCH pick_seq_rule
162 	   INTO l_pick_seq_rule_name, L_ORDER_ID_PRIORITY, x_ORDER_ID_SORT,
163 	   L_INVOICE_VALUE_PRIORITY, x_INVOICE_VALUE_SORT,
164 	   L_SCHEDULE_DATE_PRIORITY, x_SCHEDULE_DATE_SORT,
165 	   L_TRIP_STOP_DATE_PRIORITY,
166 	   x_TRIP_STOP_DATE_SORT, L_SHIPMENT_PRI_PRIORITY, x_SHIPMENT_PRI_SORT;
167 	 EXIT WHEN pick_seq_rule%notfound;
168       END LOOP;
169       CLOSE pick_seq_rule;
170 
171       -- initialize the pick sequence rule parameters
172       i := 1;
173 
174       l_ordered_psr(i).attribute_name := 'ORDER_NUMBER';
175       l_ordered_psr(i).priority := l_order_id_priority;
176       l_ordered_psr(i).sort_order := x_order_id_sort;
177       i := i + 1;
178 
179       l_ordered_psr(i).attribute_name := 'SHIPMENT_PRIORITY';
180       l_ordered_psr(i).priority := l_shipment_pri_priority;
181       l_ordered_psr(i).sort_order := x_shipment_pri_sort;
182       i := i + 1;
183 
184       l_ordered_psr(i).attribute_name := 'INVOICE_VALUE';
185       l_ordered_psr(i).priority := l_invoice_value_priority;
186       l_ordered_psr(i).sort_order := x_invoice_value_sort;
187       i := i + 1;
188 
189       l_ordered_psr(i).attribute_name := 'SCHEDULE_DATE';
190       l_ordered_psr(i).priority := l_schedule_date_priority;
191       l_ordered_psr(i).sort_order := x_schedule_date_sort;
192       i := i + 1;
193 
194       l_ordered_psr(i).attribute_name := 'TRIP_STOP_DATE';
195       l_ordered_psr(i).priority := l_trip_stop_date_priority;
196       l_ordered_psr(i).sort_order := x_trip_stop_date_sort;
197       i := i + 1;
198 
199       -- sort the table for pick sequence rule according to priority
200       FOR i IN 1 .. g_total_pick_criteria LOOP
201 	 FOR j IN i + 1 .. g_total_pick_criteria LOOP
202 	    IF (l_ordered_psr(j).priority < l_ordered_psr(i).priority) THEN
203 	       l_temp_psr := l_ordered_psr(j);
204 	       l_ordered_psr(j) := l_ordered_psr(i);
205 	       l_ordered_psr(i) := l_temp_psr;
206 	    END IF;
207 	 END LOOP;
208       END LOOP;
209    END IF; -- for p_pick_seq_rule_id is null
210 
211    x_ordered_psr := l_ordered_psr;
212    x_api_status := FND_API.G_RET_STS_SUCCESS;
213 
214 EXCEPTION
215    --
216    WHEN OTHERS THEN
217       --
218       x_api_status := fnd_api.g_ret_sts_unexp_error;
219       --
220       IF pick_seq_rule%ISOPEN THEN
221 	 CLOSE pick_seq_rule;
222       END IF;
223       IF l_debug = 1 THEN
224 	 print_debug('Error in Init_Rules: ' || sqlcode || ', ' || sqlerrm);
225       END IF;
226 
227 END Init_Rules;
228 
229 
230 
231 PROCEDURE Get_Source_Sub_Dest_Loc_Info(p_Org_id              IN NUMBER,
232                                        p_Item_id             IN NUMBER,
233                                        p_Picking_Sub         IN VARCHAR2,
234                                        x_source_sub          OUT NOCOPY VARCHAR2,
235 				       x_src_pick_uom        OUT NOCOPY VARCHAR2,
236                                        x_MAX_MINMAX_QUANTITY OUT NOCOPY NUMBER,
237 				       x_fixed_lot_multiple  OUT NOCOPY NUMBER,
238                                        x_return_status       OUT NOCOPY VARCHAR2)
239   IS
240 
241      -- Get the source sub for destination location for the replenishment move order
242 
243      CURSOR c_get_source_sub IS
244 	select MISI.SOURCE_SUBINVENTORY, MSISR.pick_uom_code, Nvl(MISI.max_minmax_quantity,0), NVL(MISI.FIXED_LOT_MULTIPLE, -1)
245 	  FROM MTL_ITEM_SUB_INVENTORIES MISI,
246 	  MTL_SECONDARY_INVENTORIES msi,
247 	  MTL_SECONDARY_INVENTORIES MSISR
248 	  WHERE MISI.organization_id = p_Org_id
249 	  AND MISI.SECONDARY_INVENTORY = MSI.SECONDARY_INVENTORY_NAME
250 	  AND MISI.ORGANIZATION_ID = MSI.ORGANIZATION_ID
251 	  and MISI.INVENTORY_ITEM_ID = p_Item_id
252 	  and MISI.source_type = 3 --(for Subinventory)
253 	  AND MISI.source_organization_id = p_Org_id
254 	  and MISI.SECONDARY_INVENTORY = p_picking_sub
255 	  and MSISR.SECONDARY_INVENTORY_NAME = MISI.SOURCE_SUBINVENTORY
256 	  AND MSISR.ORGANIZATION_ID = MISI.ORGANIZATION_ID
257 	  order by MSI.picking_order;
258 
259      -- Destination locator from Item+Sub Form will NOT be stamped on the REPL MO
260      -- So that rules engine can allocate destination locator of the
261      -- IDENTIFIED sub  based on available capacity
262 
263      L_INDEX NUMBER;
264      l_debug number := NVL(FND_PROFILE.VALUE('INV_DEBUG_TRACE'),0);
265 
266 BEGIN
267    x_return_status := fnd_api.g_ret_sts_success;
268 
269    -- Get the highest priority subinventory
270    L_INDEX := 0;
271    OPEN c_get_source_sub;
272    LOOP
273       FETCH c_get_source_sub
274 	into x_source_sub, x_src_pick_uom, x_max_minmax_quantity, x_fixed_lot_multiple;
275       EXIT WHEN c_get_source_sub%NOTFOUND;
276       L_INDEX := L_INDEX + 1;
277       EXIT WHEN L_INDEX = 1;
278    END LOOP;
279    CLOSE c_get_source_sub;
280 
281    IF l_index = 0 THEN -- means no record found
282       x_source_sub := NULL;
283       x_src_pick_uom := NULL;
284       x_max_minmax_quantity := 0;
285       x_fixed_lot_multiple  := -1;
286    END IF;
287 
288 
289    IF l_debug = 1 THEN
290       print_debug('Return values from API Get_Source_Sub_Dest_Loc_Info' );
291       print_debug('l_index               :' || l_index);
292       print_debug('x_source_sub          :' || x_source_sub );
293       print_debug('x_src_pick_uom        :' || x_src_pick_uom );
294       print_debug('x_fixed_lot_multiple  :' || x_fixed_lot_multiple);
295       print_debug('x_MAX_MINMAX_QUANTITY :' || x_MAX_MINMAX_QUANTITY);
296    END IF;
297 
298 
299    x_return_status := FND_API.G_RET_STS_SUCCESS;
300 
301 EXCEPTION
302    WHEN OTHERS THEN
303       IF l_debug = 1 THEN
304 	 print_debug('Error Get_Source_Sub_loc_Info: ' || sqlcode || ',' || sqlerrm);
305       END IF;
306 
307       IF c_get_source_sub%ISOPEN THEN
308 	 CLOSE c_get_source_sub;
309       END IF;
310 
311       x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
312 
313 END Get_Source_Sub_Dest_Loc_Info;
314 
315 
316 
317 --Updates the replenishment_status of single passed delivery_detail_id
318 -- If p_repl_status = 'R' marks it RR
319 -- If p_repl_status = 'C' marks it RC
320 -- If p_repl_status = NULL - Reverts WDD to original status (Ready to release / backorder)
321 --
322 PROCEDURE update_wdd_repl_status (p_deliv_detail_id   IN NUMBER
323 				  , p_repl_status     IN VARCHAR2
324 				  , p_deliv_qty       IN NUMBER DEFAULT NULL
325 				  , x_return_status            OUT    NOCOPY VARCHAR2
326 				  )
327   IS
328 
329      l_return_status VARCHAR2(1) := fnd_api.g_ret_sts_success;
330 
331      l_detail_info_tab             WSH_INTERFACE_EXT_GRP.delivery_details_Attr_tbl_Type;
332      l_in_rec                      WSH_INTERFACE_EXT_GRP.detailInRecType;
333      l_out_rec                     WSH_INTERFACE_EXT_GRP.detailOutRecType;
334 
335      l_msg_count     NUMBER;
336      l_msg_data      VARCHAR2(1000);
337      l_debug number := NVL(FND_PROFILE.VALUE('INV_DEBUG_TRACE'),0);
338 
339      -- for backordering
340      l_out_rows             WSH_UTIL_CORE.ID_TAB_TYPE;
341      l_backorder_deliv_tab  WSH_UTIL_CORE.ID_TAB_TYPE;
342      l_backorder_qty_tab    WSH_UTIL_CORE.ID_TAB_TYPE;
343      l_dummy_table          WSH_UTIL_CORE.ID_TAB_TYPE;
344 BEGIN
345 
346    IF (l_debug = 1) THEN
347       print_debug('Updating Repl status of delivery_detail :'||p_deliv_detail_id
348 		  ||' To Status :'||p_repl_status);
349    END IF;
350 
351    l_detail_info_tab.DELETE;
352    l_in_rec := NULL;
353 
354 
355    IF p_repl_status IS NOT NULL
356     AND p_repl_status <> FND_API.G_MISS_CHAR  THEN     --  Added for bug 16197390
357       -- call WSH to just update the replenishment status
358 
359       l_detail_info_tab(1).delivery_detail_id := p_deliv_detail_id;
360       l_detail_info_tab(1).replenishment_status := p_repl_status ;
361       l_in_rec.caller := 'WMS_REP';
362       l_in_rec.action_code := 'UPDATE';
363 
364       WSH_INTERFACE_EXT_GRP.Create_Update_Delivery_Detail
365 	(p_api_version_number  => 1.0,
366 	 p_init_msg_list       => fnd_api.g_false,
367 	 p_commit              => fnd_api.g_false,
368 	 x_return_status       => l_return_status,
369 	 x_msg_count           => l_msg_count,
370 	 x_msg_data            => l_msg_data,
371 	 p_detail_info_tab     => l_detail_info_tab,
372 	 p_in_rec              => l_in_rec,
373 	 x_out_rec             => l_out_rec
374 	 );
375 
376       IF (l_debug = 1) THEN
377 	 print_debug('Status after updating the Repl status '||l_return_status);
378       END IF;
379 
380       IF (l_return_status = FND_API.G_RET_STS_ERROR) THEN
381 	 IF (l_debug = 1) THEN
382 	    print_debug('Error returned from Create_Update_Delivery_Detail IN api update_wdd_repl_status');
383 	 END IF;
384 	 RAISE FND_API.G_EXC_ERROR;
385        ELSIF (l_return_status = FND_API.G_RET_STS_UNEXP_ERROR) THEN
386 	 IF (l_debug = 1) THEN
387 	    print_debug('Unexpected errror from Create_Update_Delivery_Detail IN api update_wdd_repl_status');
388 	 END IF;
389 	 RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
390       END IF;
391 
392     ELSE -- p_repl_status IS NULL
393 
394       -- This gets called from  INVTOTRL.pld->clear_replenishment_status() procedure.
395 
396       -- We need to explicitely backorder delivery detail
397       -- be calling api WSH_SHIP_CONFIRM_ACTIONS2.backorder
398 
399       -- While pick release process WSH does not backorder all those
400       -- delivery detail lines that can not be fulfilled at that time(once the INV
401       -- returns 'replenishment_status = 'R'). Rather WSH
402       -- marks wdd.replenishemnt_status = 'R' and released_status = 'B'.
403       -- This is just pseudo backorder. We actually need to backorder here explicitely.
404       IF (l_debug = 1) THEN
405 	 print_debug('Calling Shipping API to backorder related WDD lines');
406       END IF;
407       l_backorder_deliv_tab(1) := p_deliv_detail_id;
408       l_backorder_qty_tab(1)   := p_deliv_qty ;
409       /*  no of records in l_backorder_deliv_tab should be equal to
410           no of records in p_overpick_qtys 14014540*/
411       l_dummy_table(1) := NULL;  -- 14014540
412 
413       WSH_SHIP_CONFIRM_ACTIONS2.backorder
414 	(
415 	 p_detail_ids     => l_backorder_deliv_tab,
416 	 p_bo_qtys        => l_backorder_qty_tab,
417 	 p_req_qtys       => l_backorder_qty_tab,
418 	 p_bo_qtys2       => l_dummy_table,
419 	 p_overpick_qtys  => l_dummy_table,
420 	 p_overpick_qtys2 => l_dummy_table,
421 	 p_bo_mode        => 'UNRESERVE',
422 	 p_bo_source      => 'PICK',
423 	 x_out_rows       => l_out_rows,
424 	 x_return_status  => l_return_status
425 	 );
426       IF (l_debug = 1) THEN
427 	 print_debug('WSH_SHIP_CONFIRM_ACTIONS2.backorder returned STATUS :'||l_return_status);
428       END IF;
429 
430    END IF;
431 
432    x_return_status :=  l_return_status ;
433 
434 EXCEPTION
435    WHEN OTHERS THEN
436       IF l_debug = 1 THEN
437 	 print_debug('Error update_wdd_repl_status: ' || sqlcode || ',' || sqlerrm);
438       END IF;
439       x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
440 
441 END update_wdd_repl_status;
442 
443 
444 
445 
446 PROCEDURE Revert_ALL_WDD_dynamic_repl (p_org_id  IN NUMBER
447 				       , p_batch_id  IN NUMBER
448 				       , x_return_status            OUT    NOCOPY VARCHAR2
449 				       )
450   IS
451 
452 l_deliv_detail_id_tab num_tab;
453 
454 l_return_status VARCHAR2(1) := fnd_api.g_ret_sts_success;
455 l_detail_info_tab             WSH_INTERFACE_EXT_GRP.delivery_details_Attr_tbl_Type;
456 l_in_rec                      WSH_INTERFACE_EXT_GRP.detailInRecType;
457 l_out_rec                     WSH_INTERFACE_EXT_GRP.detailOutRecType;
458 l_debug number := NVL(FND_PROFILE.VALUE('INV_DEBUG_TRACE'),0);
459 
460 l_msg_count     NUMBER;
461 l_msg_data      VARCHAR2(1000);
462 
463 CURSOR c_rr_marked_wdd IS
464     SELECT delivery_detail_id
465       FROM wsh_delivery_details wdd
466       WHERE wdd.source_code = 'OE'
467       AND wdd.organization_id = p_org_id
468       AND wdd.requested_quantity > 0
469       -- excluding Replenishment Requested status
470       AND wdd.released_status in ('R', 'B') and wdd.replenishment_status = 'R'
471       -- there might not be reservation
472       AND NOT EXISTS
473       (select 1
474        from mtl_reservations mr
475        WHERE MR.DEMAND_SOURCE_LINE_ID = wdd.source_line_id
476        and MR.DEMAND_SOURCE_HEADER_ID =
477        inv_salesorder.get_salesorder_for_oeheader(wdd.source_header_id)
478        and MR.demand_source_type_id =
479        decode(wdd.source_document_type_id, 10, 8, 2)
480        and MR.SUBINVENTORY_CODE IS NOT NULL  --locator is not needed,
481        )-- Exclude detailed RSV
482 	 AND NOT EXISTS
483 	 (select wrd.demand_line_detail_id
484 	  from WMS_REPLENISHMENT_DETAILS wrd
485 	  where wrd.demand_line_detail_id = wdd.delivery_detail_id
486 	  and wrd.demand_line_id = wdd.source_line_id
487 	  and wrd.organization_id = wdd.organization_id
488 	  AND wrd.organization_id = p_org_id)
489 	 AND wdd.batch_id = p_batch_id;
490 
491 BEGIN
492 
493    IF (l_debug = 1) THEN
494       print_debug('Inside API Revert_ALL_WDD_dynamic_repl ....');
495    END IF;
496 
497  BEGIN
498 
499     OPEN c_rr_marked_wdd;
500     FETCH c_rr_marked_wdd BULK COLLECT INTO l_deliv_detail_id_tab;
501     CLOSE c_rr_marked_wdd;
502 
503  EXCEPTION
504     WHEN OTHERS THEN
505 	 IF (l_debug = 1) THEN
506 	    print_debug('Exception retrieving item repl records for Dynamic');
507 	 END IF;
508 	 l_return_status := fnd_api.g_ret_sts_error;
509 	 RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
510  END;
511 
512  l_detail_info_tab.DELETE;
513  IF (l_deliv_detail_id_tab.count>0) THEN --bug#10185153
514 	 FOR i IN  l_deliv_detail_id_tab.FIRST..l_deliv_detail_id_tab.LAST LOOP
515 		l_detail_info_tab(i).delivery_detail_id := l_deliv_detail_id_tab(i);
516 		-- mark the demand lines for FND_API.g_miss_char  replenishment status
517 		l_detail_info_tab(i).replenishment_status := FND_API.g_miss_char;
518 
519 	 END LOOP;
520  END IF;
521 
522  IF (l_debug = 1) THEN
523     print_debug('REVERT ALL DEMAND DETAIL STATUS to original release status');
524  END IF;
525 
526  l_in_rec := NULL;
527  l_in_rec.caller := 'WMS_REP';
528  l_in_rec.action_code := 'UPDATE';
529 
530  WSH_INTERFACE_EXT_GRP.Create_Update_Delivery_Detail
531      (p_api_version_number  => 1.0,
532       p_init_msg_list       => fnd_api.g_false,
533       p_commit              => fnd_api.g_false,
534       x_return_status       => l_return_status,
535       x_msg_count           => l_msg_count,
536       x_msg_data            => l_msg_data,
537       p_detail_info_tab     => l_detail_info_tab,
538       p_in_rec              => l_in_rec,
539       x_out_rec             => l_out_rec
540       );
541 
542    IF (l_debug = 1) THEN
543       print_debug('AFTER Changing the line status to original release status');
544    END IF;
545 
546    IF (l_return_status = FND_API.G_RET_STS_ERROR) THEN
547       IF (l_debug = 1) THEN
548 	 print_debug('Error returned from Create_Update_Delivery_Detail IN api Revert_ALL_WDD_dynamic_repl');
549       END IF;
550       RAISE FND_API.G_EXC_ERROR;
551     ELSIF (l_return_status = FND_API.G_RET_STS_UNEXP_ERROR) THEN
552       IF (l_debug = 1) THEN
553 	 print_debug('Unexpected errror from Create_Update_Delivery_Detail api IN Revert_ALL_WDD_dynamic_repl');
554       END IF;
555       RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
556    END IF;
557 
558    x_return_status :=  l_return_status ;
559 
560 EXCEPTION
561    WHEN OTHERS THEN
562       IF l_debug = 1 THEN
563 	 print_debug('Error In Revert_ALL_WDD_dynamic_repl: ' || sqlcode || ',' || sqlerrm);
564       END IF;
565       x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
566 END revert_all_wdd_dynamic_repl;
567 
568 
569 PROCEDURE Revert_Consol_item_changes ( p_repl_type   IN NUMBER
570 				       , p_demand_type_id IN NUMBER
571 				       , P_item_id       IN NUMBER
572 				       , p_org_id       IN NUMBER
573 				       , x_return_status            OUT    NOCOPY VARCHAR2
574 				      )
575   IS
576 
577      l_deliv_detail_id_tab num_tab;
578      l_debug number := NVL(FND_PROFILE.VALUE('INV_DEBUG_TRACE'),0);
579      l_detail_info_tab             WSH_INTERFACE_EXT_GRP.delivery_details_Attr_tbl_Type;
580      l_in_rec                      WSH_INTERFACE_EXT_GRP.detailInRecType;
581      l_out_rec                     WSH_INTERFACE_EXT_GRP.detailOutRecType;
582 
583      l_item_id NUMBER;
584      l_org_id NUMBER;
585 
586      l_msg_count NUMBER;
587      l_msg_data VARCHAR2(1000);
588 
589      l_return_status VARCHAR2(1) := fnd_api.g_ret_sts_success;
590 
591      CURSOR c_demand_for_items IS
592 	SELECT demand_line_detail_id
593 	  FROM wms_repl_demand_gtmp
594 	  WHERE inventory_item_id = p_item_id
595 	  AND ORGANIZATION_ID  = p_org_id
596 	  AND repl_level = 1
597 	  AND demand_type_id <> 4;
598 BEGIN
599 
600    IF (l_debug = 1) THEN
601       print_debug('Inside API Revert_Consol_item_changes .......');
602    END IF;
603 
604    -- if repl_type 2 and demand_type_id <> 4 then revert that WDD to original status
605    IF p_repl_type = g_dynamic_repl AND p_demand_type_id <> 4  THEN
606 
607       IF (l_debug = 1) THEN
608 	 print_debug('Reverting WDD status to original status for consol item');
609       END IF;
610 
611       BEGIN
612 
613 	 OPEN c_demand_for_items;
614 	 FETCH c_demand_for_items BULK COLLECT INTO l_deliv_detail_id_tab;
615 	 CLOSE c_demand_for_items;
616 
617       EXCEPTION
618 	 WHEN OTHERS THEN
619 	    IF (l_debug = 1) THEN
620 	       print_debug('Exception retrieving repl records for consol item');
621 	    END IF;
622 	    l_return_status := fnd_api.g_ret_sts_error;
623 	    RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
624       END;
625 
626       l_detail_info_tab.DELETE;
627 	  IF (l_deliv_detail_id_tab.count>0) THEN --bug#10185153
628 		  FOR i IN  l_deliv_detail_id_tab.FIRST..l_deliv_detail_id_tab.LAST LOOP
629 		 l_detail_info_tab(i).delivery_detail_id := l_deliv_detail_id_tab(i);
630 		 -- mark the demand lines for FND_API.g_miss_char replenishment status
631 		 l_detail_info_tab(i).replenishment_status := FND_API.g_miss_char;
632 		  END LOOP;
633 	  END IF;
634 
635       l_in_rec := NULL;
636       l_in_rec.caller := 'WMS_REP';
637       l_in_rec.action_code := 'UPDATE';
638 
639       WSH_INTERFACE_EXT_GRP.Create_Update_Delivery_Detail
640 	(p_api_version_number  => 1.0,
641 	 p_init_msg_list       => fnd_api.g_false,
642 	 p_commit              => fnd_api.g_false,
643 	 x_return_status       => l_return_status,
644 	 x_msg_count           => l_msg_count,
645 	 x_msg_data            => l_msg_data,
646 	 p_detail_info_tab     => l_detail_info_tab,
647 	 p_in_rec              => l_in_rec,
648 	 x_out_rec             => l_out_rec
649 	 );
650 
651       IF (l_debug = 1) THEN
652 	 print_debug('AFTER Changing the line status to original release status');
653       END IF;
654 
655       IF (l_return_status = FND_API.G_RET_STS_ERROR) THEN
656 	 IF (l_debug = 1) THEN
657 	    print_debug('Error returned from Create_Update_Delivery_Detail IN api revert_consol_item_changes');
658 	 END IF;
659 	 RAISE FND_API.G_EXC_ERROR;
660        ELSIF (l_return_status = FND_API.G_RET_STS_UNEXP_ERROR) THEN
661 	 IF (l_debug = 1) THEN
662 	    print_debug('Unexpected errror from	Create_Update_Delivery_Detail api IN revert_consol_item_changes');
663 	 END IF;
664 	 RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
665       END IF;
666 
667    END IF; -- for IF p_repl_type = g_dynamic_repl AND p_demand_type_id <> 4
668 
669 
670    -- remove all entries for that item from gtmp
671    DELETE FROM  wms_repl_demand_gtmp
672      WHERE inventory_item_id = p_item_id
673      AND ORGANIZATION_ID  = p_org_id;
674 
675     x_return_status :=  l_return_status ;
676 
677 EXCEPTION
678    WHEN OTHERS THEN
679       IF l_debug = 1 THEN
680 	 print_debug('Error in Revert_Consol_item_changes: ' || sqlcode || ',' || sqlerrm);
681       END IF;
682       x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
683 END revert_consol_item_changes;
684 
685 
686 
687 
688 PROCEDURE Backorder_wdd_for_repl( x_return_status            OUT    NOCOPY VARCHAR2
689 				)
690   IS
691  l_return_status VARCHAR2(1) := fnd_api.g_ret_sts_success;
692  l_debug number := NVL(FND_PROFILE.VALUE('INV_DEBUG_TRACE'),0);
693  l_out_rows             WSH_UTIL_CORE.ID_TAB_TYPE;
694 BEGIN
695 
696    IF (l_debug = 1)  THEN
697       print_debug( 'Calling Shipping API to backorder all unment demand lines during Replenishment');
698    END IF;
699    -- Bulk processing of records here
700    --these demand lines need fresh backordering
701 
702      WSH_SHIP_CONFIRM_ACTIONS2.backorder
703      (
704       p_detail_ids     => G_backorder_deliv_tab,
705       p_bo_qtys        => G_backorder_qty_tab,
706       p_req_qtys       => G_backorder_qty_tab,
707       p_bo_qtys2       => G_dummy_table,
708       p_overpick_qtys  => G_dummy_table,
709       p_overpick_qtys2 => G_dummy_table,
710       p_bo_mode        => 'UNRESERVE',
711       p_bo_source      => 'PICK',
712       x_out_rows       => l_out_rows,
713       x_return_status  => l_return_status
714       );
715 
716    IF (l_debug = 1)  THEN
717       print_debug( 'After call to Backorder API Return Status :'||l_return_status);
718    END IF;
719 
720    IF l_return_status <> fnd_api.g_ret_sts_success THEN
721       RAISE fnd_api.g_exc_unexpected_error;
722    END IF;
723 
724    --Delete all entries in the pl/sql table
725    G_backorder_deliv_tab.DELETE;
726    G_backorder_qty_tab.DELETE;
727    G_dummy_table.DELETE;
728 
729     x_return_status :=  l_return_status;
730 EXCEPTION
731    WHEN OTHERS THEN
732       IF l_debug = 1 THEN
733 	 print_debug('Error in Backorder_wdd_for_repl: ' || sqlcode || ',' || sqlerrm);
734       END IF;
735       --Delete all entries in the pl/sql table
736       G_backorder_deliv_tab.DELETE;
737       G_backorder_qty_tab.DELETE;
738       G_dummy_table.DELETE;
739       x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
740 END Backorder_wdd_for_repl ;
741 
742 
743 
744 
745 PROCEDURE ADJUST_ATR_FOR_ITEM  (p_repl_level  IN NUMBER
746 				, p_repl_type IN NUMBER
747 				, x_consol_item_repl_tbl IN OUT NOCOPY CONSOL_ITEM_REPL_TBL
748 				, x_return_status            OUT    NOCOPY VARCHAR2
749 				)
750   IS
751 
752 
753      l_qoh NUMBER;
754      l_rqoh NUMBER;
755      l_qr   NUMBER;
756      l_qs NUMBER;
757      l_att NUMBER;
758      l_atr NUMBER;
759      l_msg_count     NUMBER;
760      l_msg_data      VARCHAR2(1000);
761      l_debug number := NVL(FND_PROFILE.VALUE('INV_DEBUG_TRACE'),0);
762 
763      l_is_revision_ctrl BOOLEAN;
764      l_is_lot_ctrl BOOLEAN;
765      l_is_serial_ctrl BOOLEAN;
766 
767      l_open_mo_qty NUMBER;
768      l_item_id NUMBER;
769      l_org_id NUMBER;
770      l_demand_line_detail_id NUMBER;
771      l_quantity   NUMBER;
772      l_uom_code VARCHAR2(3);
773      l_prim_repl_qty NUMBER;
774      l_released_status VARCHAR2(1);
775      cnt NUMBER;
776 	 l_cnt NUMBER; --BUG10149131/BUG10131943
777      l_qty_in_repl_uom NUMBER;
778      l_REPL_UOM_CODE  VARCHAR2(3);
779 
780      l_demand_header_id NUMBER;
781      l_demand_line_id NUMBER;
782      l_demand_type_id  NUMBER;
783      l_new_qty_in_repl_uom NUMBER;
784 
785      l_expected_ship_date DATE;
786      l_repl_to_subinventory_code VARCHAR2(10);
787      l_repl_status VARCHAR2(1);
788 
789      l_in_rec                      WSH_INTERFACE_EXT_GRP.detailInRecType;
790      l_out_rec                     WSH_INTERFACE_EXT_GRP.detailOutRecType;
791 
792      l_detail_id_tab               WSH_UTIL_CORE.id_tab_type;
793      l_action_prms                 WSH_GLBL_VAR_STRCT_GRP.dd_action_parameters_rec_type;
794      l_action_out_rec              WSH_GLBL_VAR_STRCT_GRP.dd_action_out_rec_type;
795 
796      l_return_status VARCHAR2(1) := fnd_api.g_ret_sts_success;
797      l_split_wdd_id NUMBER;
798 
799      l_dyn_bkord_dd_id_tab num_tab;
800 
801      l_psh_cnt NUMBER;
802      l_push_bkord_dd_id_tab num_tab;
803      l_rsvd_demand_qty NUMBER;
804      l_gtmp_demand_qty NUMBER;
805      l_rsv_accounted_qty NUMBER;
806      l_other_wdd_qty NUMBER;
807      l_temp_value NUMBER;
808      l_rsvd_demand_line_qty NUMBER; --BUG14504260
809 
810      CURSOR c_item_demand_lines IS
811 	SELECT  demand_header_id,
812 	  demand_line_id,
813 	  demand_line_detail_id,
814 	  demand_type_id,
815 	  Quantity,
816 	  Uom_code,
817 	  quantity_in_repl_uom,
818 	  REPL_UOM_code,
819 	  Expected_ship_date,
820 	  Repl_To_Subinventory_code,
821 	  repl_status,
822 	  RELEASED_STATUS
823 	  FROM wms_repl_demand_gtmp
824 	  WHERE inventory_item_id = l_item_id
825 	  AND organization_id = l_org_id
826 	  AND repl_level = P_REPL_LEVEL
827 	  ORDER BY repl_sequence_id;
828 
829   BEGIN
830 
831      IF (l_debug = 1)  THEN
832 	print_debug('Inside API ADJUST_atr_for_item.....');
833      END IF ;
834 
835 	 cnt := g_backorder_deliv_tab.count; --BUG10149131/BUG13491877 this is to store counter for global variable to store all WDD's to be backordered. initialise.
836 
837 
838 	 IF (x_consol_item_repl_tbl.count>0) THEN --bug#10185153
839      FOR i IN x_consol_item_repl_tbl.FIRST.. x_consol_item_repl_tbl.LAST LOOP
840 
841 	l_item_id := x_consol_item_repl_tbl(i).item_id;
842 	l_org_id := x_consol_item_repl_tbl(i).organization_id;
843 
844 	-- Get all item details
845 	IF inv_cache.set_item_rec(L_ORG_ID, L_item_id)  THEN
846 
847 	   IF inv_cache.item_rec.revision_qty_control_code = 2 THEN
848 	      l_is_revision_ctrl := TRUE;
849 	    ELSE
850 	      l_is_revision_ctrl := FALSE;
851 	   END IF;
852 
853 	   IF inv_cache.item_rec.lot_control_code = 2 THEN
854 	      l_is_lot_ctrl := TRUE;
855 	    ELSE
856 	      l_is_lot_ctrl := FALSE;
857 	   END IF;
858 
859 	   IF inv_cache.item_rec.serial_number_control_code NOT IN (1,6) THEN
860 	      l_is_serial_ctrl := FALSE;
861 	    ELSE
862 	      l_is_serial_ctrl := TRUE;
863 	   END IF;
864 
865 	 ELSE
866 
867 	   IF (l_debug = 1)  THEN
868 	      print_debug('Error: Item detail not found');
869 	   END IF ;
870 
871 	   RAISE no_data_found;
872 	END IF; -- for inv_cache.set_item_rec
873 
874 
875 	--uom conversio would already be defined, otherwise it will not come here
876 	-- get the final repl qty in the primary UOM
877 	l_prim_repl_qty :=
878 	  ROUND((x_consol_item_repl_tbl(i).total_demand_qty * get_conversion_rate(l_Item_id,
879 								x_consol_item_repl_tbl(i).repl_uom_code,
880 										  inv_cache.item_rec.primary_uom_code
881 										  )),
882 		g_conversion_precision);
883 
884 
885 	IF (l_debug = 1)  THEN
886 	   print_debug('Processing for Item :'||l_item_id||
887 		       ' Total Primary Dmd Qty :'||l_prim_repl_qty);
888 	END IF ;
889 
890 	--Query Quantity Tree
891 	inv_quantity_tree_pub.clear_quantity_cache;
892 
893 	-- Check value passed in this call to QTY Tree
894 	inv_quantity_tree_pub.query_quantities
895 	  (
896 	   p_api_version_number           => 1.0
897 	   , p_init_msg_lst               => fnd_api.g_false
898 	   , x_return_status              => l_return_status
899 	   , x_msg_count                  => l_msg_count
900 	   , x_msg_data                   => l_msg_data
901 	   , p_organization_id            => L_ORG_ID
902 	   , p_inventory_item_id          => L_item_id
903 	   , p_tree_mode                  => inv_quantity_tree_pub.g_transaction_mode
904 	   , p_is_revision_control        => l_is_revision_ctrl
905 	   , p_is_lot_control             => l_is_lot_ctrl
906 	   , p_is_serial_control        => l_is_serial_ctrl
907 	   , p_demand_source_type_id    => -9999 --should not be null
908 	   , p_demand_source_header_id  => -9999 --should not be null
909 	   , p_demand_source_line_id    => -9999
910 	   , p_revision                      => NULL
911 	   , p_lot_number                 => NULL
912 	   , p_subinventory_code          => NULL
913 	   , p_locator_id                 => NULL
914 	   , p_lot_expiration_date 		  => sysdate	--bug#10185153
915 	   , x_qoh                        => l_qoh
916 	   , x_rqoh                       => l_rqoh
917 	  , x_qr                         => l_qr
918 	  , x_qs                         => l_qs
919 	  , x_att                        => l_att
920 	  , x_atr                        => l_atr
921 	  );
922 
923 	IF (l_debug = 1)  THEN
924 	   print_debug( 'Return status from QTY TREE:' ||l_return_status);
925 	   print_debug( '>>>> From Qrt Tree, Org Level atr for Item :'||L_item_id||' is : '||l_atr);
926 	END IF;
927 
928 	IF l_return_status <> fnd_api.g_ret_sts_success THEN
929 	   l_atr := 0;
930 	END IF;
931 
932 	----------------------
933 	-- Since Qty Tree would have also subttracted qty for current demand
934 	-- lines under consideration for which there is existing
935 	-- reservation as well, I need to add them back
936 	-- to see real picture of the atr for demand line under consideration
937 
938 	------------------
939 	-- Note: one SO demand line can have multiple delivery_details
940 	-- Reservation is made at the SO line level and WRDG is at the
941 	-- delivery_detail level
942 
943 	-- Steps:
944 	-- 1-Get all the RSV qty for the item+org for ONLY those SO lines
945 	-- that are part OF GTMP table= Q1
946 	-- 2-Get the SUM OF qty in the GTMP for item+org combination  = Q2
947         -- Q3 - represents, For a specific item+Org, SUM OF qty for ALL wdds that are :
948 	-- 1- Part of same SO line whose wdds in the GTMP table
949 	-- 2- Excludes Wdds in the GTMP table
950 	-- 3- WDD.released_status not in (R,N,B,X,C) or already RR
951 
952 	--R- Ready to Release
953 	--N- Not ready to Release
954 	--B- Backordered
955 	--X- Not applicable
956 	--C- Shipped
957 	--S- Released to Warehouse
958 	--Y- Staged
959 
960 
961 	-- On the so line that can be possible candidate to contribute to reduction OF ATR
962 
963 	-- Qty that would already have been accounted for in the qty
964 	-- tree = MIN(MAX((Q1-Q3), 0),Q2)
965 
966 	------------------------
967 
968 	-- Get Q1
969 	-- 13806919 Changed the query(Q1) to get only distinct records from WRDG
970 	-- Also changed mr.reservations_quantity to mr.primary_reservation_quantity
971 	-- as Q2 and Q3 values are fetched in primary UOM
972 
973 	SELECT NVL(SUM(mr.primary_reservation_quantity),0)
974 	INTO l_rsvd_demand_qty
975 	FROM mtl_reservations mr ,
976 	     (select  distinct organization_id, inventory_item_id,
977 			  demand_line_id, demand_header_id
978 		   from WMS_REPL_DEMAND_GTMP
979 		   where inventory_item_id = l_item_id
980 		   and  organization_id = l_org_id
981 		   and demand_type_id <> 4
982 		   and repl_level = nvl(p_repl_level,1)) wrdg_v
983 	WHERE mr.organization_id       = wrdg_v.organization_id
984 	AND mr.inventory_item_id       = wrdg_v.inventory_item_id
985 	AND MR.DEMAND_SOURCE_LINE_ID   = wrdg_v.DEMAND_line_ID
986 	AND MR.DEMAND_SOURCE_HEADER_ID = wrdg_v.DEMAND_HEADER_ID;
987 
988 
989 	-- Get Q2
990 	SELECT Nvl(sum(wrdg.QUANTITY),0) INTO l_gtmp_demand_qty
991 	  from WMS_REPL_DEMAND_GTMP WRDG
992 	  WHERE  Wrdg.INVENTORY_ITEM_ID = l_item_id
993 	  and wrdg.ORGANIZATION_ID = L_ORG_ID
994 	  and wrdg.demand_type_id <> 4
995 	  and wrdg.repl_level = nvl(p_repl_level, 1);
996 
997 	-- Get Q3
998 	SELECT  Nvl(SUM(wdd.requested_quantity),0) INTO l_other_wdd_qty
999 	  FROM wsh_delivery_details wdd
1000 	  WHERE wdd.organization_id = l_org_id
1001 	  AND wdd.inventory_item_id = l_item_id
1002 	  AND((wdd.released_status NOT IN ('R','N','B','X','C') AND wdd.replenishment_status IS NULL)
1003 	      OR (wdd.released_status = 'B' AND wdd.replenishment_status IS NOT NULL))
1004 	  AND NOT EXISTS
1005 		(SELECT 1
1006 		 FROM wms_repl_demand_gtmp wrdg
1007 		 WHERE wrdg.organization_id = wdd.organization_id
1008 		 AND wrdg.inventory_item_id = wdd.inventory_item_id
1009 		 AND wrdg.demand_line_detail_id = wdd.delivery_detail_id
1010 		 AND wrdg.demand_header_id = inv_salesorder.get_salesorder_for_oeheader(wdd.source_header_id)
1011 		 AND wrdg.demand_line_id = wdd.source_line_id
1012 		 )
1013 	  AND inv_salesorder.get_salesorder_for_oeheader(wdd.source_header_id) IN
1014 		(
1015 		 SELECT DISTINCT demand_header_id FROM wms_repl_demand_gtmp wrdg1
1016 		 WHERE WRDG1.organization_id = l_org_id
1017 		 AND WRDG1.inventory_item_id = l_item_id
1018 		 );
1019 
1020 
1021 	IF (l_debug = 1)  THEN
1022 	   print_debug( ' l_rsvd_demand_qty:'||l_rsvd_demand_qty);
1023 	   print_debug( ' l_gtmp_demand_qty:'||l_gtmp_demand_qty);
1024 	   print_debug( ' l_other_wdd_qty  :'||l_other_wdd_qty);
1025 
1026 	END IF;
1027 
1028 	--l_rsv_accounted_qty = MIN(MAX((Q1-Q3), 0),Q2)
1029 	--l_rsv_accounted_qty :=  MIN(MAX((l_rsvd_demand_qty-l_other_wdd_qty ), 0),l_gtmp_demand_qty) ;
1030 
1031 
1032 	IF (l_rsvd_demand_qty-l_other_wdd_qty ) >= 0 THEN
1033 	   l_temp_value := (l_rsvd_demand_qty-l_other_wdd_qty );
1034 	 ELSE
1035 	   l_temp_value := 0;
1036 	END IF;
1037 
1038 
1039 	IF l_temp_value >= l_gtmp_demand_qty THEN
1040 	   l_rsv_accounted_qty :=l_gtmp_demand_qty;
1041 	 ELSE
1042 	   l_rsv_accounted_qty :=l_temp_value;
1043 	END IF;
1044 
1045 
1046 	IF (l_debug = 1)  THEN
1047 	   print_debug( 'Already Rsvd QTY AT ORG for demand lines for current item :'||l_rsv_accounted_qty);
1048 	END IF;
1049 
1050 
1051 	-- Adjust the l_atr with "EFFECTIVE QTY" on open MO whose source_sub is
1052 	-- sub under consideration. These MO should NOT be part of WRD becs
1053 	-- those part of WRD would already have been accounted in the RSV
1054 	-- Problematic are those for which MO is created but not allocated and
1055 	-- NOT tracked IN wrd AND whose source sub is Current Sub under consideration
1056 	-- So any untracked repl MO that is going out of the current sub should
1057 	-- be subtracted FROM l_org_atr for item for the reason of directionality (Pallet > CASE > Each)
1058 	-- becs material move from higher configuration to lower configuration
1059 	-- "EFFECTIVE QTY" = (mtrl.quantity - (Nvl(mtrl.quantity_detailed,0) + Nvl(mtrl.quantity_delivered,0)))
1060 
1061        BEGIN
1062 	  SELECT  SUM((mtrl.quantity - (Nvl(mtrl.quantity_detailed,0) +
1063 					Nvl(mtrl.quantity_delivered,0))))  INTO l_open_mo_qty
1064 	    FROM mtl_txn_request_lines mtrl,
1065 	    Mtl_txn_request_headers mtrh
1066 	    WHERE  mtrl.header_id = mtrh.header_id
1067 	    AND mtrl.organization_id = mtrh.organization_id
1068 	    AND mtrl.organization_id   = L_ORG_ID
1069 	    AND mtrl.inventory_item_id = L_item_id
1070 	    AND mtrl.organization_id in (select organization_id from mtl_parameters where wms_enabled_flag = 'Y')
1071 	    AND MTRH.move_order_type = 2
1072 	    and mtrl.line_status in (3,7) -- only approved and pre-approved
1073 	    and mtrl.transaction_type_id = 64
1074 	    and mtrl.transaction_source_type_id = 4
1075 	    and mtrl.from_SUBINVENTORY_CODE = x_consol_item_repl_tbl(i).repl_to_subinventory_code
1076 	    GROUP BY mtrl.inventory_item_id;
1077        EXCEPTION
1078 	  WHEN no_data_found THEN
1079 	     l_open_mo_qty := 0;
1080        END;
1081 
1082        l_atr := l_atr + Nvl(l_rsv_accounted_qty,0) - Nvl(l_open_mo_qty,0);
1083 
1084        IF (l_debug = 1)  THEN
1085 	  print_debug( 'Total effective qty for Untracked repl MO going out of FP Sub:' ||l_open_mo_qty);
1086 	  print_debug( 'Final Org Level Effective ATR for Item in GTMP table:'||l_atr);
1087        END IF;
1088 
1089        --========================================
1090        -- Now perform these 3 things.
1091        --1- Do calculation about qty
1092        --2- Remove unmet entery from the GTMP table
1093        --3- For the Item, Adjust the QTY in the CONSOLIDATED TABLE
1094        --4- Backorder the unmet demand line qty
1095        --========================================
1096 
1097        --1- Do calculation about qty
1098        IF l_atr > l_prim_repl_qty THEN
1099 	  -- do nothing
1100 	  --CONTINUE;
1101 	  GOTO skip_item;
1102 
1103 	ELSE -- L_ATR IS NOT GOOD ENOUGH to handle all demands
1104 	  l_prim_repl_qty := 0; -- Reset AND re-add in loop for each item
1105 	  l_psh_cnt := 0;
1106 	  l_cnt := 0; --BUG10149131/BUG10131943
1107 	--  l_dyn_bkord_dd_id_tab.DELETE;
1108 	--  l_push_bkord_dd_id_tab.DELETE;
1109 
1110       --We will reduce this and later we will add the demand line specific reserved qty.
1111 	  l_atr := l_atr - Nvl(l_rsv_accounted_qty,0) ; --BUG14504260
1112 
1113 
1114 	  OPEN c_item_demand_lines;
1115 	  LOOP
1116 	     FETCH c_item_demand_lines INTO   l_demand_header_id,
1117 	       l_demand_line_id,
1118 	       l_demand_line_detail_id,
1119 	       l_demand_type_id,
1120 	       l_Quantity,
1121 	       l_Uom_code,
1122 	       l_qty_in_repl_uom,
1123 	       l_REPL_UOM_code,
1124 	       l_Expected_ship_date,
1125 	       l_Repl_To_Subinventory_code,
1126 	       l_repl_status,
1127 	       l_released_status;
1128 
1129 	     EXIT WHEN c_item_demand_lines%notfound;
1130 
1131        SELECT NVL(SUM(mr.primary_reservation_quantity),0)
1132 			INTO l_rsvd_demand_line_qty
1133 			FROM mtl_reservations mr
1134 			WHERE mr.organization_id       =l_org_id
1135 			AND mr.inventory_item_id       =l_item_id
1136 			AND MR.DEMAND_SOURCE_LINE_ID   =  l_demand_line_id
1137 			AND MR.DEMAND_SOURCE_HEADER_ID = l_demand_header_id;
1138 
1139 		 l_atr  :=  l_atr  + l_rsvd_demand_line_qty  ; --BUG14504260
1140 
1141 		IF (l_debug = 1)  THEN
1142 		    print_debug( 'l_atr after considering current order demand'||l_atr);
1143 		END IF;
1144 
1145 	     IF l_atr >= l_quantity THEN
1146 		-- once l_atr becomes negative it will always reamin negative
1147 		-- and code will always go TO the ELSE section afterwards
1148 		-- Final primary qty will be set here for this item
1149 		l_atr := l_atr - l_quantity;
1150 		l_prim_repl_qty := l_prim_repl_qty +l_quantity;
1151 
1152 	      ELSE  -- means l_atr < l_quantity; remaining l_atr is not enough for l_quantity
1153 
1154 		IF l_atr <> 0  THEN -- so that it does not call to split again FOR an item
1155 		   IF (l_debug = 1)  THEN
1156 		      print_debug( 'Remaining l_atr is not enough for CURRENT demand line,....splitting the WDD ');
1157 		   END IF;
1158 
1159 		   -- 1-Call Shipping API to split the WDD with (l_quantity - l_atr)
1160 		   -- Shipping will update current WDD with qty = l_atr
1161 		   -- and create a new WDD with qty = (l_quantity - l_atr)
1162 
1163 		   -- 2-Split the Qty in the GTMP :UPDATE current demand RECORD with qty = l_atr
1164 		   -- We do NOT need to insert the new record in GTMP with qty = (l_quantity - l_atr)
1165 		   -- since we are going to delete downstream from GTMP for ALL unmet demand lines
1166 
1167 		   -- -3-Adjust 	l_prim_repl_qty := l_prim_repl_qty +l_atr;
1168 		   -- -4- Set l_atr = 0
1169 
1170 		   l_detail_id_tab.DELETE;
1171 		   l_action_prms := NULL;
1172 		   l_detail_id_tab(1) := l_demand_line_detail_id;
1173 		   -- Caller needs to be WSH_PUB in order for shipping to allow this action
1174 		   l_action_prms.caller := 'WSH_PUB';
1175 		   l_action_prms.action_code := 'SPLIT-LINE';
1176 		   l_action_prms.split_quantity := (l_quantity - l_atr);
1177 
1178 		   WSH_INTERFACE_GRP.Delivery_Detail_Action
1179 		     (p_api_version_number  => 1.0,
1180 		      p_init_msg_list       => fnd_api.g_false,
1181 		      p_commit              => fnd_api.g_false,
1182 		      x_return_status       => l_return_status,
1183 		      x_msg_count           => l_msg_count,
1184 		      x_msg_data            => l_msg_data,
1185 		      p_detail_id_tab       => l_detail_id_tab,
1186 		      p_action_prms         => l_action_prms,
1187 		      x_action_out_rec      => l_action_out_rec
1188 		      );
1189 
1190 		   IF (l_return_status = FND_API.G_RET_STS_ERROR) THEN
1191 		      IF (l_debug = 1) THEN
1192 			 print_debug( 'Error returned from Split ADJUST_ATR_FOR_ITEM API..skip this demand');
1193 		      END IF;
1194 		      -- skip this demand line
1195 		      GOTO  next_dmd_rec;
1196 		    ELSIF (l_return_status = FND_API.G_RET_STS_UNEXP_ERROR) THEN
1197 		      IF (l_debug = 1) THEN
1198 			 print_debug( 'Unexpected errror from Split ADJUST_ATR_FOR_ITEM API..skip this demand');
1199 		      END IF;
1200 		      -- skip this demand line
1201 		      GOTO  next_dmd_rec;
1202 		   END IF;
1203 
1204 		   l_split_wdd_id := l_action_out_rec.result_id_tab(l_action_out_rec.result_id_tab.FIRST);
1205 
1206 		   l_new_qty_in_repl_uom := ROUND((l_atr * get_conversion_rate(l_item_id,
1207 									       inv_cache.item_rec.primary_uom_code,
1208 									       x_consol_item_repl_tbl(i).repl_uom_code )), g_conversion_precision);
1209 
1210 		   -- update the qty in the existing GTMP record
1211 		   UPDATE wms_repl_demand_gtmp
1212 		     SET  QUANTITY   = l_atr,
1213 		     QUANTITY_IN_REPL_UOM  =  l_new_qty_in_repl_uom
1214 		     WHERE demand_line_detail_id = l_demand_line_detail_id;
1215 
1216 		   --reset program parameters for next loop
1217 		   l_prim_repl_qty := l_prim_repl_qty +l_atr;
1218 		   l_atr := 0;
1219 
1220 
1221 		   --Override l_demand_line_detail_id so that it gets added to
1222 		   -- the backorder list. released status of both dd_id is same
1223 		   l_demand_line_detail_id :=	l_split_wdd_id;
1224 		END IF; --for l_atr <> 0
1225 
1226 		-- the code will go in above split case only once to consume
1227 		-- all remaining available l_atr. Thereafter, it will only go to following section to add
1228 		-- lines to be backordered
1229 
1230 		-- add to the backorder table to backorder demand AND delete from GTMP
1231 		IF p_repl_type = g_push_repl THEN
1232 
1233 		   -- we can call the backorder API for WDD lines that are already backordered
1234 		   -- Now, Shipping team has made changes and it will honor
1235 		   -- consolidation of the backordered api feature
1236 		   -- it does NOT matter whether DD_id was alredy backordered
1237 
1238 		   l_cnt := l_cnt+1; --BUG10131943
1239 		   cnt := cnt+1;
1240 		   l_push_bkord_dd_id_tab(l_cnt) := l_demand_line_detail_id;  --BUG10131943
1241 
1242 		   g_backorder_deliv_tab(cnt):= l_demand_line_detail_id;
1243 		   g_backorder_qty_tab(cnt) := l_quantity;
1244 		   -- since we are backordering entire qty parameters
1245 		   -- p_bo_qtys AND  p_req_qtys will have same value
1246 		   g_dummy_table(cnt)       := 0;
1247 
1248 
1249 		 ELSIF p_repl_type = g_dynamic_repl THEN
1250 		   -- call the  backorder API to backorder the delivery_detail
1251 		   -- add the delivery_detail to the global variable
1252 		   -- it does NOT matter whether DD_id was already backordered
1253 		   l_cnt := l_cnt+1; --BUG10149131
1254 		   cnt := cnt+1;
1255 		   l_dyn_bkord_dd_id_tab(l_cnt) := l_demand_line_detail_id; --BUG10149131
1256 
1257 		   g_backorder_deliv_tab(cnt):= l_demand_line_detail_id;
1258 		   g_backorder_qty_tab(cnt) := l_quantity;
1259 		   -- since we are backordering entire qty parameters
1260 		   -- p_bo_qtys AND  p_req_qtys will have same value
1261 		   g_dummy_table(cnt)       := 0;
1262 
1263 		END IF;
1264 
1265 	     END IF; -- for IF l_atr >= l_quantity
1266 
1267 	     <<next_dmd_rec>>
1268 	       IF l_return_status <> 'S' THEN
1269 		  IF (l_debug = 1) THEN
1270 		     print_debug( 'Removing the demand from repl consideration :'||l_demand_line_detail_id);
1271 		  END IF;
1272 		  -- delete this demand line from the GTMP
1273 		  -- subtract the qty from the consol record
1274 		  DELETE FROM wms_repl_demand_gtmp
1275 		    WHERE demand_line_detail_id = l_demand_line_detail_id;
1276 
1277 		  -- we have not updated the qty l_prim_repl_qty yet
1278 		  -- so no need to update the consol qty for this item
1279 
1280 		  -- Add here to list of delivery_details to be backordered
1281 		  cnt := cnt+1;
1282 		  g_backorder_deliv_tab(cnt):= l_demand_line_detail_id;
1283 		  g_backorder_qty_tab(cnt) := l_quantity;
1284 		  -- since we are backordering entire qty parameters
1285 		  -- p_bo_qtys AND  p_req_qtys will have same value
1286 		  g_dummy_table(cnt)       := 0;
1287 
1288 	       END IF; --for IF l_return_status <> 'S'
1289 
1290 	  END LOOP;
1291 	  CLOSE c_item_demand_lines;
1292        END IF; -- for if l_atr > l_prim_repl_qty
1293 
1294        --2- Remove unmet entery from the GTMP table IN bulk
1295        IF p_repl_type = g_push_repl THEN
1296 	  IF (l_debug = 1) THEN
1297 	     print_debug( 'PUSH - NUMBER OF lines to be deleted :'||l_push_bkord_dd_id_tab.count);
1298 	  END IF;
1299 
1300 	  FORALL k IN 1 .. l_push_bkord_dd_id_tab.COUNT
1301 	    DELETE FROM wms_repl_demand_gtmp
1302 	    WHERE demand_line_detail_id = l_push_bkord_dd_id_tab(k)
1303 	    AND inventory_item_id = l_item_id
1304 	    AND organization_id = L_ORG_ID
1305 	    AND Nvl(repl_level,1) = p_repl_level;
1306 	ELSIF p_repl_type = g_dynamic_repl THEN
1307 	  IF (l_debug = 1) THEN
1308 	     print_debug( 'DYNAMIC - NUMBER OF lines to be deleted :'||l_dyn_bkord_dd_id_tab.count);
1309 	  END IF;
1310 
1311 	  IF (l_dyn_bkord_dd_id_tab.count>0) THEN
1312 		  FOR k IN l_dyn_bkord_dd_id_tab.FIRST .. l_dyn_bkord_dd_id_tab.LAST LOOP
1313 			  print_debug( 'AMO - value of K ' || k);
1314 			 print_debug( 'AMO Debug l_dyn_bkord_dd_id_tab place 1 '||l_dyn_bkord_dd_id_tab(k));
1315 
1316 		  END LOOP;
1317 	  END IF;
1318 
1319 	  IF (l_debug = 1) THEN
1320 	     print_debug( 'AMO Debug place 1.5 value i  '||i);
1321 	     print_debug( 'AMO Debug place 2 '||x_consol_item_repl_tbl(i).total_demand_qty );
1322 		 print_debug( 'AMO Debug place 3 '||x_consol_item_repl_tbl(i).repl_uom_code);
1323 	  END IF;
1324 
1325 
1326 	  FORALL k IN 1 .. l_dyn_bkord_dd_id_tab.COUNT
1327 	    DELETE FROM wms_repl_demand_gtmp
1328 	    WHERE demand_line_detail_id = l_dyn_bkord_dd_id_tab(k)
1329 	    AND inventory_item_id = l_item_id
1330 	    AND organization_id = L_ORG_ID
1331 	    AND Nvl(repl_level,1) = p_repl_level;
1332        END IF;
1333 
1334 
1335 	  IF (l_debug = 1) THEN
1336 	     print_debug( 'AMOaa Debug place 1.5 value i  '||i);
1337 	     print_debug( 'AMOaa Debug place 2 '||x_consol_item_repl_tbl(i).total_demand_qty );
1338 		 print_debug( 'AMOaa Debug place 3 '||x_consol_item_repl_tbl(i).repl_uom_code);
1339 	  END IF;
1340 
1341        --3- For the Item, Adjust the QTY in the CONSOLIDATED TABLE
1342        IF l_prim_repl_qty > 0 THEN
1343 	  x_consol_item_repl_tbl(i).total_demand_qty :=
1344 	    ROUND((l_prim_repl_qty * get_conversion_rate(l_item_id,
1345 							 inv_cache.item_rec.primary_uom_code,
1346 							 x_consol_item_repl_tbl(i).repl_uom_code
1347 							 )),
1348 		  g_conversion_precision);
1349 
1350 	  IF (l_debug = 1)  THEN
1351 	     print_debug( 'After all into account Final total dmd Qty :'||x_consol_item_repl_tbl(i).total_demand_qty);
1352 	     print_debug( 'In the UOM Code :'||x_consol_item_repl_tbl(i).repl_uom_code);
1353 	  END IF;
1354 
1355 	ELSE
1356 	    IF (l_debug = 1)  THEN
1357 	       print_debug( 'NO Qty available for this item in the ORG....removing FROM Replenishment Consideration');
1358 	    END IF;
1359 	    x_consol_item_repl_tbl.DELETE(i);
1360        END IF;
1361 
1362 
1363 
1364        --4- Backorder the unmet demand line qty
1365        -- We do not need to do anything here as we have already added those
1366        -- delivery_details IN the global TABLE that need TO be backordered
1367        -- we call an api  WSH_SHIP_CONFIRM_ACTIONS2.backorder()
1368        -- to backorder these delivery at the end of the
1369        -- replenishment process - be it push/stock-up OR pull/dynamic
1370 
1371        /* NOT needed
1372 
1373        IF p_repl_type = g_push_repl THEN
1374 	  NULL;
1375 	  -- To honor the consolidation of the backordered demand lines
1376 	  -- We need to call the WSH_SHIP_CONFIRM_ACTIONS2.backorder() API
1377 	  -- at the end of Push replenishment process. Above in the code,
1378 	  -- We have already stored the delivery_details_ids to be
1379 	  -- backordered IN the global pacakge variable -  g_backorder_deliv_tab
1380 
1381 	ELSIF p_repl_type = g_dynamic_repl THEN
1382 	  -- since line is already marked RR, just reverting the line status
1383 	  -- to its orignal status will make it Backorder
1384 	  -- Bulk processing of records here
1385 
1386 	  -- FOR dynamic repl,consolidation of the backordered demand lines
1387 	  -- works fine, even if we call in the middle of the dynamic repl
1388 	  -- only for the push repl, backorder API needs to be called at
1389 	  -- end of the push replenishment process.
1390 
1391 	  IF (l_debug = 1)  THEN
1392 	     print_debug( 'Calling Shipping API to revert to original status FOR unmet demand lines');
1393 	  END IF;
1394 	  l_in_rec := NULL;
1395 	  l_in_rec.caller := 'WMS_REP';
1396 	  l_in_rec.action_code := 'UPDATE';
1397 
1398 	  WSH_INTERFACE_EXT_GRP.Create_Update_Delivery_Detail
1399 	    (p_api_version_number  => 1.0,
1400 	     p_init_msg_list       => fnd_api.g_false,
1401 	     p_commit              => fnd_api.g_false,
1402 	     x_return_status       => l_return_status,
1403 	     x_msg_count           => l_msg_count,
1404 	     x_msg_data            => l_msg_data,
1405 	     p_detail_info_tab     => l_detail_info_tab,
1406 	     p_in_rec              => l_in_rec,
1407 	     x_out_rec             => l_out_rec
1408 	     );
1409 
1410 	  IF (l_debug = 1) THEN
1411 	     print_debug('AFTER Changing the line status to original release status');
1412 	  END IF;
1413 
1414 	  IF (l_return_status = FND_API.G_RET_STS_ERROR) THEN
1415 	     IF (l_debug = 1) THEN
1416 		print_debug('Error returned from Create_Update_Delivery_Detail IN api ADJUST_ATR_FOR_ITEM');
1417 	     END IF;
1418 	     RAISE FND_API.G_EXC_ERROR;
1419 	   ELSIF (l_return_status = FND_API.G_RET_STS_UNEXP_ERROR) THEN
1420 	     IF (l_debug = 1) THEN
1421 		print_debug('Unexpected errror from Create_Update_Delivery_Detail api IN ADJUST_ATR_FOR_ITEM');
1422 	     END IF;
1423 	     RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
1424 	  END IF;
1425 
1426 	 END IF;
1427 
1428 	 */
1429 	--AMO IFFCO --BUG10149131
1430 	l_dyn_bkord_dd_id_tab.DELETE;
1431 	l_push_bkord_dd_id_tab.DELETE;
1432 
1433 	<<skip_item>>
1434 	IF (l_debug = 1 and x_consol_item_repl_tbl.exists(i)) THEN  -- 13393465
1435 		print_debug('end consolidated item : '||x_consol_item_repl_tbl(i).item_id);
1436 	END IF;
1437 
1438      END LOOP; -- For each consolidated Items
1439 	 END IF;
1440 
1441    x_return_status := l_return_status;
1442 
1443   EXCEPTION
1444    WHEN OTHERS THEN
1445       IF (l_debug = 1)  THEN
1446 	 print_debug('Exception in ADJUST_atr_for_item: ' || sqlcode || ', ' || sqlerrm);
1447       END IF;
1448       x_return_status :=   FND_API.G_RET_STS_ERROR;
1449       -- calling API will rollback
1450 END ADJUST_atr_for_item;
1451 
1452 
1453 
1454 PROCEDURE PUSH_REPLENISHMENT(P_repl_level                IN NUMBER DEFAULT 1,
1455 			     p_Item_id                   IN NUMBER,
1456 			     p_organization_id           IN NUMBER,
1457 			     p_ABC_assignment_group_id   IN NUMBER, -- For ABC Compile Group
1458 			     p_abc_class_id              IN NUMBER, -- For Item Classification
1459 			     p_Order_Type_id             IN NUMBER,
1460 			     p_Carrier_id                IN NUMBER,
1461 			     p_customer_class            IN VARCHAR2,
1462 			     p_customer_id               IN NUMBER,
1463 			     p_Ship_Method_code          IN VARCHAR2,
1464 			     p_Scheduled_Ship_Date_To    IN NUMBER,
1465 			     p_Scheduled_Ship_Date_From  IN NUMBER,
1466 			     p_Forward_Pick_Sub          IN VARCHAR2,
1467 			     p_repl_UOM                  IN VARCHAR2,
1468 			     p_Repl_Lot_Size             IN NUMBER,
1469 			     p_Min_Order_lines_threshold IN NUMBER,
1470 			     p_Min_repl_qty_threshold    IN NUMBER,
1471 			     p_max_NUM_items_for_repl    IN NUMBER,
1472 			     p_Sort_Criteria             IN NUMBER,
1473 			     p_Auto_Allocate             IN VARCHAR2,
1474   p_Plan_Tasks                IN VARCHAR2,
1475   p_Release_Sequence_Rule_Id  IN NUMBER,
1476   p_Create_Reservation        IN VARCHAR2,
1477   x_return_status             OUT NOCOPY VARCHAR2,
1478   x_msg_count                 OUT NOCOPY NUMBER,
1479   x_msg_data                  OUT NOCOPY VARCHAR2)
1480   IS
1481 
1482      l_return_value BOOLEAN;
1483      l_debug              NUMBER      :=  NVL(fnd_profile.VALUE('INV_DEBUG_TRACE'), 0);
1484      l_consol_item_repl_tbl CONSOL_ITEM_REPL_TBL;
1485 
1486      l_return_status VARCHAR2(3) := fnd_api.g_ret_sts_success;
1487 BEGIN
1488    x_return_status := l_return_status;
1489 
1490    SAVEPOINT push_replenishment_sp;
1491 
1492    -- REPLENISHMENT_TYPE
1493    --  1 - PUSH REPLENISHMENT
1494    --  2 - DYNAMIC REPLENISHMENT
1495    -- Do validation on passed parameter values
1496 
1497    IF l_debug = 1 THEN
1498       print_debug('Printing Values inside PUSH_REPLENISHMENT');
1499       print_debug(' P_repl_level               :'|| p_repl_level);
1500       print_debug(' p_Item_id                  :'|| p_Item_id  );
1501       print_debug(' p_organization_id          :'||p_organization_id );
1502       print_debug(' p_ABC_assignment_group_id  :'||p_ABC_assignment_group_id );
1503       print_debug(' p_abc_class_id             :'|| p_abc_class_id );
1504       print_debug(' p_Order_Type_id            :'|| p_Order_Type_id );
1505       print_debug(' p_Carrier_id               :'||p_Carrier_id );
1506       print_debug(' p_customer_class           :'|| p_customer_class );
1507       print_debug(' p_customer_id              :'|| p_customer_id  );
1508       print_debug(' p_Ship_Method_code         :'|| p_Ship_Method_code );
1509       print_debug(' p_Scheduled_Ship_Date_To   :'|| p_Scheduled_Ship_Date_To );
1510       print_debug(' p_Scheduled_Ship_Date_From :'||p_Scheduled_Ship_Date_From );
1511       print_debug(' p_Forward_Pick_Sub         :'|| p_Forward_Pick_Sub    );
1512       print_debug(' p_repl_UOM                 :'|| p_repl_UOM   );
1513       print_debug(' p_Repl_Lot_Size            :'||  p_Repl_Lot_Size  );
1514       print_debug(' p_Min_Order_lines_threshold :'||p_Min_Order_lines_threshold);
1515       print_debug(' p_Min_repl_qty_threshold    :'||p_Min_repl_qty_threshold  );
1516       print_debug(' p_max_NUM_items_for_repl    :'||p_max_NUM_items_for_repl  );
1517       print_debug(' p_Sort_Criteria             :'|| p_Sort_Criteria  );
1518       print_debug(' p_Auto_Allocate             :'|| p_Auto_Allocate    );
1519       print_debug(' p_Plan_Tasks                :'|| p_Plan_Tasks    );
1520       print_debug(' p_Release_Sequence_Rule_Id  :'||p_Release_Sequence_Rule_Id);
1521       print_debug(' p_Create_Reservation        :'|| p_Create_Reservation  );
1522    END IF;
1523 
1524 
1525    IF (p_organization_id IS NULL
1526        OR p_Forward_Pick_Sub IS NULL
1527        OR p_repl_UOM IS NULL
1528        OR p_Sort_Criteria IS NULL  --Default is total demand quantity = 1 from UI
1529        OR p_Auto_Allocate IS NULL
1530        OR p_Plan_Tasks IS NULL
1531        OR (p_ABC_assignment_group_id IS NULL AND p_abc_class_id IS NOT NULL)) THEN
1532 
1533       IF l_debug = 1 THEN
1534 	 print_debug(' ERROR: VALIDATION FAILED !'  );
1535       END IF;
1536 
1537       x_return_status :=   FND_API.G_RET_STS_ERROR;
1538       x_msg_data  := 'Missing Required Information';
1539       RETURN;
1540 
1541    END IF;
1542 
1543    -- Initialize Global package tables
1544 
1545    l_consol_item_repl_tbl.DELETE;
1546 
1547    -- Initialize the global Item UOM conversion table
1548    g_item_uom_conversion_tb.DELETE;
1549 
1550    POPULATE_PUSH_REPL_DEMAND(p_repl_level                => p_repl_level,
1551 			     p_Item_id                   => p_Item_id,
1552 			     p_organization_id           => p_organization_id,
1553 			     p_ABC_assignment_group_id   => p_ABC_assignment_group_id,
1554 			     p_abc_class_id              => p_abc_class_id,
1555 			     p_Order_Type_id             => p_Order_Type_id,
1556 			     p_Carrier_id                => p_Carrier_id,
1557 			     p_customer_class            => p_customer_class,
1558 			     p_customer_id               => p_customer_id,
1559 			     p_Ship_Method_code          => p_Ship_Method_code,
1560 			     p_Scheduled_Ship_Date_To    => p_Scheduled_Ship_Date_To,
1561 			     p_Scheduled_Ship_Date_From  => p_Scheduled_Ship_Date_From,
1562 			     p_Forward_Pick_Sub          => p_Forward_Pick_Sub,
1563 			     p_repl_UOM                  => p_repl_UOM,
1564 			     p_Release_Sequence_Rule_Id  => p_Release_Sequence_Rule_Id,
1565 			     p_Min_Order_lines_threshold => p_Min_Order_lines_threshold,
1566 			     p_Min_repl_qty_threshold    => p_Min_repl_qty_threshold,
1567      p_max_NUM_items_for_repl    => p_max_NUM_items_for_repl,
1568      p_Sort_Criteria             => p_Sort_Criteria,
1569      x_consol_item_repl_tbl      => l_consol_item_repl_tbl,
1570      x_return_status             => l_return_status,
1571      x_msg_count                 => x_msg_count,
1572      x_msg_data                  => x_msg_data);
1573 
1574 
1575    IF l_RETURN_status = fnd_api.g_ret_sts_success THEN
1576       IF (l_debug = 1) THEN
1577 	 PRINT_DEBUG('Demand records populated successfully');
1578       END IF;
1579 
1580     ELSE
1581       l_consol_item_repl_tbl.DELETE;
1582       IF (l_debug = 1) THEN
1583 	 PRINT_DEBUG('Error from API POPULATE_PUSH_REPL_DEMAND');
1584       END IF;
1585       RAISE fnd_api.g_exc_unexpected_error;
1586    END IF;
1587 
1588 
1589    -- ==========TEST CODE starts ===========
1590    -- This code is for debugging purpose only, this code should be in
1591    -- l_debug = 1 only
1592    IF (l_debug = 1) THEN
1593       IF l_consol_item_repl_tbl.COUNT <> 0 THEN
1594 		 print_debug('*******AFTER GETTING DEMAND RECORDS******');
1595 		 FOR i IN l_consol_item_repl_tbl.FIRST .. l_consol_item_repl_tbl.LAST LOOP
1596 			IF (NOT l_consol_item_repl_tbl.exists(i)) THEN
1597 			   print_debug('RECORD has been deleted from consol table, Skipping it');
1598 			 ELSE
1599 			   print_debug('ITEM_ID = ' || l_consol_item_repl_tbl(i).ITEM_ID  || ' '
1600 				   || 'total_demand_qty = ' || l_consol_item_repl_tbl(i).total_demand_qty );
1601 
1602 			END IF;
1603 		 END LOOP;
1604       END IF;
1605    END IF;
1606    -- ==========TEST CODE ends ===========
1607 
1608 
1609 
1610    -- To populate the demand table - WMS_REPL_DEMAND_GTMP - Get values in l_consol_item_repl_tbl
1611    -- Cache information about relevant items
1612    -- Call the Extensibility API to see if there is a custom logic to get the consolidate demand lines per Item.
1613    --This API will appropriately populate l_consol_item_repl_tbl .
1614 
1615 
1616    IF (WMS_REPL_CUSTOM_APIS_PUB.g_is_api_implemented) THEN
1617       l_consol_item_repl_tbl.DELETE;
1618       WMS_REPL_CUSTOM_APIS_PUB.GET_CONSOL_REPL_DEMAND_CUST(x_return_status        => x_return_status,
1619 							   x_msg_count            => x_msg_count,
1620 							   x_msg_data             => x_msg_data,
1621 							   x_consol_item_repl_tbl => l_consol_item_repl_tbl);
1622 
1623    END IF; -- for API is implemented
1624 
1625 
1626    IF l_consol_item_repl_tbl.COUNT <> 0 THEN
1627 
1628       --Call the core replenishment processing API - PROCESS_REPLENISHMENT()
1629       PROCESS_REPLENISHMENT(P_repl_level           => P_repl_level,
1630 			    p_repl_type            => 1, --Push Replenishment
1631 			    p_Repl_Lot_Size        => p_Repl_Lot_Size,
1632 			    P_consol_item_repl_tbl => l_consol_item_repl_tbl,
1633 			    p_Create_Reservation   => p_Create_Reservation,
1634 			    p_Auto_Allocate        => p_Auto_Allocate,
1635 			    p_Plan_Tasks           => p_Plan_Tasks,
1636 			    x_return_status        => l_return_status,
1637 			    x_msg_count            => x_msg_count,
1638 			    x_msg_data             => x_msg_data);
1639 
1640       IF l_RETURN_status = fnd_api.g_ret_sts_success THEN
1641 	 IF (l_debug = 1) THEN
1642 	    PRINT_DEBUG('processed replenishment successfully');
1643 	 END IF;
1644 
1645        ELSE
1646 	 IF (l_debug = 1) THEN
1647 	    PRINT_DEBUG('Error from API process_replenishment');
1648 	 END IF;
1649 	 RAISE fnd_api.g_exc_unexpected_error;
1650       END IF;
1651     ELSE
1652       IF (l_debug = 1) THEN
1653 	 print_debug('No Demand Records Identified for Chosen Criteria..Exiting...');
1654       END IF;
1655       ROLLBACK TO push_replenishment_sp;
1656       -- RETURN; -- bug 7201888
1657    END IF;
1658 
1659    -- Call an API to backorder all demands lines that were stored to be backordered
1660    -- We do not fail the transaction even if the backordering fails
1661 
1662    IF (l_debug = 1) THEN
1663       print_debug( 'Number of WDDs to backorder :'||g_backorder_deliv_tab.COUNT());
1664    END IF;
1665 
1666    IF g_backorder_deliv_tab.COUNT() <> 0 THEN
1667       Backorder_wdd_for_repl( l_return_status );
1668       IF l_RETURN_status <> fnd_api.g_ret_sts_success THEN
1669 	 IF (l_debug = 1) THEN
1670 	    PRINT_DEBUG('Call to Backorder_wdd_for_repl API returned failure..DO NOTHING');
1671 	 END IF;
1672       END IF;
1673    END IF;
1674 
1675 
1676    COMMIT; -- commit entire transaction
1677    x_return_status := FND_API.g_ret_sts_success;
1678 
1679    IF (l_debug = 1) THEN
1680       PRINT_DEBUG('Done with the Push Replenishment');
1681    END IF;
1682 
1683 EXCEPTION
1684 
1685    WHEN OTHERS THEN
1686       ROLLBACK TO push_replenishment_sp;
1687       l_consol_item_repl_tbl.DELETE;
1688       g_item_uom_conversion_tb.DELETE;
1689       IF l_debug = 1 THEN
1690 	 print_debug('Error in PUSH_REPLENISHMENT: ' || sqlcode || ', ' || sqlerrm);
1691       END IF;
1692       x_return_status:= FND_API.g_ret_sts_error;
1693 
1694 END PUSH_REPLENISHMENT;
1695 
1696 
1697 PROCEDURE DYNAMIC_REPLENISHMENT(p_org_id IN NUMBER,
1698 				P_Batch_id                 IN NUMBER,
1699 				p_Plan_Tasks               IN VARCHAR2,
1700 				p_Release_Sequence_Rule_Id IN NUMBER,
1701 				P_repl_level               IN NUMBER DEFAULT 1,
1702 				x_msg_count                OUT NOCOPY NUMBER,
1703 				x_return_status            OUT NOCOPY VARCHAR2,
1704 				x_msg_data                 OUT NOCOPY VARCHAR2)
1705   IS
1706      l_return_value         BOOLEAN;
1707      l_consol_item_repl_tbl CONSOL_ITEM_REPL_TBL;
1708      l_debug              NUMBER      :=  NVL(fnd_profile.VALUE('INV_DEBUG_TRACE'), 0);
1709 
1710      l_return_status VARCHAR2(3) := fnd_api.g_ret_sts_success;
1711 BEGIN
1712 
1713    x_return_status := l_return_status;
1714    SAVEPOINT dynamic_replenishment_sp;
1715 
1716    --REPLENISHMENT_TYPE
1717    --  1 - PUSH REPLENISHMENT
1718    --  2 - DYNAMIC REPLENISHMENT
1719 
1720    IF l_debug = 1 THEN
1721       print_debug('Inside DYNAMIC_REPLENISHMENT API....');
1722       print_debug('p_org_id      :'||p_org_id  );
1723       print_debug('p_Batch_id    :'||p_Batch_id );
1724       print_debug('p_Plan_Tasks  :'||p_Plan_Tasks );
1725       print_debug('p_Release_Sequence_Rule_Id :'||p_Release_Sequence_Rule_Id );
1726       print_debug('p_repl_level  :'||p_repl_level );
1727    END IF;
1728 
1729 
1730    -- Do validation on passed parameter values
1731 
1732    IF(P_Batch_id IS NULL) THEN
1733       -- if no batch_id provided, just return, Pick release should not fail here
1734       IF l_debug = 1 THEN
1735 	 print_debug('P_Batch_id is NULL, Returning from DYNAMIC_REPLENISHMENT');
1736       END IF;
1737       RETURN;
1738    END IF;
1739 
1740    --Initialize Global package tables
1741    l_consol_item_repl_tbl.DELETE;
1742 
1743    -- Initialize the global Item UOM conversion table
1744    g_item_uom_conversion_tb.DELETE;
1745 
1746    POPULATE_DYNAMIC_REPL_DEMAND(p_repl_level               => p_repl_level,
1747 				p_org_id                   => p_org_id,
1748 				P_Batch_id                 => P_Batch_id,
1749 				p_Release_Sequence_Rule_Id => p_Release_Sequence_Rule_Id,
1750 				x_consol_item_repl_tbl     => L_consol_item_repl_tbl,
1751 				x_return_status            => l_return_status,
1752 				x_msg_count                => x_msg_count,
1753 				x_msg_data                 => x_msg_data
1754 				);
1755    -- API for dynamic replenishment should not return error
1756    -- The API needs to revert the original status of WDD
1757    -- Even if it errors out for what ever reason, all WDDs
1758    -- should be reverted in the called API at the very least
1759    -- and return status of success with no records in consol table
1760    IF l_RETURN_status = fnd_api.g_ret_sts_success THEN
1761       IF (l_debug = 1) THEN
1762 	 PRINT_DEBUG('Demand records populated successfully');
1763       END IF;
1764     ELSE
1765       l_consol_item_repl_tbl.DELETE;
1766       IF (l_debug = 1) THEN
1767 	 PRINT_DEBUG('Error from API POPULATE_dynamic_REPL_DEMAND');
1768       END IF;
1769       RAISE fnd_api.g_exc_unexpected_error;
1770    END IF;
1771 
1772    -- To populate the demand table - WMS_REPL_DEMAND_GTMP - Get values in l_consol_item_repl_tbl
1773    -- Cache information about relevant items
1774    -- Call the core replenishment processing API - PROCESS_REPLENISHMENT()
1775 
1776 
1777 
1778    -- ==========TEST CODE starts ===========
1779    -- This code is for debugging purpose only, this code should be in
1780    -- l_debug = 1 only
1781    IF (l_debug = 1) THEN
1782       IF l_consol_item_repl_tbl.COUNT <> 0 THEN
1783 		 print_debug('*******AFTER POPULATE_DYNAMIC_REPL_DEMAND****');
1784 		 FOR i IN l_consol_item_repl_tbl.FIRST .. l_consol_item_repl_tbl.LAST LOOP
1785 
1786 			IF (NOT l_consol_item_repl_tbl.exists(i)) THEN
1787 			   print_debug('RECORD has been deleted from consol table, Skipping it');
1788 			 ELSE
1789 			   print_debug('ITEM_ID,  Total_qty,  available_OH,  open_MO_QTY, Final_repl_qty ');
1790 			   print_debug( l_consol_item_repl_tbl(i).ITEM_ID  || ' , ' ||
1791 					l_consol_item_repl_tbl(i).total_demand_qty || ' , '||
1792 					l_consol_item_repl_tbl(i).available_onhand_qty|| ' , '||
1793 					l_consol_item_repl_tbl(i).open_mo_qty|| ' , '||
1794 					l_consol_item_repl_tbl(i).final_replenishment_qty);
1795 
1796 			END IF;
1797 		 END LOOP;
1798       END IF;
1799    END IF;
1800    -- ==========TEST CODE ends ===========
1801 
1802 
1803 
1804    IF l_consol_item_repl_tbl.COUNT <> 0 THEN
1805       PROCESS_REPLENISHMENT (
1806 			      P_repl_level                => P_repl_level,
1807 			      p_repl_type                 => 2,  --Dynamic Replenishment
1808 			      p_Repl_Lot_Size             => NULL,
1809 			      P_consol_item_repl_tbl      => l_consol_item_repl_tbl,
1810 			      p_Create_Reservation        => 'Y',
1811 			      p_Auto_Allocate             => 'Y',
1812 			      p_Plan_Tasks                => p_Plan_Tasks,
1813 			      x_return_status             => l_return_status  ,
1814 			      x_msg_count                 => x_msg_count ,
1815 			      x_msg_data                  => x_msg_data );
1816 
1817       IF l_RETURN_status = fnd_api.g_ret_sts_success THEN
1818 	 IF (l_debug = 1) THEN
1819 	    PRINT_DEBUG('processed replenishment successfully');
1820 	 END IF;
1821 
1822        ELSE
1823 	 IF (l_debug = 1) THEN
1824 	    PRINT_DEBUG('Error from API process_replenishment');
1825 	 END IF;
1826 	 -- To call revert of WDD status for all WDDs
1827 	 RAISE fnd_api.g_exc_unexpected_error;
1828       END IF;
1829     ELSE
1830 
1831       IF (l_debug = 1) THEN
1832 	 print_debug('No Demand Records Identified for Chosen Criteria..Exiting...');
1833       END IF;
1834    END IF;
1835 
1836 
1837    -- Call an API to backorder all demands lines that were stored to be backordered
1838    -- We do not fail the transaction even if the backordering fails
1839 
1840    IF (l_debug = 1) THEN
1841       print_debug( 'Number of WDDs to backorder :'||g_backorder_deliv_tab.COUNT());
1842    END IF;
1843 
1844    IF g_backorder_deliv_tab.COUNT() <> 0 THEN
1845       Backorder_wdd_for_repl( l_return_status );
1846       IF l_RETURN_status <> fnd_api.g_ret_sts_success THEN
1847 	 IF (l_debug = 1) THEN
1848 	    PRINT_DEBUG('Call to Backorder_wdd_for_repl API returned failure..DO NOTHING');
1849 	 END IF;
1850       END IF;
1851    END IF;
1852 
1853 
1854    COMMIT;
1855    x_return_status := FND_API.g_ret_sts_success;
1856 
1857    IF (l_debug = 1) THEN
1858       PRINT_DEBUG('Done with the Pull/Dynamic Replenishment');
1859    END IF;
1860 
1861 
1862 EXCEPTION
1863    WHEN OTHERS THEN
1864       ROLLBACK TO dynamic_replenishment_sp;
1865       l_consol_item_repl_tbl.DELETE;
1866       IF l_debug = 1 THEN
1867 	 print_debug('SHOULD NOT HAPPEN Error in DYNAMIC_REPLENISHMENT: ' || sqlcode || ', ' || sqlerrm);
1868       END IF;
1869 
1870       -- To call revert of WDD status for all WDDs
1871       -- need to revert all WDD status back
1872       Revert_ALL_WDD_dynamic_repl (p_org_id           => p_org_id
1873 				   , p_batch_id       => p_batch_id
1874 				   , x_return_status  =>  l_return_status
1875 				   );
1876 
1877       IF l_debug = 1 THEN
1878 	 print_debug('status:'||l_return_status);
1879       END IF;
1880       COMMIT;
1881 
1882       x_return_status:= FND_API.g_ret_sts_error;
1883 END DYNAMIC_REPLENISHMENT;
1884 
1885 
1886 
1887 PROCEDURE POPULATE_PUSH_REPL_DEMAND
1888   (p_repl_level                IN NUMBER,
1889    p_Item_id                   IN NUMBER,
1890    p_organization_id           IN NUMBER,
1891    p_ABC_assignment_group_id   IN NUMBER, -- For ABC Compile Group
1892    p_abc_class_id              IN NUMBER, -- For Item Classification
1893    p_Order_Type_id             IN NUMBER,
1894    p_Carrier_id                IN NUMBER,
1895    p_customer_class            IN VARCHAR2,
1896    p_customer_id               IN NUMBER,
1897    p_Ship_Method_code          IN VARCHAR2,
1898    p_Scheduled_Ship_Date_To    IN NUMBER,
1899    p_Scheduled_Ship_Date_From  IN NUMBER,
1900    p_Forward_Pick_Sub          IN VARCHAR2,
1901    p_repl_UOM                  IN VARCHAR2,
1902    p_Release_Sequence_Rule_Id  IN NUMBER,
1903    p_Min_Order_lines_threshold IN NUMBER,
1904    p_Min_repl_qty_threshold    IN NUMBER,
1905    p_max_NUM_items_for_repl    IN NUMBER,
1906    p_Sort_Criteria             IN NUMBER,
1907    x_consol_item_repl_tbl      OUT NOCOPY CONSOL_ITEM_REPL_TBL,
1908    x_return_status             OUT NOCOPY VARCHAR2,
1909    x_msg_count                 OUT NOCOPY NUMBER,
1910   x_msg_data                  OUT NOCOPY VARCHAR2
1911   )
1912   IS
1913 
1914 
1915 
1916      -- Note: This procedure/concurrent program will be launced for a
1917      -- specific organization. All demand lines for same organizations should be together but here it
1918      -- will not matter (for dynamic repl,it will be ordered by org_id as well
1919 
1920      l_debug              NUMBER      := NVL(fnd_profile.VALUE('INV_DEBUG_TRACE'), 0);
1921 
1922      L_ORDER_ID_SORT           VARCHAR2(4) := NULL;
1923      L_INVOICE_VALUE_SORT      VARCHAR2(4) := NULL;
1924      L_SCHEDULE_DATE_SORT      VARCHAR2(4) := NULL;
1925      L_TRIP_STOP_DATE_SORT     VARCHAR2(4) := NULL;
1926      L_SHIPMENT_PRI_SORT       VARCHAR2(4) := NULL;
1927 
1928      L_INDEX                NUMBER;
1929      l_progress             VARCHAR2(10);
1930      l_quantity_in_repl_uom NUMBER;
1931      L_match_found          NUMBER;
1932      l_return_value BOOLEAN;
1933 
1934 
1935      --TEST : if sub is specified on the SO, we exclude that unless it is same
1936      -- AS forward pick Sub
1937 
1938   CURSOR c_repl_demand_cur IS
1939 	SELECT
1940 	  item_id,header_id,line_id,delivery_detail_id,demand_type_id,requested_quantity,requested_quantity_uom,
1941 	  quantity_in_repl_uom, expected_ship_date , replenishment_status,released_status,
1942 	  sort_attribute1 ,sort_attribute2,sort_attribute3,sort_attribute4,sort_attribute5
1943 
1944 	  FROM (
1945 		SELECT wdd.inventory_item_id as item_id,
1946 		inv_salesorder.get_salesorder_for_oeheader(wdd.source_header_id) AS header_id,
1947 		wdd.source_line_id AS line_id,
1948 		wdd.delivery_detail_id delivery_detail_id,
1949 		decode(wdd.source_document_type_id, 10, 8, 2) as demand_type_id, -- for SO=2 and Internal Order=8
1950 		wdd.requested_quantity requested_quantity, -- this is always stored in primary UOM
1951 		wdd.requested_quantity_uom requested_quantity_uom,
1952 		ROUND((wdd.requested_quantity * get_conversion_rate(wdd.inventory_item_id,
1953 					 wdd.requested_quantity_uom,
1954 					 p_repl_UOM)),g_conversion_precision) as quantity_in_repl_uom,
1955 
1956 		decode(p_Scheduled_Ship_Date_To,
1957 		       null,
1958 		       decode(p_Scheduled_Ship_Date_From,
1959 			      null,
1960 			      null,
1961 			      NVL(WMS_REPLENISHMENT_PVT.Get_Expected_Time(decode(wdd.source_document_type_id, 10, 8, 2),
1962 									  wdd.source_header_id,
1963 									  wdd.source_line_id,
1964 									  wdd.delivery_detail_id),
1965 				  WDD.date_scheduled)),
1966 
1967 		       NVL(WMS_REPLENISHMENT_PVT.Get_Expected_Time(decode(wdd.source_document_type_id, 10, 8, 2),
1968 								   wdd.source_header_id,
1969 								   wdd.source_line_id,
1970 								   wdd.delivery_detail_id),
1971 			   WDD.date_scheduled)) as expected_ship_date,
1972 			     wdd.replenishment_status,
1973 			     wdd.released_status,
1974 
1975 			     -- For order clause by select column values for WSH_PICK_SEQUENCE_RULES
1976 			     -- get for sort_attribute1
1977 			     To_number(DECODE(p_Release_Sequence_Rule_Id,
1978 					      null,
1979 					      null,
1980                   DECODE(g_ordered_psr(1).attribute_name,
1981                          'ORDER_NUMBER',
1982                          DECODE(L_ORDER_ID_SORT,
1983                                 'ASC',
1984                                 To_number(wdd.source_header_number),
1985                                 'DESC',
1986                                 (-1 * To_number(wdd.SOURCE_HEADER_NUMBER)),
1987                                 null),
1988                          'SHIPMENT_PRIORITY',
1989 			 DECODE(WDD.SHIPMENT_PRIORITY_CODE,
1990 				'High',
1991 				20,
1992 				'Standard',
1993 				10,
1994 			       NULL),
1995 			 'INVOICE_VALUE',
1996                          GET_SORT_INVOICE_VALUE(WDD.SOURCE_HEADER_ID,
1997                                                 L_INVOICE_VALUE_SORT),
1998                          'SCHEDULE_DATE',
1999                          DECODE(L_SCHEDULE_DATE_SORT,
2000                                  'ASC',
2001                                 (WDD.DATE_SCHEDULED -
2002                                 TO_DATE('01-01-1700 23:59:59',
2003                                          'DD-MM-YYYY HH24:MI:SS')),
2004                                 'DESC',
2005                                 (TO_DATE('01-01-1700 23:59:59',
2006                                          'DD-MM-YYYY HH24:MI:SS') -
2007                                 WDD.DATE_SCHEDULED),
2008                                 null),
2009                          'TRIP_STOP_DATE',
2010                          GET_SORT_TRIP_STOP_DATE(wdd.delivery_detail_id,
2011                                                  L_TRIP_STOP_DATE_SORT),
2012                          NULL))) as sort_attribute1,
2013 
2014            -- get for sort_attribute2
2015             To_number(DECODE(p_Release_Sequence_Rule_Id,
2016                   null,
2017                   null,
2018                   DECODE(g_ordered_psr(2).attribute_name,
2019                          'ORDER_NUMBER',
2020 			 DECODE(L_ORDER_ID_SORT,
2021 				'ASC',
2022                                 To_number(wdd.source_header_number),
2023                                 'DESC',
2024                                 (-1 * To_number(wdd.SOURCE_HEADER_NUMBER)),
2025                                 null),
2026                          'SHIPMENT_PRIORITY',
2027 			 DECODE(WDD.SHIPMENT_PRIORITY_CODE,
2028 				'High',
2029 				20,
2030 				'Standard',
2031 				10,
2032 				NULL),
2033                          'INVOICE_VALUE',
2034                          GET_SORT_INVOICE_VALUE(WDD.SOURCE_HEADER_ID,
2035                                                 L_INVOICE_VALUE_SORT),
2036                          'SCHEDULE_DATE',
2037                          DECODE(L_SCHEDULE_DATE_SORT,
2038 				'ASC',
2039                                 (WDD.DATE_SCHEDULED -
2040                                 TO_DATE('01-01-1700 23:59:59',
2041                                          'DD-MM-YYYY HH24:MI:SS')),
2042                                 'DESC',
2043                                 (TO_DATE('01-01-1700 23:59:59',
2044                                          'DD-MM-YYYY HH24:MI:SS') -
2045                                 WDD.DATE_SCHEDULED),
2046                                 null),
2047                          'TRIP_STOP_DATE',
2048                          GET_SORT_TRIP_STOP_DATE(wdd.delivery_detail_id,
2049                                                  L_TRIP_STOP_DATE_SORT),
2050                          NULL))) as sort_attribute2,
2051 
2052            -- get for sort_attribute3
2053             To_number(DECODE(p_Release_Sequence_Rule_Id,
2054                   null,
2055                   null,
2056                   DECODE(g_ordered_psr(3).attribute_name,
2057                          'ORDER_NUMBER',
2058 			 DECODE(L_ORDER_ID_SORT,
2059 				'ASC',
2060                                 To_number(wdd.source_header_number),
2061                                 'DESC',
2062                                 (-1 * To_number(wdd.SOURCE_HEADER_NUMBER)),
2063                                 null),
2064                          'SHIPMENT_PRIORITY',
2065 			 DECODE(WDD.SHIPMENT_PRIORITY_CODE,
2066 				'High',
2067 				20,
2068 				'Standard',
2069 				10,
2070 				NULL),
2071                          'INVOICE_VALUE',
2072                          GET_SORT_INVOICE_VALUE(WDD.SOURCE_HEADER_ID,
2073                                                 L_INVOICE_VALUE_SORT),
2074                          'SCHEDULE_DATE',
2075                          DECODE(L_SCHEDULE_DATE_SORT,
2076 				'ASC',
2077                                 (WDD.DATE_SCHEDULED -
2078                                 TO_DATE('01-01-1700 23:59:59',
2079                                          'DD-MM-YYYY HH24:MI:SS')),
2080                                 'DESC',
2081                                 (TO_DATE('01-01-1700 23:59:59',
2082                                          'DD-MM-YYYY HH24:MI:SS') -
2083                                 WDD.DATE_SCHEDULED),
2084                                 null),
2085                          'TRIP_STOP_DATE',
2086                          GET_SORT_TRIP_STOP_DATE(wdd.delivery_detail_id,
2087                                                  L_TRIP_STOP_DATE_SORT),
2088                          NULL))) as sort_attribute3,
2089 
2090            -- get for sort_attribute4
2091             To_number(DECODE(p_Release_Sequence_Rule_Id,
2092                   null,
2093                   null,
2094                   DECODE(g_ordered_psr(4).attribute_name,
2095                          'ORDER_NUMBER',
2096 			 DECODE(L_ORDER_ID_SORT,
2097 				'ASC',
2098                                 To_number(wdd.source_header_number),
2099                                 'DESC',
2100                                 (-1 * To_number(wdd.SOURCE_HEADER_NUMBER)),
2101                                 null),
2102                          'SHIPMENT_PRIORITY',
2103 			 DECODE(WDD.SHIPMENT_PRIORITY_CODE,
2104 				'High',
2105 				20,
2106 				'Standard',
2107 				10,
2108 				NULL),
2109 			 'INVOICE_VALUE',
2110                          GET_SORT_INVOICE_VALUE(WDD.SOURCE_HEADER_ID,
2111                                                 L_INVOICE_VALUE_SORT),
2112                          'SCHEDULE_DATE',
2113                          DECODE(L_SCHEDULE_DATE_SORT,
2114 				'ASC',
2115                                 (WDD.DATE_SCHEDULED -
2116                                 TO_DATE('01-01-1700 23:59:59',
2117                                          'DD-MM-YYYY HH24:MI:SS')),
2118                                 'DESC',
2119                                 (TO_DATE('01-01-1700 23:59:59',
2120                                          'DD-MM-YYYY HH24:MI:SS') -
2121                                 WDD.DATE_SCHEDULED),
2122                                 null),
2123                          'TRIP_STOP_DATE',
2124                          GET_SORT_TRIP_STOP_DATE(wdd.delivery_detail_id,
2125                                                  L_TRIP_STOP_DATE_SORT),
2126                          NULL))) as sort_attribute4,
2127 
2128            -- get for sort_attribute5
2129             To_number(DECODE(p_Release_Sequence_Rule_Id,
2130                   null,
2131                   null,
2132                   DECODE(g_ordered_psr(5).attribute_name,
2133                          'ORDER_NUMBER',
2134 			 DECODE(L_ORDER_ID_SORT,
2135 				'ASC',
2136                                 To_number(wdd.source_header_number),
2137                                 'DESC',
2138                                 (-1 * To_number(wdd.SOURCE_HEADER_NUMBER)),
2139                                 null),
2140                          'SHIPMENT_PRIORITY',
2141 			 DECODE(WDD.SHIPMENT_PRIORITY_CODE,
2142 				'High',
2143 				20,
2144 				'Standard',
2145 				10,
2146 				null),
2147                          'INVOICE_VALUE',
2148                          GET_SORT_INVOICE_VALUE(WDD.SOURCE_HEADER_ID,
2149                                                 L_INVOICE_VALUE_SORT),
2150                          'SCHEDULE_DATE',
2151                          DECODE(L_SCHEDULE_DATE_SORT,
2152 				'ASC',
2153                                 (WDD.DATE_SCHEDULED -
2154                                 TO_DATE('01-01-1700 23:59:59',
2155                                          'DD-MM-YYYY HH24:MI:SS')),
2156                                 'DESC',
2157                                 (TO_DATE('01-01-1700 23:59:59',
2158                                          'DD-MM-YYYY HH24:MI:SS') -
2159                                 WDD.DATE_SCHEDULED),
2160                                 null),
2161                          'TRIP_STOP_DATE',
2162                          GET_SORT_TRIP_STOP_DATE(wdd.delivery_detail_id,
2163                                                  L_TRIP_STOP_DATE_SORT),
2164 			   NULL))) as sort_attribute5
2165 
2166 			   FROM oe_order_lines_all oel,
2167 			   wsh_delivery_details wdd
2168 			   WHERE wdd.organization_id = p_organization_id
2169 			   AND wdd.source_code = 'OE'
2170 			   AND oel.booked_flag = 'Y'
2171 			   AND oel.open_flag = 'Y'
2172 			   AND wdd.requested_quantity > 0
2173 			   AND oel.line_id = wdd.source_line_id
2174 			   -- excluding Replenishment requested status
2175 			   AND wdd.released_status in ('R', 'B')
2176 			   and nvl(wdd.replenishment_status, 'C') = 'C'
2177 			   -- there might not be reservation
2178 			   AND not exists
2179 			   (select 1
2180 			    from mtl_reservations mr
2181 			    WHERE MR.DEMAND_SOURCE_LINE_ID = wdd.source_line_id
2182 			    and MR.DEMAND_SOURCE_HEADER_ID =
2183 			    inv_salesorder.get_salesorder_for_oeheader(wdd.source_header_id)
2184 			    AND MR.SUBINVENTORY_CODE IS NOT NULL) --locator is not needed -- Exclude detailed RSV
2185 
2186 			      --Exclude those demands that have suub
2187 			      -- specified, we can not use sub = Forward_pick_sub either
2188 			      -- becs FP sub info is not availble while marking 'RC' at the pick drop time when rsv = N
2189 			    AND wdd.subinventory IS NULL
2190 				/*10131943- Made the query on MTL_ABC_ASSIGNMENTS a sub-query because an item can have multiple ABC compile/group assignments*/
2191                 AND (NOT EXISTS (SELECT 1
2192 							   FROM   mtl_abc_assignments maa
2193 							   WHERE   maa.inventory_item_id = oel.inventory_item_id)
2194 					 OR EXISTS (SELECT 1
2195 							   FROM   mtl_abc_assignments maa
2196 							   WHERE   maa.inventory_item_id = oel.inventory_item_id
2197 								AND Nvl(maa.assignment_group_id, -1) = Nvl(p_ABC_assignment_group_id, Nvl(maa.assignment_group_id, -1))
2198 								AND Nvl(maa.abc_class_id, -1) = Nvl(p_abc_class_id, Nvl(maa.abc_class_id, -1))
2199 								)
2200 					)
2201 			     AND (nvl(wdd.customer_id, -1) = nvl(p_customer_id,nvl(wdd.customer_id, -1))
2202 				   OR  wdd.customer_id in (SELECT party_id FROM  hz_cust_accounts
2203 						      WHERE customer_class_code = p_customer_class
2204 						      AND  status <> 'I'
2205 						      AND  party_id = nvl(p_customer_id,party_id)))
2206 			      AND wdd.source_header_type_id = nvl(P_ORDER_TYPE_ID,source_header_type_id)
2207 			      AND NOT  exists
2208 			      (select wrd.demand_line_detail_id
2209 			       from WMS_REPLENISHMENT_DETAILS wrd
2210 			       where wrd.demand_line_detail_id = wdd.delivery_detail_id
2211 			       and wrd.demand_line_id = wdd.source_line_id
2212 			       and wrd.organization_id = wdd.organization_id
2213 			       And wrd.organization_id = p_organization_id)
2214 
2215 			      AND wdd.INVENTORY_ITEM_ID = NVL(P_ITEM_ID, wdd.INVENTORY_ITEM_ID)
2216 			      AND nvl(wdd.carrier_id, -1) =
2217 			      NVL(p_Carrier_id, nvl(wdd.carrier_id, -1))
2218 			      AND nvl(wdd.SHIP_METHOD_CODE, '@@@') =
2219 			      NVL(p_Ship_Method_code, nvl(wdd.SHIP_METHOD_CODE, '@@@')) -- mandatory field
2220 
2221 			      ) X
2222 
2223 			WHERE x.quantity_in_repl_uom > 0
2224 			AND x.expected_ship_date <= (SYSDATE + p_scheduled_ship_date_to )-- MANDATORY FIELD
2225 
2226 				ORDER BY
2227 			      x.sort_attribute1,
2228 			      x.sort_attribute2,
2229 			      x.sort_attribute3,
2230 			      x.sort_attribute4,
2231 			      x.sort_attribute5
2232 			      FOR UPDATE SKIP LOCKED;
2233 
2234 			      --<<Those demands that are still in Order Management and
2235 			      -- not scheduled yet are not considering in the demand
2236 			      --  cursor. Only those demands that are scheduled, means that
2237 			      --are booked and they exist in WDD are being considered as
2238 			      --valid demand>>
2239 
2240 
2241 			      -- DESTINATION SUB IS SAME FOR ALL THESE RECORDS in c_item_repl_cur
2242      CURSOR c_item_repl_cur IS
2243 	SELECT  X.inventory_item_id inventory_item_id,
2244 	  X.total_demand_qty total_demand_qty,
2245 	  X.date_required date_required
2246 	  FROM (SELECT inventory_item_id,
2247 		sum(quantity_in_repl_uom) as total_demand_qty,
2248 		MIN(expected_ship_date) as date_required,
2249 		MIN(repl_sequence_id) AS order_priority -- to avoid conflicting situation
2250 		FROM WMS_REPL_DEMAND_GTMP
2251 		where organization_id = p_organization_id
2252 		group by inventory_item_id
2253 		order by decode(p_Sort_Criteria,
2254 				1,
2255 				sum(quantity_in_repl_uom),
2256 				count(1)) DESC, order_priority ASC) X
2257 		  WHERE ROWNUM <= nvl(p_max_NUM_items_for_repl, 1e25);
2258 
2259 
2260 
2261 
2262 		--BULK OPERATION: Table to store results from the open demand for replenishment
2263 		l_item_id_tb num_tab;
2264 		l_header_id_tb num_tab;
2265 		l_line_id_tb num_tab;
2266 		l_delivery_detail_id_tb num_tab;
2267 		l_demand_type_id_tb num_tab;
2268 		l_requested_quantity_tb num_tab;
2269 		l_requested_quantity_uom_tb uom_tab;
2270 		l_quantity_in_repl_uom_tb num_tab;
2271 		l_expected_ship_date_tb date_tab;
2272 		l_repl_status_tb  char1_tab;
2273 		l_released_status_tb char1_tab;
2274 		l_attr1_tab num_tab;
2275 		l_attr2_tab num_tab;
2276 		l_attr3_tab num_tab;
2277 		l_attr4_tab num_tab;
2278 		l_attr5_tab num_tab;
2279 
2280 
2281 		-- BULK OPERATION:  Table to store consolidate demand results for replenishment
2282 		l_total_demand_qty_tb num_tab;
2283 		l_date_required_tb date_tab;
2284 
2285 		l_temp_cnt NUMBER; -- for debugging only
2286 		l_return_status VARCHAR2(3) := fnd_api.g_ret_sts_success;
2287 BEGIN
2288    x_return_status := l_return_status;
2289 
2290    IF (l_debug = 1) THEN
2291       print_debug('Inside POPULATE_PUSH_REPL_DEMAND Release_Sequence_Rule_Id: '||p_Release_Sequence_Rule_Id);
2292    END IF;
2293 
2294 
2295    -- Get the Order By Clause based on Pick Release Rule
2296    --initialize gloabl variables
2297    --delete old value
2298    g_ordered_psr.DELETE;
2299    init_rules(p_pick_seq_rule_id    =>  p_Release_Sequence_Rule_Id,
2300 	      x_order_id_sort       =>  L_ORDER_ID_SORT,
2301 	      x_INVOICE_VALUE_SORT  =>  L_INVOICE_VALUE_SORT,
2302 	      x_SCHEDULE_DATE_SORT  =>  L_SCHEDULE_DATE_SORT,
2303 	      x_trip_stop_date_sort =>  L_TRIP_STOP_DATE_SORT,
2304 	      x_SHIPMENT_PRI_SORT   =>  l_shipment_pri_sort,
2305 	      x_ordered_psr         =>  g_ordered_psr,
2306 	      x_api_status          =>  l_return_status );
2307 
2308    IF (l_debug = 1) THEN
2309       print_debug('Status after calling init_rules'||l_return_status);
2310    END IF;
2311    IF (l_return_status <> fnd_api.g_ret_sts_success) THEN
2312       x_return_status := l_return_status;
2313       -- caller rollsback everything if error
2314       RETURN;
2315    END IF;
2316 
2317    --Clear all tables for bulk operation
2318    l_item_id_tb.DELETE;
2319    l_header_id_tb.DELETE;
2320    l_line_id_tb.DELETE;
2321    l_delivery_detail_id_tb.DELETE;
2322    l_demand_type_id_tb.DELETE;
2323    l_requested_quantity_tb.DELETE;
2324    l_requested_quantity_uom_tb.DELETE;
2325    l_quantity_in_repl_uom_tb.DELETE;
2326    l_expected_ship_date_tb.DELETE;
2327    l_repl_status_tb.DELETE;
2328    l_released_status_tb.DELETE;
2329    l_attr1_tab.DELETE;
2330    l_attr2_tab.DELETE;
2331    l_attr3_tab.DELETE;
2332    l_attr4_tab.DELETE;
2333    l_attr5_tab.DELETE;
2334 
2335    -- BULK Fetch all data from the demand cursor
2336    BEGIN
2337       OPEN c_repl_demand_cur;
2338       FETCH c_repl_demand_cur BULK COLLECT INTO l_item_id_tb,l_header_id_tb, l_line_id_tb, l_delivery_detail_id_tb,
2339 	l_demand_type_id_tb, l_requested_quantity_tb,l_requested_quantity_uom_tb,
2340 	l_quantity_in_repl_uom_tb,l_expected_ship_date_tb,l_repl_status_tb,l_released_status_tb,
2341 	l_attr1_tab,l_attr2_tab,l_attr3_tab,l_attr4_tab,l_attr5_tab ;
2342 
2343       IF (l_debug = 1) THEN
2344 	 print_debug('InProcess ROWCOUNT :'||  c_repl_demand_cur%ROWCOUNT );
2345       END IF;
2346       CLOSE c_repl_demand_cur;
2347 
2348    EXCEPTION
2349       WHEN OTHERS THEN
2350 	 IF (l_debug = 1) THEN
2351 	    print_debug('Exception retrieving open repl demand records :'||SQLCODE ||' '||SQLERRM);
2352 	 END IF;
2353       -- caller rollsback everything if error
2354 	 x_return_status := fnd_api.g_ret_sts_error;
2355 	 RETURN;
2356    END;
2357 
2358 
2359    --BULK insert all demand records in the GTMP table
2360    BEGIN
2361       FORALL k IN INDICES OF l_delivery_detail_id_tb
2362 	insert into WMS_REPL_DEMAND_GTMP
2363 	(Repl_Sequence_id,
2364 	 repl_level,
2365 	 Inventory_item_id,
2366 	 Organization_id,
2367 	 demand_header_id,
2368 	 demand_line_id,
2369 	 demand_line_detail_id,
2370 	 demand_type_id,
2371 	 Quantity,
2372 	 Uom_code,
2373 	 quantity_in_repl_uom,
2374 	 REPL_UOM_code,
2375 	 Expected_ship_date,
2376 	 Repl_To_Subinventory_code,
2377 	 filter_item_flag,
2378 	 repl_status,
2379 	 repl_type,
2380 	 RELEASED_STATUS)
2381 	values
2382 	(WMS_REPL_DEMAND_GTMP_S.NEXTVAL,
2383 	 p_repl_level,
2384 	 l_item_id_tb(k),
2385 	 p_organization_id,
2386 	 l_header_id_tb(k),
2387 	 l_line_id_tb(k),
2388 	 l_delivery_detail_id_tb(k),
2389 	 l_demand_type_id_tb(k),
2390 	 l_requested_quantity_tb(k),
2391 	 l_requested_quantity_uom_tb(k),
2392 	 l_quantity_in_repl_uom_tb(k),
2393 	 p_repl_UOM,
2394 	 l_expected_ship_date_tb(k),
2395 	 P_Forward_Pick_Sub,
2396 	 NULL,
2397 	 l_repl_status_tb(k),
2398 	 1,
2399 	 l_released_status_tb(k)); -- for Push replenishment
2400 
2401 
2402       /*
2403       -- p_Scheduled_Ship_Date_FROM is long enough to go to take the
2404       -- expected_date TO the last month, the query used to fail.
2405       --  AND x.expected_ship_date >=
2406       --        DECODE(NVL(p_Scheduled_Ship_Date_FROM, -1),-1,x.expected_ship_date,(SYSDATE - p_scheduled_ship_date_from))
2407       -- NULL value of p_Scheduled_Ship_Date_FROM is fine,
2408       -- running seperate query from dual with problematic value is also fine
2409       -- So I removed the condition from the main query and have put here
2410       -- AS extra CHECK ON p_scheduled_ship_date_from value condition
2411       */
2412 
2413       IF  p_scheduled_ship_date_from IS NOT NULL THEN
2414 	 DELETE FROM  WMS_REPL_DEMAND_GTMP
2415 	   WHERE expected_ship_date < (SYSDATE - p_scheduled_ship_date_from);
2416       END IF;
2417 
2418 
2419       -- NOTE:  Only those records were inserted in the GTMP table for which there is no detailed reservation
2420       -- Delete records in the GTMP table for which total demand qty for an
2421       -- item is below the p_Min_repl_qty_threshold (Minimum threshold for Replenishment);
2422 
2423       IF p_Min_repl_qty_threshold is NOT NULL THEN
2424 	 DELETE FROM  WMS_REPL_DEMAND_GTMP
2425 	   WHERE (inventory_item_id)
2426 	   IN  (SELECT inventory_item_id
2427 		from WMS_REPL_DEMAND_GTMP
2428 		where organization_id = p_organization_id
2429 		group by inventory_item_id
2430 		having sum(quantity_in_repl_uom) < p_Min_repl_qty_threshold);
2431 
2432       END IF;
2433 
2434 
2435       --  Delete records in the GTMP table for which number of order lines are below p_Min_Order_lines_threshold
2436       -- (Minimum Order lines threshold)
2437       IF p_Min_Order_lines_threshold IS NOT NULL THEN
2438 	 DELETE  FROM  WMS_REPL_DEMAND_GTMP
2439 	   where(inventory_item_id) in
2440 	   (SELECT  inventory_item_id from WMS_REPL_DEMAND_GTMP
2441 	    where organization_id = p_organization_id group by inventory_item_id
2442 	    having count(1) < Nvl(p_min_order_lines_threshold,1));
2443 
2444       END IF;
2445    EXCEPTION
2446       WHEN OTHERS THEN
2447 	 IF (l_debug = 1) THEN
2448 	    print_debug('Error inserting wms_repl_demand_gtmp table');
2449 	 END IF;
2450 	 -- caller rollsback everything if error
2451 	 x_return_status := fnd_api.g_ret_sts_error;
2452 	 RETURN;
2453    END;
2454 
2455 
2456    -- Sort the remaining records based on the Sort Criteria specified (1 =
2457    --Total Demand Quantity; 2= Number of Order lines)
2458    --and then apply the filter p_max_NUM_items_for_repl ( Number of Items to be considered for Replenishment )
2459    --  Now the cursor c_consol_item_repl_cur will apply two filter: p_sort_criteria and p_max_num_items_for_repl
2460    -- Now store these final Item records for consolidated demand in the PL/SQL table
2461    -- l_consol_item_repl_tbl . This PL/SQL table will have more information (available onhand qty
2462    -- open move order qty and final_replenishment_qty populated in later calculation.
2463 
2464    -- USE BULK UPLOAD
2465 
2466    -- Clear tables for bulk operation
2467    l_item_id_tb.DELETE;
2468    l_total_demand_qty_tb.DELETE;
2469    l_date_required_tb.DELETE;
2470 
2471    BEGIN
2472       OPEN c_item_repl_cur;
2473       FETCH c_item_repl_cur BULK COLLECT INTO  l_item_id_tb, l_total_demand_qty_tb, l_date_required_tb;
2474       CLOSE c_item_repl_cur;
2475    EXCEPTION
2476       WHEN OTHERS THEN
2477 	 IF (l_debug = 1) THEN
2478 	    print_debug('Exception retrieving item repl records');
2479 	 END IF;
2480 	 x_return_status := fnd_api.g_ret_sts_error;
2481       -- caller rollback everything if error
2482 	 RETURN;
2483    END;
2484 
2485    IF (l_debug = 1) THEN
2486       print_debug('Total Number of consolidate Repl Records:'||l_item_id_tb.COUNT);
2487    END IF;
2488 
2489 
2490 
2491    -- Proceed following only if anything need to be processed
2492    IF l_item_id_tb.COUNT = 0 THEN
2493 
2494       IF (l_debug = 1) THEN
2495 	 print_debug('No record to be processed..Exiting');
2496       END IF;
2497 
2498 
2499     ELSE -- means there are records are to be processed
2500 
2501       --Clear consolidated table
2502       x_consol_item_repl_tbl.DELETE;
2503       IF (l_item_id_tb.count>0) THEN --bug#10185153
2504 		  FOR k IN l_item_id_tb.FIRST .. l_item_id_tb.LAST LOOP
2505 			 x_consol_item_repl_tbl(k).Organization_id := p_organization_id;
2506 			 x_consol_item_repl_tbl(k).Item_id := l_item_id_tb(k);
2507 			 x_consol_item_repl_tbl(k).total_demand_qty := l_total_demand_qty_tb(k);
2508 			 x_consol_item_repl_tbl(k).date_required := l_date_required_tb(k);
2509 
2510 			 x_consol_item_repl_tbl(k).available_onhand_qty := 0; --calculated later
2511 			 x_consol_item_repl_tbl(k).open_mo_qty := 0; --calculated later
2512 			 x_consol_item_repl_tbl(k).final_replenishment_qty := 0; --calculated later
2513 
2514 			 x_consol_item_repl_tbl(k).repl_to_subinventory_code := P_Forward_Pick_sub; --same for batch
2515 			 x_consol_item_repl_tbl(k).repl_uom_code := p_repl_UOM; --same for a batch
2516 
2517 		  END LOOP;
2518 	  END IF;
2519 
2520 
2521 
2522       -- ===========================================
2523       -- Delete all records from the GTMP table for all items that is not part
2524       -- of the l_consol_item_repl_tbl pl/sql table. here are steps TO DO it
2525 
2526       --1- BULK Insert again all item records in the PL/SQL table with
2527       --  Filter_item_flag columns = 'Y into the GTMP table,  We want to keep
2528       --  all original item records in GTMP that corresponds to these newly inserted item_id records
2529       --2-Delete those item records in the GTMP table whose item_ids are not same as item_id
2530       --  records that correspond to Filter_item_flag columns = Y records
2531       --3-Remove all records in the table that correspond to Filter_item_flag columns = 'Y'
2532       -- ===========================================
2533 
2534       --1 BULK Insert again all item records in the PL/SQL table with
2535       BEGIN
2536 	 FORALL k IN 1 .. l_item_id_tb.COUNT
2537 	   INSERT INTO WMS_REPL_DEMAND_GTMP
2538 	   (Repl_Sequence_id,
2539 	    repl_level,
2540 	    Inventory_item_id,
2541 	    Organization_id,
2542 	    demand_header_id,
2543 	    demand_line_id,
2544 	    demand_line_detail_id,
2545 	    demand_type_id,
2546 	    quantity_in_repl_uom,
2547 	    REPL_UOM_code,
2548 	    Quantity,
2549 	    Uom_code,
2550 	    Expected_ship_date,
2551 	    Repl_To_Subinventory_code,
2552 	    filter_item_flag,
2553 	    repl_status,
2554 	    repl_type,
2555 	    RELEASED_STATUS)
2556 	   VALUES
2557 	   (WMS_REPL_DEMAND_GTMP_S.NEXTVAL,
2558 	    p_repl_level,
2559 	    l_item_id_tb(k),
2560 	    p_organization_id, --for push repl, it is same though
2561 	    -9999,
2562 	    -9999,
2563 	    -9999,
2564 	    -9999,
2565 	    -9999,
2566 	    p_repl_UOM,
2567 	    -9999,
2568 	    '@@@',
2569 	    l_date_required_tb(k),
2570 	    P_Forward_Pick_Sub,
2571 	    'Y',
2572 	    NULL,
2573 	    1, -- For Push replenishment
2574 	    NULL);
2575 
2576 
2577 	 --2 Delete those item records in the GTMP table whose item_ids are not same as item_id
2578 	 --records that correspond to Filter_item_flag columns = 'Y' records
2579 	 DELETE FROM wms_repl_demand_gtmp
2580 	   WHERE filter_item_flag IS NULL
2581 	     AND inventory_item_id NOT IN (SELECT inventory_item_id FROM
2582 					   wms_repl_demand_gtmp WHERE
2583 					   Nvl(filter_item_flag,'N') = 'Y');
2584 
2585 
2586 	   --3  Remove all records in the table that correspond to Filter_item_flag columns = 'Y'
2587 	   DELETE FROM wms_repl_demand_gtmp
2588 	     WHERE filter_item_flag = 'Y';
2589 
2590       EXCEPTION
2591 	 WHEN OTHERS THEN
2592 	    IF (l_debug = 1) THEN
2593 	       print_debug('Error inserting in WRDG temp table with Filter_item_flag = y : '||SQLCODE ||' '||SQLERRM);
2594 	    END IF;
2595 	    -- caller rollsback everything if error
2596 	    x_return_status := fnd_api.g_ret_sts_error;
2597 	    x_consol_item_repl_tbl.DELETE;
2598 	    RETURN;
2599       END;
2600 
2601 
2602       -- Discard all demand lines from Push Repl consideration that could not be
2603       -- Fulfilled BY available Effective atr in the entire the organizatrion
2604       -- Adjust ALL qty in consol_table and GTMP accordingly for all items
2605       IF x_consol_item_repl_tbl.COUNT() <> 0 THEN
2606 	 ADJUST_ATR_FOR_ITEM  (p_repl_level             => p_repl_level
2607 			       , p_repl_type            => g_push_repl
2608 			       , x_consol_item_repl_tbl => x_consol_item_repl_tbl
2609 			       , x_return_status        => l_return_status
2610 			       );
2611 
2612 	 IF l_return_status <> 'S' THEN
2613 	    IF l_debug = 1 THEN
2614 	       print_debug('API ADJUST_ATR_FOR_ITEM returned error');
2615 	    END IF;
2616 	    x_return_status := fnd_api.g_ret_sts_error;
2617 	    x_consol_item_repl_tbl.DELETE;
2618 	    RETURN;
2619 	 END IF;
2620 
2621 	 IF l_debug = 1 THEN
2622 	    print_debug('Return Status after call to ADJUST_ATR_FOR_ITEM :'|| l_return_status);
2623 	 END IF;
2624 
2625       END IF;
2626 
2627       --=====================TEST CODE STARTS =======
2628       -- ONLY for debugging purpose
2629       IF l_debug = 1 THEN
2630 	 SELECT COUNT(1) INTO  l_temp_cnt FROM wms_repl_demand_gtmp;
2631 	 print_debug(' FINAL record count in gtmp :'||l_temp_cnt);
2632 	 print_debug(' number of records in consol table :'||x_consol_item_repl_tbl.COUNT());
2633       END IF;
2634       --=====================TEST CODE ENDS =======
2635 
2636    END IF; --  IF l_item_id_tb.COUNT = 0
2637 
2638       x_return_status := FND_API.g_ret_sts_success;
2639 
2640       IF l_debug = 1 THEN
2641 	 print_debug('Done with API populate_push_repl_demand');
2642       END IF;
2643 
2644 EXCEPTION
2645    WHEN OTHERS THEN
2646       IF (l_debug = 1) THEN
2647 	 print_debug('Error in populate_push_repl_demand SQLCODE:'||SQLCODE ||' '||SQLERRM );
2648       END IF;
2649       --
2650       -- caller rollsback everything if error
2651       x_return_status := fnd_api.g_ret_sts_unexp_error;
2652       x_consol_item_repl_tbl.DELETE;
2653       --
2654 END  populate_push_repl_demand ;
2655 
2656 PROCEDURE check_for_next_level_repl(p_move_order_header_id IN NUMBER,
2657 				    p_move_order_line_id IN NUMBER,
2658 				    p_organization_id IN NUMBER,
2659 				    p_inventory_item_id IN NUMBER,
2660 				    p_repl_level IN NUMBER,
2661 				    x_source_sub_atr IN OUT nocopy NUMBER,
2662 				    x_create_qty OUT nocopy VARCHAR2,
2663 				    x_return_status OUT nocopy VARCHAR2,
2664 				    x_msg_count OUT nocopy NUMBER,
2665 				    x_msg_data OUT nocopy VARCHAR2)
2666   IS
2667      l_debug              NUMBER      := NVL(fnd_profile.VALUE('INV_DEBUG_TRACE'), 0);
2668      l_repl_level NUMBER := p_repl_level;
2669      l_create_qty NUMBER := 0; -- 0 to signify it was not created
2670      l_source_sub_atr NUMBER := x_source_sub_atr;
2671      l_pending_mo_qty NUMBER;
2672      l_mo_source_sub VARCHAR2(50);
2673      l_mo_source_loc NUMBER;
2674      l_is_revision_ctrl BOOLEAN := FALSE;
2675      l_is_lot_ctrl BOOLEAN := FALSE;
2676      l_is_serial_ctrl BOOLEAN := FALSE;
2677      l_qoh NUMBER;
2678      l_rqoh NUMBER;
2679      l_qr   NUMBER;
2680      l_qs NUMBER;
2681      l_atr NUMBER;
2682      l_return_status VARCHAR2(3) := fnd_api.g_ret_sts_success;
2683      l_next_lvl_src_sub VARCHAR(30);
2684 BEGIN
2685    x_create_qty := l_create_qty;
2686    x_return_status := fnd_api.g_ret_sts_success;
2687 
2688    IF l_source_sub_atr IS NULL THEN
2689       l_source_sub_atr := -9999;
2690    END IF;
2691 
2692    IF l_repl_level IS NULL THEN
2693    BEGIN
2694       SELECT repl_level
2695 	INTO l_repl_level
2696 	FROM wms_replenishment_details
2697 	WHERE source_type_id = 4
2698 	AND organization_id = p_organization_id
2699 	AND inventory_item_id = p_inventory_item_id
2700 	AND source_header_id = p_move_order_header_id
2701 	AND source_line_id = p_move_order_line_id
2702 	AND ROWNUM = 1;
2703    EXCEPTION
2704       WHEN no_data_found THEN
2705 	 l_repl_level := 1;
2706       WHEN OTHERS THEN
2707 	 l_repl_level := 4;
2708    END;
2709    END IF;
2710    IF (l_debug = 1) THEN
2711       print_debug('l_repl_level:'||l_repl_level);
2712    END IF;
2713 
2714    IF l_repl_level >= 4 THEN
2715       x_return_status := fnd_api.g_ret_sts_success;
2716       x_create_qty := 0;
2717       RETURN;
2718    END IF;
2719 
2720 
2721    BEGIN
2722       SELECT (quantity - Nvl(quantity_detailed,0) - Nvl(quantity_delivered,0))
2723 	, from_subinventory_code
2724 	, from_locator_id
2725 	INTO l_create_qty
2726 	, l_mo_source_sub
2727 	, l_mo_source_loc
2728 	FROM mtl_txn_request_lines
2729 	WHERE line_id = p_move_order_line_id
2730 	AND organization_id = p_organization_id
2731 	AND inventory_item_id = p_inventory_item_id;
2732       IF (l_debug = 1) THEN
2733 	 print_debug('l_create_qty:'||l_create_qty);
2734 	 print_debug('l_mo_source_sub:'||l_mo_source_sub);
2735 	 print_debug('l_mo_source_loc:'||l_mo_source_loc);
2736       END IF;
2737       IF ((l_create_qty <= 0) OR (l_mo_source_sub IS NULL)) THEN
2738 	 x_return_status := fnd_api.g_ret_sts_success;
2739 	 x_create_qty := 0;
2740 	 RETURN;
2741       END IF;
2742 	select MISI.SOURCE_SUBINVENTORY into l_next_lvl_src_sub
2743 	FROM MTL_ITEM_SUB_INVENTORIES MISI
2744 	WHERE MISI.organization_id = p_organization_id
2745 	and MISI.INVENTORY_ITEM_ID = p_inventory_item_id
2746 	and MISI.source_type = 3 --(for Subinventory)
2747 	and MISI.SECONDARY_INVENTORY = l_mo_source_sub
2748 	AND ROWNUM = 1;
2749 
2750 	if l_next_lvl_src_sub is NULL then
2751 
2752 		if (l_debug = 1) THEN
2753 		print_debug('Since no next level setup exists, thus returning' );
2754 		END IF;
2755 		x_create_qty := 0;
2756 		x_return_status := fnd_api.g_ret_sts_success;
2757 		return;
2758 	end if;
2759 
2760 
2761       IF l_source_sub_atr = -9999 THEN
2762 	 -- Get all item details
2763 	 IF inv_cache.set_item_rec(p_ORGANIZATION_ID, p_inventory_item_id)  THEN
2764 	    IF (l_debug = 1) THEN
2765 	       print_debug('Getting Item Attribute Details' );
2766 	    END IF;
2767 	    IF inv_cache.item_rec.revision_qty_control_code = 2 THEN
2768 	       l_is_revision_ctrl := TRUE;
2769 	     ELSE
2770 	       l_is_revision_ctrl := FALSE;
2771 	    END IF;
2772 
2773 	    IF inv_cache.item_rec.lot_control_code = 2 THEN
2774 	       l_is_lot_ctrl := TRUE;
2775 	     ELSE
2776 	       l_is_lot_ctrl := FALSE;
2777 	    END IF;
2778 
2779 	    IF inv_cache.item_rec.serial_number_control_code NOT IN (1,6) THEN
2780 	       l_is_serial_ctrl := FALSE;
2781 	     ELSE
2782 	       l_is_serial_ctrl := TRUE;
2783 	    END IF;
2784 
2785 	  ELSE
2786 	    IF (l_debug = 1) THEN
2787 	       print_debug('Error: Item detail not found');
2788 	    END IF;
2789 	    x_return_status := fnd_api.g_ret_sts_success;
2790 	    x_create_qty := 0;
2791 	 END IF; -- for inv_cache.set_item_rec
2792 
2793 	 IF (l_debug = 1) THEN
2794 	    print_debug('Clearing Qty Tree' );
2795 	 END IF;
2796 	 --Query Quantity Tree
2797 	 inv_quantity_tree_pub.clear_quantity_cache;
2798 
2799 	 IF (l_debug = 1) THEN
2800 	    print_debug('Calling Qty Tree API' );
2801 	 END IF;
2802 
2803 	 inv_quantity_tree_pub.query_quantities
2804 	   (
2805 	    p_api_version_number         => 1.0
2806 	    , p_init_msg_lst               => fnd_api.g_false
2807 	    , x_return_status              => l_return_status
2808 	    , x_msg_count                  => x_msg_count
2809 	    , x_msg_data                   => x_msg_data
2810 	    , p_organization_id            => p_organization_id
2811 	    , p_inventory_item_id          => p_inventory_item_id
2812 	    , p_tree_mode                  => inv_quantity_tree_pub.g_transaction_mode
2813 	    , p_is_revision_control        =>  l_is_revision_ctrl
2814 	    , p_is_lot_control             =>  l_is_lot_ctrl
2815 	    , p_is_serial_control          =>  l_is_serial_ctrl
2816 	    , p_demand_source_type_id    => -9999 --should not be null
2817 	    , p_demand_source_header_id  => -9999 --should not be null
2818 	    , p_demand_source_line_id    => -9999
2819 	    , p_revision                   => NULL
2820 	    , p_lot_number                 => NULL
2821 	    , p_subinventory_code          => l_mo_source_sub
2822 	    , p_locator_id                 => l_mo_source_loc
2823 	    , x_qoh                        => l_qoh
2824 	    , x_rqoh                       => l_rqoh
2825 	   , x_qr                         => l_qr
2826 	   , x_qs                         => l_qs
2827 	   , x_att                        => l_source_sub_atr
2828 	   , x_atr                        => l_atr
2829 	   );
2830 
2831 	 IF (l_debug = 1) THEN
2832 	    print_debug( 'Return status from QTY TREE:' ||x_return_status);
2833 	 END IF;
2834 	 IF l_return_status = fnd_api.g_ret_sts_success THEN
2835 	    x_source_sub_atr := l_source_sub_atr;
2836 	  ELSE
2837 	    l_source_sub_atr := -9999;
2838 	 END IF;
2839       END IF;
2840       IF (l_debug = 1) THEN
2841 	 print_debug( 'l_source_sub_atr is: '||l_source_sub_atr);
2842       END IF;
2843       IF l_source_sub_atr <= 0 THEN
2844 	 x_return_status := fnd_api.g_ret_sts_success;
2845 	 x_create_qty := l_create_qty;
2846 	 x_source_sub_atr := 0;
2847 	 RETURN;
2848       END IF;
2849       x_return_status := fnd_api.g_ret_sts_success;
2850       x_create_qty := 0;
2851    EXCEPTION
2852       WHEN OTHERS THEN
2853 	 x_return_status := fnd_api.g_ret_sts_success;
2854 	 x_create_qty := 0;
2855 	 x_source_sub_atr := NULL;
2856    END;
2857 END check_for_next_level_repl;
2858 
2859 PROCEDURE trigger_next_level_repl(p_repl_level IN NUMBER
2860 				  , p_repl_lot_size IN NUMBER
2861 				  , p_plan_tasks IN VARCHAR2
2862 				  , x_return_status OUT nocopy VARCHAR2)
2863   IS
2864      l_return_status VARCHAR2(3);
2865      l_org_id_tb num_tab;
2866      l_item_id_tb num_tab;
2867      l_repl_to_sub_code_tb char_tab;
2868      l_repl_UOM_CODE_tb uom_tab;
2869      l_total_demand_qty_tb num_tab;
2870      l_consol_item_repl_tbl consol_item_repl_tbl;
2871      l_debug NUMBER      := NVL(fnd_profile.VALUE('INV_DEBUG_TRACE'), 0);
2872 
2873      l_msg_count NUMBER;
2874      l_msg_data VARCHAR2(1000);
2875 
2876      CURSOR c_distinct_org_id IS
2877 	SELECT DISTINCT organization_id
2878 	  FROM wms_repl_demand_gtmp
2879 	  WHERE repl_level = p_repl_level;
2880 
2881      CURSOR c_item_repl_cur(v_org_id NUMBER) IS
2882 	SELECT inventory_item_id,
2883 	  sum(quantity_in_repl_uom) as total_demand_qty,
2884 	      repl_to_subinventory_code,
2885 	      repl_uom_code
2886 	      FROM wms_repl_demand_gtmp
2887 	      WHERE organization_id = v_org_id
2888 	      AND repl_level = p_repl_level
2889 	      GROUP BY inventory_item_id, repl_to_subinventory_code,repl_uom_code
2890 	      ORDER BY inventory_item_id, repl_to_subinventory_code;
2891 
2892 BEGIN
2893    l_org_id_tb.DELETE;
2894    l_return_status  := fnd_api.g_ret_sts_success;
2895 
2896    IF (l_debug = 1) THEN
2897       print_debug('Inside API trigger_next_level_repl');
2898    END IF;
2899 
2900    BEGIN
2901       OPEN c_distinct_org_id;
2902       FETCH c_distinct_org_id bulk collect INTO l_org_id_tb;
2903       CLOSE c_distinct_org_id;
2904    EXCEPTION
2905       WHEN OTHERS THEN
2906 	 x_return_status := fnd_api.g_ret_sts_error;
2907 	 DELETE FROM wms_repl_demand_gtmp WHERE repl_level = p_repl_level;
2908 	 IF (l_debug = 1) THEN
2909 	    print_debug('Exception getting orgs:'||p_repl_level);
2910 	 END IF;
2911 	 RETURN;
2912    END;
2913 
2914    FOR j IN 1..l_org_id_tb.COUNT loop
2915       l_item_id_tb.DELETE;
2916       l_total_demand_qty_tb.DELETE;
2917       l_repl_to_sub_code_tb.DELETE;
2918       l_repl_uom_code_tb.DELETE;
2919       BEGIN
2920 
2921 	 SAVEPOINT new_org_sp;
2922 
2923 	 OPEN c_item_repl_cur(l_org_id_tb(j));
2924 	 FETCH c_item_repl_cur BULK COLLECT INTO l_item_id_tb,
2925 	   l_total_demand_qty_tb,
2926 	   l_repl_to_sub_code_tb,l_repl_uom_code_tb;
2927 	 CLOSE c_item_repl_cur;
2928 
2929 	 l_consol_item_repl_tbl.DELETE;
2930 	 IF (l_item_id_tb.count>0) THEN --bug#10185153
2931 		 FOR k IN l_item_id_tb.FIRST .. l_item_id_tb.LAST LOOP
2932 			l_consol_item_repl_tbl(k).Organization_id := l_org_id_tb(j);
2933 			l_consol_item_repl_tbl(k).Item_id := l_item_id_tb(k);
2934 			l_consol_item_repl_tbl(k).total_demand_qty := l_total_demand_qty_tb(k);
2935 			l_consol_item_repl_tbl(k).date_required := sysdate;
2936 
2937 			l_consol_item_repl_tbl(k).available_onhand_qty := 0;
2938 			l_consol_item_repl_tbl(k).open_mo_qty := 0;
2939 			l_consol_item_repl_tbl(k).final_replenishment_qty := 0;
2940 
2941 			l_consol_item_repl_tbl(k).repl_to_subinventory_code := l_repl_to_sub_code_tb(k);
2942 			l_consol_item_repl_tbl(k).repl_uom_code := l_repl_uom_code_tb(k);
2943 
2944 			l_consol_item_repl_tbl(k).final_replenishment_qty:= l_total_demand_qty_tb(k);
2945 		 END LOOP;
2946 	 END IF;
2947 
2948 	 IF l_consol_item_repl_tbl.COUNT <> 0 THEN
2949 	    PROCESS_REPLENISHMENT (
2950 				    P_repl_level              	=> P_repl_level,
2951 				    p_repl_type                 => 2,
2952 				    p_Repl_Lot_Size             => p_Repl_Lot_Size,
2953 				    P_consol_item_repl_tbl      => l_consol_item_repl_tbl,
2954 				    p_Create_Reservation        => 'N',
2955 				    p_Auto_Allocate             => 'Y',
2956 				    p_Plan_Tasks                => p_Plan_Tasks,
2957 				    x_return_status             => l_return_status  ,
2958 				    x_msg_count                 => l_msg_count ,
2959 				    x_msg_data                  => l_msg_data );
2960 
2961 	    IF l_return_status <> 'S' THEN
2962 	       IF (l_debug = 1) THEN
2963 		  print_debug('Error performing replenishment for Multi-step');
2964 	       END IF;
2965 	       ROLLBACK TO new_org_sp;
2966 	       DELETE FROM wms_repl_demand_gtmp
2967 		 WHERE repl_level = p_repl_level
2968 		 AND organization_id = l_org_id_tb(j);
2969 	       GOTO next_org;
2970 	    END IF;
2971 	  ELSE
2972 	    IF (l_debug = 1) THEN
2973 	       print_debug('No Demand Records Identified for this level..Exiting...');
2974 	    END IF;
2975 	 END IF;
2976 
2977 
2978       EXCEPTION
2979 	 WHEN OTHERS THEN
2980 	    IF (l_debug = 1) THEN
2981 	       print_debug('Exception retrieving item repl records for Multi-step');
2982 	    END IF;
2983 	    ROLLBACK TO new_org_sp;
2984 	    DELETE FROM wms_repl_demand_gtmp
2985 	      WHERE repl_level = p_repl_level
2986 	      AND organization_id = l_org_id_tb(j);
2987 	    GOTO next_org;
2988       END;
2989 
2990       <<next_org>>
2991 	NULL;
2992    END LOOP; -- org loop
2993 
2994 
2995    IF l_debug = 1 THEN
2996       print_debug('DONE WITH API trigger_next_level_repl');
2997    END IF;
2998    x_return_status := fnd_api.g_ret_sts_success;
2999 
3000 EXCEPTION
3001    WHEN OTHERS THEN
3002       IF l_debug = 1 THEN
3003 	 print_debug('Exception in trigger_next_level_repl: ' || sqlcode || ', ' || sqlerrm);
3004       END IF;
3005 
3006 END trigger_next_level_repl;
3007 
3008 
3009 PROCEDURE PROCESS_REPLENISHMENT( p_Repl_level           IN NUMBER,
3010 				 p_repl_type            IN NUMBER,
3011 				 p_Repl_Lot_Size        IN NUMBER,
3012 				 P_consol_item_repl_tbl IN OUT NOCOPY CONSOL_ITEM_REPL_TBL,
3013 				 p_Create_Reservation   IN VARCHAR2,
3014 				 p_Auto_Allocate        IN VARCHAR2,
3015 				 p_Plan_Tasks           IN VARCHAR2,
3016 				 x_return_status        OUT NOCOPY VARCHAR2,
3017 				 x_msg_count            OUT NOCOPY NUMBER,
3018 				 x_msg_data             OUT NOCOPY
3019 				 VARCHAR2)
3020   IS
3021 
3022      l_debug              NUMBER      := NVL(fnd_profile.VALUE('INV_DEBUG_TRACE'), 0);
3023      l_temp_cnt NUMBER; -- for debugging only
3024      l_repl_level NUMBER;
3025      l_return_status VARCHAR2(3) := fnd_api.g_ret_sts_success;
3026 
3027 BEGIN
3028    x_return_status := l_return_status;
3029 
3030    -- At this point WMS_REPL_DEMAND_GTMP table should have all the correct demand records and
3031    --l_consol_item_repl_tbl should have all the consolidated quantities grouped by for Item_Id and Repl_To_Subinventory_Code.
3032    -- Now for each entry in the p_consol_item_repl_tbl, get available onhand qty and update records in the p_consol_item_repl_tbl.
3033 
3034    -- it does not make sense to net off onhand/open MOs for
3035    -- next level of Replenishment MOs
3036    -- We would get the quantity after the first level made use
3037    -- of the atr, open MOs and the remaining qty on first level repl
3038    -- MO could not be allocated.
3039    IF (Nvl(p_repl_level,1) = 1) THEN
3040       GET_AVAILABLE_ONHAND_QTY(p_repl_level           => p_repl_level,
3041 			       p_repl_type            => p_repl_type,
3042 			       p_Create_Reservation   => p_Create_Reservation,
3043 			       x_consol_item_repl_tbl => P_consol_item_repl_tbl,
3044 			       x_return_status        => l_return_status,
3045 			       x_msg_count            => x_msg_count,
3046 			       x_msg_data             => x_msg_data);
3047       IF l_return_status <> fnd_api.g_ret_sts_success THEN
3048 	 x_return_status := fnd_api.g_ret_sts_error;
3049 	 RETURN;
3050       END IF;
3051    END IF;
3052 
3053 
3054    -- ==========TEST CODE start ===========
3055    -- for debugging purpise only, entire code should be inside l_debug = 1
3056    IF (l_debug = 1) THEN
3057       IF P_consol_item_repl_tbl.COUNT <> 0 THEN
3058 	 print_debug('*******AFTER GET_AVAILABLE_ONHAND_QTY*******');
3059 
3060 	 FOR i IN  p_consol_item_repl_tbl.FIRST .. p_consol_item_repl_tbl.LAST LOOP
3061 	    IF (NOT p_consol_item_repl_tbl.exists(i)) THEN
3062 	       IF (l_debug = 1) THEN
3063 		  print_debug('CURRENT INDEX IN THE CONSOL TABLE HAS BEEN Discarded - moving TO next consol RECORD' );
3064 	       END IF;
3065 	     ELSE
3066 	       IF (l_debug = 1) THEN
3067 		  print_debug('ITEM_ID,  Total_qty,  available_OH,  open_MO_QTY, Final_repl_qty ');
3068 		  print_debug( p_consol_item_repl_tbl(i).ITEM_ID  || ' , ' ||
3069 			       p_consol_item_repl_tbl(i).total_demand_qty || ' , '||
3070 			       p_consol_item_repl_tbl(i).available_onhand_qty|| ' , '||
3071 			       p_consol_item_repl_tbl(i).open_mo_qty|| ' , '||
3072 			       p_consol_item_repl_tbl(i).final_replenishment_qty);
3073 
3074 	       END IF;
3075 	    END IF;
3076 	 END LOOP;
3077 
3078 	 SELECT COUNT(1) INTO  l_temp_cnt FROM wms_repl_demand_gtmp;
3079 	 IF (l_debug = 1) THEN
3080 	    print_debug(' NUMBER OF RECORDS IN wms_repl_demand_gtmp l_temp_cnt :'||l_temp_cnt);
3081 	 END IF;
3082       END IF;
3083    END IF;
3084 
3085    -- ==========TEST CODE ends ===========
3086 
3087 
3088    -- For Each Item, Net Off on Hand on the Forward Pick Subinventory passed in the program
3089    -- and keep updating l_consol_item_repl_tbl(l_index).final_replenishment_qty as well
3090    -- Now for each entry in the P_consol_item_repl_tbl, get
3091    --Open move order qty and update records in the P_consol_item_repl_tbl.
3092 
3093    -- it does not make sense to net off onhand/open MOs for
3094    -- next level of Replenishment MOs
3095    -- We would get the quantity after the first level made use
3096    -- of the atr, open MOs and the remaining qty on first level repl
3097    -- MO could not be allocated.
3098    IF (Nvl(p_repl_level,1) = 1) THEN
3099       GET_OPEN_MO_QTY(p_repl_level           => p_repl_level,
3100 		      p_repl_type            => p_repl_type,
3101 		      p_Create_Reservation   => p_Create_Reservation,
3102 		      x_consol_item_repl_tbl => P_consol_item_repl_tbl,
3103 		      x_return_status        => l_return_status,
3104 		      x_msg_count            => x_msg_count,
3105 		      x_msg_data             => x_msg_data);
3106       IF l_return_status <> fnd_api.g_ret_sts_success THEN
3107 	 x_return_status := fnd_api.g_ret_sts_error;
3108 	 RETURN;
3109       END IF;
3110    END IF;
3111 
3112 
3113    -- ==========TEST CODE starts ===========
3114    -- for debugging purpise only, entire code should be inside l_debug = 1
3115    IF (l_debug = 1) THEN
3116       IF P_consol_item_repl_tbl.COUNT <> 0 THEN
3117 	 print_debug('********AFTER GET_OPEN_MO_QTY API call*******');
3118 
3119 	 FOR i IN p_consol_item_repl_tbl.FIRST .. p_consol_item_repl_tbl.LAST LOOP
3120 	    IF (NOT p_consol_item_repl_tbl.exists(i)) THEN
3121 	       IF (l_debug = 1) THEN
3122 		  print_debug('CURRENT INDEX IN THE CONSOL TABLE HAS BEEN Discarded - moving TO next consol RECORD' );
3123 	       END IF;
3124 	     ELSE
3125 
3126 	       IF (l_debug = 1) THEN
3127 		  print_debug('ITEM_ID,  Total_qty,  available_OH,  open_MO_QTY, Final_repl_qty ');
3128 		  print_debug( p_consol_item_repl_tbl(i).ITEM_ID  || ' , ' ||
3129 			       p_consol_item_repl_tbl(i).total_demand_qty || ' , '||
3130 			       p_consol_item_repl_tbl(i).available_onhand_qty|| ' , '||
3131 			       p_consol_item_repl_tbl(i).open_mo_qty|| ' , '||
3132 			       p_consol_item_repl_tbl(i).final_replenishment_qty);
3133 
3134 	       END IF;
3135 	    END IF;
3136 	 END LOOP;
3137       END IF;
3138    END IF; -- IF (l_debug = 1) THEN
3139    -- ==========TEST CODE ends ===========
3140 
3141 
3142    --  For Each Item, Net Off Open Move Orders in the Forward Pick Subinventory and keep updating l_consol_item_repl_tbl(l_index).final_replenishment_qty as well
3143    -- At this point P_consol_item_repl_tbl should have total replenishment quantity to create MO for. It is done inside the API - GET_OPEN_MO_QTY().
3144    -- Now create Replenishment Move Orders for effective demand that could not be fulfilled by available onhand or open move order
3145    -- Make sure to upp the replenishment quantity in the
3146    --p_consol_item_repl_tbl(l_index).final_replenishment_qty
3147    -- based on the p_Repl_Lot_Size parameter passed in the program. other
3148    -- parameters p_Create_Reservation, p_Auto_Allocate AND p_Plan_Tasks parameters will be honored inside following call.
3149 
3150 
3151    CREATE_REPL_MOVE_ORDER(p_repl_level           => p_repl_level,
3152 			  p_repl_type            => p_repl_type,
3153 			  P_consol_item_repl_tbl => P_consol_item_repl_tbl,
3154 			  p_Create_Reservation   => p_Create_Reservation,
3155 			  p_Repl_Lot_Size        => p_Repl_Lot_Size,
3156 			  p_Auto_Allocate        => p_Auto_Allocate,
3157 			  p_Plan_Tasks           => p_Plan_Tasks,
3158 			  x_return_status        => l_return_status,
3159 			  x_msg_count            => x_msg_count,
3160 			  x_msg_data             => x_msg_data);
3161    IF l_return_status <> fnd_api.g_ret_sts_success THEN
3162       x_return_status := fnd_api.g_ret_sts_error;
3163       RETURN;
3164    END IF;
3165 
3166 
3167    --TODO : Satish
3168    -- Delete from WMS_REPL_DEMAND_GTMP for current level of replenishment. There might be records remaining in this table for the mext level of replenishment.
3169    -- Trigger next level of replenishment IF
3170    --  Replenishment level < 4  (Ea < CS < PLT < SupPLT)
3171    -- And there are records in the GTMP for the next level. It should have been already inserted by now
3172 
3173 
3174    DELETE FROM wms_repl_demand_gtmp WHERE repl_level=Nvl(p_repl_level,1);
3175 
3176 
3177    x_return_status := 'S';
3178 
3179    --TODO: Blocking Multi-Level Code changes
3180    -- Multi step change
3181    IF ((p_repl_level < 4) AND (p_auto_allocate = 'Y')) THEN
3182 	BEGIN
3183 
3184 	   l_repl_level := Nvl(p_repl_level,1) + 1;
3185    	   COMMIT;
3186 
3187 	   IF (l_debug = 1) THEN
3188 	      print_debug('STARTING THE NEXT LEVEL REPL :'||L_repl_level);
3189 	   END IF;
3190 
3191 
3192 
3193    	   trigger_next_level_repl(p_repl_level => l_repl_level
3194    				   , p_repl_lot_size => p_repl_lot_size
3195    				   , p_plan_tasks => p_plan_tasks
3196    				   , x_return_status => l_return_status);
3197    	EXCEPTION
3198    	   WHEN OTHERS THEN
3199    	      l_return_status := 'E';
3200    	END;
3201    	IF l_return_status <> 'S' THEN
3202    	   DELETE FROM wms_repl_demand_gtmp WHERE repl_level = (Nvl(p_repl_level,1)+1);
3203    	END IF;
3204 
3205    END IF;
3206 
3207 
3208 EXCEPTION
3209    WHEN OTHERS THEN
3210       IF l_debug = 1 THEN
3211 	 print_debug('PROCESS_REPLENISHMENT: Exception block: ' || sqlcode || ', ' || sqlerrm);
3212       END IF;
3213       --
3214       x_return_status := fnd_api.g_ret_sts_unexp_error;
3215       --
3216 END PROCESS_REPLENISHMENT;
3217 
3218 
3219 
3220 
3221 PROCEDURE CREATE_REPL_MOVE_ORDER(p_Repl_level           IN NUMBER,
3222 				 p_repl_type            IN NUMBER,
3223 				 p_consol_item_repl_tbl IN OUT NOCOPY CONSOL_ITEM_REPL_TBL,
3224                                  p_Create_Reservation   IN VARCHAR2,
3225                                  p_Repl_Lot_Size        IN NUMBER,
3226                                  p_Auto_Allocate        IN VARCHAR2,
3227                                  p_Plan_Tasks           IN VARCHAR2,
3228                                  x_return_status        OUT NOCOPY VARCHAR2,
3229                                  x_msg_count            OUT NOCOPY NUMBER,
3230                                  x_msg_data             OUT NOCOPY VARCHAR2
3231 				 )
3232   IS
3233 
3234      -- Note: UI will insure that if p_Create_Reservation  = No then p_Auto_Allocate must be No
3235      -- In case of Push Replenishement, once all replenishment tasks are
3236      -- completed, user will perform pick release manually.
3237      -- Just to keep in mind, we do not distinguish dynamic and push in the Allocate_repl_move_order Conc Request
3238 
3239      l_trohdr_rec       INV_Move_Order_PUB.Trohdr_Rec_Type;
3240      l_trohdr_val_rec   INV_Move_Order_PUB.Trohdr_Val_Rec_Type;
3241      l_x_trohdr_rec     INV_Move_Order_PUB.Trohdr_Rec_Type;
3242      l_x_trohdr_val_rec INV_Move_Order_PUB.Trohdr_Val_Rec_Type;
3243      l_commit           VARCHAR2(1) := FND_API.G_TRUE;
3244 
3245      l_trolin_tbl       INV_Move_Order_PUB.Trolin_Tbl_Type;
3246      l_trolin_val_tbl   INV_Move_Order_PUB.Trolin_Val_Tbl_Type;
3247      l_x_trolin_tbl     INV_Move_Order_PUB.Trolin_Tbl_Type;
3248      l_x_trolin_val_tbl INV_Move_Order_PUB.Trolin_Val_Tbl_Type;
3249 
3250      l_return_status VARCHAR2(1);
3251      l_msg_count     NUMBER;
3252      l_msg_data      VARCHAR2(1000);
3253      l_msg         VARCHAR2(250);
3254      l_plan_tasks BOOLEAN;
3255      l_repl_lot_size_prim NUMBER;
3256 
3257      -- Multi step change
3258      l_source_sub_atr NUMBER;
3259      l_create_qty NUMBER;
3260      l_prev_item_id NUMBER;
3261      l_prev_sub_code VARCHAR2(10);
3262 
3263      l_item_id_tb num_tab;
3264      l_org_id_tb num_tab;
3265      l_demand_header_id_tb num_tab;
3266      l_demand_line_id_tb num_tab;
3267      l_demand_type_id_tb num_tab;
3268      l_requested_quantity_tb num_tab;
3269      l_requested_quantity_uom_tb uom_tab;
3270      l_quantity_in_repl_uom_tb num_tab;
3271      l_expected_ship_date_tb date_tab;
3272      l_repl_to_sub_code_tb char_tab;
3273      l_repl_UOM_CODE_tb uom_tab;
3274      l_next_repl_cntr NUMBER := 0;
3275 
3276      l_del_index NUMBER;
3277      l_del_consol_item_tb num_tab;
3278 
3279      l_src_sub     VARCHAR2(10);
3280      l_order_count NUMBER ;
3281 
3282      l_demand_header_id            NUMBER;
3283      L_demand_line_id              NUMBER;
3284      L_demand_line_detail_id       NUMBER;
3285      L_demand_quantity             NUMBER;
3286      L_demand_quantity_in_repl_uom NUMBER;
3287      L_demand_uom_code             VARCHAR2(3);
3288      L_demand_type_id              NUMBER;
3289      L_sequence_id                 NUMBER;
3290      l_expected_ship_date          date;
3291      l_repl_level                  NUMBER;
3292      l_repl_type                   NUMBER;
3293 
3294      l_repl_UOM_code               VARCHAR2(3);
3295      l_Repl_Lot_Size               NUMBER;
3296 
3297      l_rsv_tbl_tmp    inv_reservation_global.mtl_reservation_tbl_type;
3298      l_rsv_rec            inv_reservation_global.mtl_reservation_tbl_type;
3299      l_serial_number      inv_reservation_global.serial_number_tbl_type;
3300      l_to_serial_number   inv_reservation_global.serial_number_tbl_type;
3301      l_quantity_reserved  NUMBER;
3302      l_quantity_reserved2 NUMBER;
3303      l_rsv_id             NUMBER;
3304      l_error_code         NUMBER;
3305      l_mo_uom_code        VARCHAR2(3);
3306 
3307      l_detail_info_tab             WSH_INTERFACE_EXT_GRP.delivery_details_Attr_tbl_Type;
3308      l_in_rec                      WSH_INTERFACE_EXT_GRP.detailInRecType;
3309      l_out_rec                     WSH_INTERFACE_EXT_GRP.detailOutRecType;
3310 
3311      l_rsv_temp_rec   inv_reservation_global.mtl_reservation_rec_type;
3312      l_rsv_temp_rec_2 inv_reservation_global.mtl_reservation_rec_type;
3313      l_line_num           NUMBER  ;
3314 
3315      l_debug number := NVL(FND_PROFILE.VALUE('INV_DEBUG_TRACE'),0);
3316 
3317      l_index                 NUMBER;
3318      l_prev_org_id           NUMBER;
3319      l_MAX_MINMAX_QUANTITY   NUMBER;
3320      l_mtl_reservation_count NUMBER;
3321      l_fixed_lot_multiple    NUMBER;
3322      l_src_pick_uom          VARCHAR2(3);
3323      l_txn_prim_qty          NUMBER;
3324 
3325 
3326      -- For bulk upload in the WRD table
3327      l_organization_id_tab  num_tab;
3328      l_mo_header_id_tab  num_tab;
3329      l_mo_line_id_tab  num_tab;
3330      l_demand_header_id_tab  num_tab;
3331      l_demand_line_id_tab  num_tab;
3332      l_demand_line_detail_id_tab  num_tab;
3333      l_demand_type_id_tab  num_tab;
3334      l_item_id_tab  num_tab;
3335      l_demand_uom_code_tab  uom_tab;
3336      l_demand_quantity_tab  num_tab;
3337      l_sequence_id_tab  num_tab;
3338      l_repl_level_tab  num_tab;
3339      l_repl_type_tab  num_tab;
3340 
3341      l_conversion  NUMBER;
3342 
3343      l_quantity_detailed NUMBER;
3344      l_quantity_detailed_conv NUMBER;
3345      l_num_detail_recs NUMBER;
3346      l_prim_quantity_detailed NUMBER;
3347      l_mo_line_id NUMBER;
3348      l_task_id NUMBER;
3349 
3350      CURSOR c_demand_lines_for_item(p_org_id NUMBER, p_item_id number, P_FP_SUB VARCHAR2) IS
3351 	Select repl_sequence_id,
3352 	  demand_header_id,
3353 	  demand_line_id,
3354 	  demand_line_detail_id,
3355 	  demand_type_id,
3356 	  quantity,
3357 	  uom_code,
3358 	  expected_ship_date,
3359 	  quantity_in_repl_uom,
3360 	  repl_uom_code,
3361 	  Nvl(repl_level,1),
3362 	  repl_type
3363 	  FROM WMS_REPL_DEMAND_GTMP
3364 	  WHERE ORGANIZATION_ID = p_org_id
3365 	  AND inventory_item_id = p_item_id
3366 	  AND REPL_TO_SUBINVENTORY_CODE = P_FP_SUB
3367 	  order by Repl_Sequence_id;
3368 
3369      CURSOR c_mmtt_rec IS
3370       SELECT transaction_temp_id
3371         FROM mtl_material_transactions_temp
3372 	WHERE move_order_line_id = l_mo_line_id;
3373 
3374 BEGIN
3375    --Note: by the time this API is called p_consol_item_repl_tbl(i).final_replenishment_qty
3376    -- will store the Correct qty (rounded up) to create replenishment MO for each Item
3377 
3378    l_src_sub := NULL;
3379 
3380    l_trohdr_rec.created_by             := fnd_global.user_id;
3381    l_trohdr_rec.creation_date          := sysdate;
3382    l_trohdr_rec.header_status          := INV_Globals.g_to_status_preapproved;
3383    l_trohdr_rec.last_updated_by        := fnd_global.user_id;
3384    l_trohdr_rec.last_update_date       := sysdate;
3385    l_trohdr_rec.last_update_login      := fnd_global.user_id;
3386    l_trohdr_rec.organization_id        := NULL; -- assigned inside the loop
3387    l_trohdr_rec.status_date            := sysdate;
3388    l_trohdr_rec.move_order_type        := INV_GLOBALS.G_MOVE_ORDER_REPLENISHMENT;
3389    l_trohdr_rec.transaction_type_id    := INV_GLOBALS.G_TYPE_TRANSFER_ORDER_SUBXFR;
3390    l_trohdr_rec.operation              := INV_GLOBALS.G_OPR_CREATE;
3391    l_trohdr_rec.db_flag                :=   FND_API.G_TRUE;
3392 
3393    -- Multi step change
3394    l_item_id_tb.DELETE;
3395    l_org_id_tb.DELETE;
3396    l_demand_header_id_tb.DELETE;
3397    l_demand_line_id_tb.DELETE;
3398    l_demand_type_id_tb.DELETE;
3399    l_requested_quantity_tb.DELETE;
3400    l_requested_quantity_uom_tb.DELETE;
3401    l_quantity_in_repl_uom_tb.DELETE;
3402    l_expected_ship_date_tb.DELETE;
3403    l_repl_to_sub_code_tb.DELETE;
3404    l_repl_uom_code_tb.DELETE;
3405    l_next_repl_cntr := 1;
3406 
3407 
3408    IF l_debug = 1 THEN
3409       print_debug('Inside the API CREATE_REPL_MOVE_ORDER');
3410    END IF;
3411 
3412    l_del_index := 0;
3413    IF (p_consol_item_repl_tbl.count>0) THEN --bug#10185153
3414    FOR i IN p_consol_item_repl_tbl.FIRST.. p_consol_item_repl_tbl.LAST LOOP
3415 
3416 
3417       IF (NOT p_consol_item_repl_tbl.exists(i)) THEN
3418 
3419 	 IF (l_debug = 1) THEN
3420 	    print_debug('CURRENT INDEX IN THE CONSOL TABLE HAS BEEN Discarded - moving TO next consol RECORD' );
3421 
3422 	 END IF;
3423        ELSE
3424 
3425 
3426 
3427 	 IF l_debug = 1 THEN
3428 	    print_debug('Final Replenishment Qty for item - '|| p_consol_item_repl_tbl(i).Item_id
3429 			||' ,Qty : '||p_consol_item_repl_tbl(i).final_replenishment_qty);
3430 	 END IF;
3431 
3432       IF p_consol_item_repl_tbl(i).final_replenishment_qty <= 0 THEN
3433 
3434 	 IF l_debug = 1 THEN
3435 	    print_debug('No Need of Replenishment for this Item....Moving to next consol Item');
3436 	 END IF;
3437 
3438        ELSE
3439 
3440 	 --******* Create Move Order Header per organization ******
3441 	 -- Per organization, create a single MO header for all items. p_consol_item_repl_tbl has recorde ordered by
3442 	 -- organization_id
3443 
3444 	 IF (l_prev_org_id IS NULL) OR (l_prev_org_id <> p_consol_item_repl_tbl(i).organization_id) THEN
3445 	    --values for other parameters for header as same so assigned outside the loop
3446 
3447 	    l_trohdr_rec.organization_id := p_consol_item_repl_tbl(i).organization_id;
3448 
3449 	    -- Create MO Header
3450 	    IF l_debug = 1 THEN
3451 	       print_debug('CALLING INV_Move_Order_PUB.Create_Move_Order_Header');
3452 	    END IF;
3453 
3454 	    INV_Move_Order_PUB.Create_Move_Order_Header(p_api_version_number => 1.0,
3455 							p_init_msg_list      => FND_API.G_FALSE,
3456 							p_return_values      => FND_API.G_TRUE,
3457 							p_commit             => l_commit,
3458 							x_return_status      => l_return_status,
3459 							x_msg_count          => l_msg_count,
3460 							x_msg_data           => l_msg_data,
3461 							p_trohdr_rec         => l_trohdr_rec,
3462 							p_trohdr_val_rec     => l_trohdr_val_rec,
3463 							x_trohdr_rec         => l_x_trohdr_rec,
3464 							x_trohdr_val_rec     => l_x_trohdr_val_rec,
3465 							p_validation_flag    => inv_move_order_pub.g_validation_yes
3466 							);
3467 
3468 
3469 	    IF l_debug = 1 THEN
3470 	       print_debug('After Calling Create_Move_Order_Header');
3471 	    END IF;
3472 
3473 	    IF l_return_status = FND_API.G_RET_STS_ERROR THEN
3474 	       IF l_debug = 1 THEN
3475 		  print_debug('Creating MO Header failed with unexpected error returning message: ' ||
3476 			      l_msg_data);
3477 	       END IF;
3478 	       RAISE fnd_api.g_exc_unexpected_error;
3479 	       -- If cant create a common MOH, do no repl stuff
3480 	     ELSIF l_return_status = FND_API.G_RET_STS_UNEXP_ERROR THEN
3481 	       IF l_debug = 1 THEN
3482 		  print_debug('Creating MO Header failed with expected error returning message: ' ||
3483 			      l_msg_data);
3484 	       END IF;
3485 	       RAISE fnd_api.g_exc_error;
3486 	       -- If cant create a common MOH, do no repl stuff
3487 	     ELSE
3488 	       IF l_debug = 1 THEN
3489 		  print_debug('Creating MO Header returned success with MO Header Id: ' || l_x_trohdr_rec.header_id);
3490 	       END IF;
3491 	    END IF;
3492 
3493 	    --set line number for MO lines under this header
3494 	    l_line_num := 0;
3495 
3496 	 END IF; --Create MO header per organization
3497 
3498 	 --******* Create Move Order Line for a mover order header in an organization ******
3499 	 -- Create MO Lines for all Items in the pl/sql table under the same MO header for an organization
3500 	 -- Create replenishment MO lines only if the quantity can not be fulfilled by available OH or Open MO
3501 
3502 	 SAVEPOINT Current_MOL_SP;
3503 
3504 	 -- Get the source sub from the item+sub desktop form for the Front Pick Sub OR let rules
3505 	 -- engine decide while performing allocation
3506          IF l_debug = 1 THEN
3507 	    print_debug('Calling Get_Source_Sub_Dest_Loc_Info....');
3508 	 END IF;
3509 	 -- Get source sub and loc information for the repl MO, if available
3510 	 l_return_status := fnd_api.g_ret_sts_success;
3511 	 Get_Source_Sub_Dest_Loc_Info(p_Org_id              => p_consol_item_repl_tbl(i).ORGANIZATION_ID,
3512 				      p_Item_id             => p_consol_item_repl_tbl(i).Item_id,
3513 				      p_Picking_Sub         => p_consol_item_repl_tbl(i).Repl_To_Subinventory_code,
3514 				      x_source_sub          => l_src_sub,
3515 				      x_src_pick_uom        => l_src_pick_uom,
3516 				      x_MAX_MINMAX_QUANTITY => l_MAX_MINMAX_QUANTITY,
3517 				      x_fixed_lot_multiple  => l_fixed_lot_multiple,
3518 				      x_return_status       => l_return_status);
3519 
3520 	 IF l_return_status <> fnd_api.g_ret_sts_success THEN
3521 	    GOTO next_consol_rec;
3522 	 END IF;
3523 
3524 	 -- Final Replenishment Quantity = Maximum of min-max qty + Sum of
3525 	 -- unallocated demand + Sum of Allocated but not executed tasks
3526 	 -- Available On Hand - Sum of unallocated replenishment move orders with destination sub ] .
3527 
3528 	 --By the time, code comes at this point, last 2 are already
3529 	 --subtracted. Maximum of min-max qty should alWays be in the fixed
3530 	 --lot multiple. It is restrained by the UI on the item-sub form
3531 
3532 	 p_consol_item_repl_tbl(i).final_replenishment_qty :=
3533 	   p_consol_item_repl_tbl(i).final_replenishment_qty + L_MAX_MINMAX_QUANTITY;
3534 
3535 	 IF l_debug = 1 THEN
3536 	    print_debug('getting right qty and uom for the move order line creation' );
3537 	    print_debug('Current Final Qty: '||p_consol_item_repl_tbl(i).final_replenishment_qty);
3538 	 END IF;
3539 
3540 	 -- For DYNAMIC REPL, How to stamp the qty and UOM on the newly created Replenishment Move Order
3541 	 --example:
3542 	 -- Destination Sub = CASE (Pick_UOM = CS)
3543 	 -- 1CS = 10 Ea
3544 	 -- Final calculated Repl Qty = 3CS
3545 	 --
3546 	 -- Fixed-Lot-multiplier(200 ea)	Src-sub(bulk)	Pick-uom-Src-sub (PLT=100 Ea)	Example (Qty ON repl mo)
3547 	 -- Y	                            Y                       	Y		2PLT
3548 	 -- Y	                            y                          	N		20CS
3549 	 -- n                                 y                   	y       	1PLT
3550 	 -- n                                 y                   	n       	10CS
3551 	 -- n                                 n             	Not applicable   	3CS
3552 	 --
3553 
3554 	 -- If open MO and available Onhand can offset the current demand, then do not create Replenishment MO for those records
3555 	 IF p_consol_item_repl_tbl(i).final_replenishment_qty > 0 THEN
3556 
3557 	    -- Upp the replenishment qty appropriately
3558 
3559 	    --set the item info in cache
3560 	    IF inv_cache.set_item_rec(p_consol_item_repl_tbl(i).ORGANIZATION_ID, p_consol_item_repl_tbl(i).item_id) THEN
3561 
3562 	       -- for Dynamic replenishment or next level repl, p_Repl_Lot_Size will be passed as NULL
3563 	       IF p_repl_lot_size IS NULL THEN
3564 		  IF l_debug = 1 THEN
3565 		     print_debug('repl_lot_size is NULL, Either Dynamic Or Next LEVEL Repl');
3566 		  END IF;
3567 
3568 		  -- means final qty and uom code need to change with following condition
3569 		  IF l_fixed_lot_multiple <> -1 OR (l_src_pick_uom IS NOT NULL AND
3570 						    l_src_pick_uom <> p_consol_item_repl_tbl(i).repl_uom_code) THEN
3571 
3572 
3573 
3574 		     IF l_fixed_lot_multiple <> -1 THEN
3575 			l_repl_lot_size_prim := l_fixed_lot_multiple;
3576 
3577 			-- If lot multiplier is specified and src_pick_uom IS specified
3578 			-- The qty should be tracked in src_pick_uom
3579 			IF l_src_pick_uom IS NOT NULL THEN  -- pushing with bug 7201888
3580 			   l_conversion := ROUND(get_conversion_rate(p_consol_item_repl_tbl(i).Item_id,
3581 								       l_src_pick_uom,
3582 								     inv_cache.item_rec.primary_uom_code),
3583 						 g_conversion_precision);
3584 
3585 			END IF;
3586 
3587 		      ELSIF l_src_pick_uom IS NOT NULL THEN
3588 			-- GET THE MULITPLE OF THE "UNIT QTY CONVERSION OF the source sub pick UOM"
3589 			l_conversion := ROUND(get_conversion_rate(p_consol_item_repl_tbl(i).Item_id,
3590 									  l_src_pick_uom,
3591 									  inv_cache.item_rec.primary_uom_code),
3592 						      g_conversion_precision);
3593 
3594 
3595 			IF l_debug = 1 THEN
3596 			   print_debug('Unit Conversion qty for Source UOM :'||l_conversion);
3597 			END IF;
3598 
3599 			-- what if UOM conversion not defined
3600 			IF l_conversion  > 0 THEN
3601 			   l_repl_lot_size_prim := l_conversion;
3602 			END IF;
3603 		     END IF; -- IF l_fixed_lot_multiple <> -1
3604 
3605 
3606 		     IF l_debug = 1 THEN
3607 			print_debug('Value of repl_lot_size in Primary UOM: '||l_repl_lot_size_prim);
3608 		     END IF;
3609 
3610 		     -- GET THE FINAL PRIMARY MOVE ORDER QTY
3611 		     -- This UOM conversion will be defined, otherwise code
3612 		     -- will not come here, repl_uom_code in consol table
3613 		     -- would not have been marked otherwise
3614 		     l_txn_prim_qty :=
3615 		       ROUND((p_consol_item_repl_tbl(i).final_replenishment_qty * get_conversion_rate(p_consol_item_repl_tbl(i).Item_id,
3616 									 p_consol_item_repl_tbl(i).repl_uom_code,
3617 									inv_cache.item_rec.primary_uom_code)),
3618 			     g_conversion_precision);
3619 
3620 		     -- UPP the PRIMARY QTY in the INTEGRAL MULITPLE of l_repl_lot_size_prim
3621 		     -- to habndle the case in which Repl_Lot_Size is exact multiple of repl qty
3622 		     IF MOD(l_txn_prim_qty,l_Repl_Lot_Size_prim) <> 0 THEN
3623 			l_txn_prim_qty :=  l_repl_lot_size_prim * (1 + FLOOR(l_txn_prim_qty/l_repl_lot_size_prim));
3624 		     END IF;
3625 
3626 
3627 		     -- Now take care of stamping right UOM and updated qty
3628 		     IF (l_src_pick_uom IS NOT NULL)  THEN
3629 			IF l_conversion  > 0 THEN
3630 			   -- convert the final qty into apporopriate qty based on l_src_pick_uom
3631 			   p_consol_item_repl_tbl(i).final_replenishment_qty :=
3632 			     ROUND((l_txn_prim_qty * get_conversion_rate(p_consol_item_repl_tbl(i).Item_id,
3633 									 inv_cache.item_rec.primary_uom_code,
3634 									 l_src_pick_uom )),
3635 				   g_conversion_precision);
3636 
3637 			   -- UPDATE THE UOM CODE AS WELL
3638 			   p_consol_item_repl_tbl(i).repl_uom_code := l_src_pick_uom;
3639 			END IF;
3640 
3641 		      ELSE -- means source sub UOM code is not available
3642 			--ADJUST THE INCREASED QTY IN THE p_consol_item_repl_tbl(i).repl_uom_code uom only
3643 			IF l_conversion  > 0 THEN
3644 			   p_consol_item_repl_tbl(i).final_replenishment_qty :=
3645 			     ROUND((l_txn_prim_qty * get_conversion_rate(p_consol_item_repl_tbl(i).Item_id,
3646 									 inv_cache.item_rec.primary_uom_code,
3647 									 p_consol_item_repl_tbl(i).Repl_UOM_Code )),
3648 				   g_conversion_precision);
3649 
3650 			   -- UOM_CODE remains same here
3651 			END IF; --	IF l_conversion  > 0
3652 		     END IF; --IF (l_src_pick_uom IS NOT NULL)
3653 
3654 		  END IF; -- means final qty and uom code need TO CHANGE
3655 
3656 
3657 		ELSE -- means p_repl_lot_size IS NOT NULL, First level of PUSH Replenishment
3658 		  -- For Push Replenishment NULL value for p_Repl_Lot_Size will be treated as 1
3659 		  IF p_Repl_Lot_Size IS NULL THEN
3660 		     L_Repl_Lot_Size := 1;
3661 		   ELSE
3662 		     L_Repl_Lot_Size := p_Repl_Lot_Size;
3663 		  END IF;
3664 
3665 		  -- to habndle the case in which Repl_Lot_Size is exact multiple of repl qty
3666 		  IF MOD(p_consol_item_repl_tbl(i).final_replenishment_qty,l_Repl_Lot_Size) <> 0 THEN
3667 
3668 		     p_consol_item_repl_tbl(i).final_replenishment_qty :=
3669 		       l_Repl_Lot_Size * (1 + FLOOR(p_consol_item_repl_tbl(i).final_replenishment_qty / l_Repl_Lot_Size));
3670 		  END IF;
3671 	       END IF; -- for p_repl_lot_size IS NOT NULL
3672 
3673 	    END IF; -- FOR inv_cache.set_item_rec
3674 
3675 	  ELSE  -- menas final_replenishment_qty <= 0
3676 	    -- Mark negative qty to avoid further considerations and creating MO
3677 	    p_consol_item_repl_tbl(i).final_replenishment_qty := -9999;
3678 
3679 	 END IF;  --for final_replenishment_qty > 0
3680 
3681 
3682 
3683 
3684 	 IF l_debug = 1 THEN
3685 	    print_debug('After Upp qty by Repl_Lot_Size, Final Repl qty :'||
3686 			p_consol_item_repl_tbl(i).final_replenishment_qty);
3687 	    print_debug('After Upp qty by Repl_Lot_Size, Final UOM CODE :'||
3688 			p_consol_item_repl_tbl(i).repl_uom_code);
3689 	 END IF;
3690 
3691 
3692 	 -- While creating the MO, we have decided NOT to check for
3693 	 -- availability of item. Even if the qty is available now, still. create	repl MO.
3694 	 -- Customer might be expecting some shipment and he would like Move Order to be already created.
3695 
3696 	 -- We do not create MO lines qty in the multiple of 'fixed lot multiple' specified on the Item-sub form.
3697 	 --It will create too many move order lines and will end up having
3698 	 --remaining left over quantities with lot of lines.
3699 	 --Instead let rules engine allocate in that fashion if needed.
3700 
3701 	 IF p_consol_item_repl_tbl(i).final_replenishment_qty <> -9999 THEN
3702 
3703 	    l_trolin_tbl.DELETE;
3704 	    l_order_count:= 1;
3705 
3706 	    -- Create MO Lines
3707 	    IF l_debug = 1 THEN
3708 	       print_debug('CALLING INV_Move_Order_PUB.Create_Move_Order_Lines');
3709 	    END IF;
3710 	    l_line_num := l_line_num + 1;
3711 	    l_trolin_tbl(l_order_count).header_id := l_x_trohdr_rec.header_id;
3712 	    l_trolin_tbl(l_order_count).created_by := fnd_global.user_id;
3713 	    l_trolin_tbl(l_order_count).creation_date := sysdate;
3714 	    l_trolin_tbl(l_order_count).date_required := p_consol_item_repl_tbl(i).date_required;
3715 	    l_trolin_tbl(l_order_count).from_subinventory_code := l_src_sub;
3716 	    l_trolin_tbl(l_order_count).line_number             := l_line_num;
3717 	    l_trolin_tbl(l_order_count).inventory_item_id := p_consol_item_repl_tbl(i).Item_id;
3718 	    l_trolin_tbl(l_order_count).last_updated_by := fnd_global.user_id;
3719 	    l_trolin_tbl(l_order_count).last_update_date := sysdate;
3720 	    l_trolin_tbl(l_order_count).last_update_login := fnd_global.user_id;
3721 	    l_trolin_tbl(l_order_count).line_status := INV_Globals.g_to_status_preapproved;
3722 	    l_trolin_tbl(l_order_count).organization_id := p_consol_item_repl_tbl(i).ORGANIZATION_ID;
3723 	    l_trolin_tbl(l_order_count).quantity := p_consol_item_repl_tbl(i).final_replenishment_qty;
3724 	    l_trolin_tbl(l_order_count).uom_code := p_consol_item_repl_tbl(i).Repl_UOM_Code;
3725 	    l_trolin_tbl(l_order_count).status_date := sysdate;
3726 	    l_trolin_tbl(l_order_count).to_subinventory_code := p_consol_item_repl_tbl(i).Repl_To_Subinventory_code;
3727 	    l_trolin_tbl(l_order_count).to_locator_id := NULL; -- Let Rule engine decide based ON avail_capacity
3728 	    l_trolin_tbl(l_order_count).transaction_source_type_id :=INV_GLOBALS.G_SOURCETYPE_MOVEORDER; -- 4
3729 	    l_trolin_tbl(l_order_count).transaction_type_id := INV_GLOBALS.G_TYPE_TRANSFER_ORDER_SUBXFR;
3730 	    l_trolin_tbl(l_order_count).db_flag := FND_API.G_TRUE;
3731 	    l_trolin_tbl(l_order_count).operation := INV_GLOBALS.G_OPR_CREATE;
3732 
3733 			--Begin 12396907
3734 			 IF inv_cache.set_item_rec(p_consol_item_repl_tbl(i).ORGANIZATION_ID, p_consol_item_repl_tbl(i).item_id) THEN
3735 
3736 				IF (inv_cache.item_rec.tracking_quantity_ind = 'PS') THEN
3737 					l_trolin_tbl(l_order_count).secondary_uom := inv_cache.item_rec.secondary_uom_code;--12396907
3738 					l_trolin_tbl(l_order_count).secondary_quantity := ROUND(
3739 										(p_consol_item_repl_tbl(i).final_replenishment_qty * get_conversion_rate(p_consol_item_repl_tbl(i).Item_id,
3740 									     p_consol_item_repl_tbl(i).repl_uom_code,
3741 									     inv_cache.item_rec.secondary_uom_code)),
3742 										 g_conversion_precision);--12396907
3743 
3744 				END IF;
3745 			 END IF;
3746 
3747 			IF l_debug = 1 THEN
3748 				print_debug('The values after conversion for secondary UOM'|| l_trolin_tbl(l_order_count).secondary_uom);
3749 				print_debug('The values after conversion for secondary quantity'|| l_trolin_tbl(l_order_count).secondary_quantity);
3750 			END IF;
3751 			--End 12396907
3752 
3753 	    -- NO NEED TO CALL THIS API FOR EACH LINE. STORE ALL LINES FOR A
3754 	    -- mo header IN THE l_trolin_tbl TABLE AND THEN CALL ONLY ONCE FOR
3755 	    -- PERFORMACE REASON. THEN FOR EACH MO LINE FROM THE SAME TABLE,
3756 	    -- CREATE RESERVATION FOR CORRESPONDING DEMAND LINES, IF NEEDED
3757 	    l_return_status := fnd_api.g_ret_sts_success;
3758 	    INV_Move_Order_PUB.Create_Move_Order_Lines(
3759 						       p_api_version_number => 1.0,
3760 						       p_init_msg_list  => FND_API.G_FALSE,
3761 						       p_commit         => FND_API.G_FALSE, --BUG14504260
3762 						       x_return_status  => l_return_status,
3763 						       x_msg_count      => l_msg_count,
3764 						       x_msg_data       => l_msg_data,
3765 						       p_trolin_tbl     => l_trolin_tbl,
3766 						       p_trolin_val_tbl => l_trolin_val_tbl,
3767 						       x_trolin_tbl     => l_x_trolin_tbl,
3768 						       x_trolin_val_tbl => l_x_trolin_val_tbl,
3769 						       p_validation_flag     => 'Y'  );
3770 
3771 
3772 	    IF L_DEBUG = 1 THEN
3773 	       print_debug('After call to INV_Move_Order_PUB.Create_Move_Order_Lines');
3774 	    END IF;
3775 
3776 	    IF l_return_status = FND_API.G_RET_STS_ERROR THEN
3777 
3778 	       IF L_DEBUG = 1 THEN
3779 		  print_debug('INV_Move_Order_PUB.Create_Move_Order_Lines failed with expected error returning message: ' || l_msg_data || l_msg_count);
3780 	       END IF;
3781 	       IF l_msg_count > 0 THEN
3782 		  FOR i in 1 .. l_msg_count LOOP
3783 		     l_msg := fnd_msg_pub.get(i, 'F');
3784 		     print_debug(l_msg);
3785 		     fnd_msg_pub.delete_msg(i);
3786 		  END LOOP;
3787 	       END IF;
3788 	       l_line_num := l_line_num - 1;
3789 	       l_trolin_tbl.DELETE(l_order_count);
3790 	       GOTO next_consol_rec;
3791 	     ELSIF l_return_status = FND_API.G_RET_STS_UNEXP_ERROR THEN
3792 	       IF L_DEBUG= 1 THEN
3793 		  print_debug('INV_Move_Order_PUB.Create_Move_Order_Lines failed with unexpected error returning message: ' || l_msg_data);
3794 	       END IF;
3795 
3796 	       IF l_msg_count > 0 THEN
3797 		  FOR i in 1 .. l_msg_count LOOP
3798 		     l_msg := fnd_msg_pub.get(i, 'F');
3799 		     print_debug(l_msg);
3800 		     fnd_msg_pub.delete_msg(i);
3801 		  END LOOP;
3802 	       END IF;
3803 	       l_line_num := l_line_num - 1;
3804 	       l_trolin_tbl.DELETE(l_order_count);
3805 	       GOTO next_consol_rec;
3806 	     ELSE
3807 	       IF L_DEBUG = 1 THEN
3808 		  print_debug('INV_Move_Order_PUB.Create_Move_Order_Lines returned success');
3809 	       END IF;
3810 	    END IF;
3811 
3812 
3813 
3814 	    IF p_Create_Reservation = 'Y'  THEN --and  Nvl(repl_level,1) = 1 THEN
3815 	       IF L_DEBUG = 1 THEN
3816 		  print_debug('******Create_Reservation = Y and  repl_LEVEL = 1');
3817 	       END IF;
3818 	       l_index := 1;
3819 
3820 	       -- Loop through all demand lines for the repl MO and Create rsv
3821 	       -- At this point, for an item, sum (quantity) for demand lines in the GTMP table should be in sync with mol_qty
3822 	       OPEN c_demand_lines_for_item(p_consol_item_repl_tbl(i).ORGANIZATION_ID, p_consol_item_repl_tbl(i).item_id, p_consol_item_repl_tbl(i).repl_to_subinventory_code);
3823 
3824 	       LOOP
3825 		  FETCH c_demand_lines_for_item INTO
3826 		    L_sequence_id, L_demand_header_id,
3827 		    L_demand_line_id,
3828 		    L_demand_line_detail_id, l_demand_type_id,
3829 		    L_demand_quantity,
3830 		    L_demand_uom_code, l_expected_ship_date,
3831 		    l_demand_quantity_in_repl_uom, l_repl_uom_code,
3832 		    l_repl_level, l_repl_type;
3833 		  EXIT WHEN c_demand_lines_for_item%notfound;
3834 
3835 		  IF L_DEBUG = 1 THEN
3836 		     print_debug('Fetch the Demand Line detail id: '|| L_demand_line_detail_id);
3837 		     print_debug('Check if reservation exists');
3838 		  END IF;
3839 
3840 		  -- Create Org Level reservation for every demand line, if it does not exist
3841 
3842 		  -- Check if an Org level reservation exists for corresponding order line
3843 		  -- Clear out old values
3844 		  l_rsv_temp_rec := l_rsv_temp_rec_2;
3845 
3846 		  -- Assign all new values
3847 		  l_rsv_temp_rec.organization_id := p_consol_item_repl_tbl(i).ORGANIZATION_ID;
3848 		  l_rsv_temp_rec.inventory_item_id := p_consol_item_repl_tbl(i).item_id;
3849 		  l_rsv_temp_rec.DEMAND_SOURCE_TYPE_ID := l_demand_type_id;
3850 		  l_rsv_temp_rec.DEMAND_SOURCE_HEADER_ID := l_demand_header_id;
3851 		  l_rsv_temp_rec.DEMAND_SOURCE_LINE_ID := l_demand_line_id;
3852 
3853 		  l_return_status := fnd_api.g_ret_sts_success;
3854 		  inv_reservation_pub.query_reservation(p_api_version_number =>1.0,
3855 							x_return_status => l_return_status,
3856 							x_msg_count   => x_msg_count,
3857 							x_msg_data    => x_msg_data,
3858 							p_query_input => l_rsv_temp_rec,
3859 							x_mtl_reservation_tbl  => l_rsv_rec,
3860 							x_mtl_reservation_tbl_count => l_mtl_reservation_count,
3861 							x_error_code => l_error_code);
3862 
3863 		  IF l_RETURN_status = fnd_api.g_ret_sts_success THEN
3864 		     IF L_DEBUG = 1 THEN
3865 			PRINT_DEBUG('Number of reservations found: ' || l_mtl_reservation_count);
3866 		     END IF;
3867 		   ELSE
3868 		     IF L_DEBUG = 1 THEN
3869 			PRINT_DEBUG('Error: ' || X_msg_data);
3870 		     END IF;
3871 		     l_line_num := l_line_num - 1;
3872 		     l_trolin_tbl.DELETE(l_order_count);
3873 		     GOTO next_consol_rec;
3874 		  END IF;
3875 
3876 		  -- If no org level reservation found then create it
3877 
3878 		  IF l_mtl_reservation_count = 0 then
3879 		     -- Create high-level reservation
3880 		     IF L_DEBUG = 1 THEN
3881 			PRINT_DEBUG('Calling Create_RSV >>>');
3882 		     END IF;
3883 		     l_return_status := fnd_api.g_ret_sts_success;
3884 		     Create_RSV(p_replenishment_type => 1, --  1- Stock Up/Push; 2- Dynamic/Pull
3885 				l_debug => l_debug,
3886 				l_organization_id => p_consol_item_repl_tbl(i).ORGANIZATION_ID,
3887 				l_inventory_item_id => p_consol_item_repl_tbl(i).item_id,
3888 				l_demand_type_id => l_demand_type_id,
3889 				l_demand_so_header_id => L_demand_header_id,
3890 				l_demand_line_id => L_demand_line_id,
3891 				l_split_wdd_id => NULL,
3892 				l_primary_uom_code => l_demand_uom_code,
3893 				l_supply_uom_code => l_demand_uom_code, -- 13942999
3894 				l_atd_qty => L_demand_quantity,
3895 				l_atd_prim_qty => L_demand_quantity,
3896 				l_supply_type_id => 13,
3897 				l_supply_header_id => NULL, -- since high level rsv
3898 				l_supply_line_id => NULL, -- since high level rsv
3899 				l_supply_line_detail_id => NULL, -- since high level rsv
3900 				l_supply_expected_time => SYSDATE,
3901 				l_demand_expected_time => l_expected_ship_date,
3902 				l_rsv_rec => l_rsv_temp_rec, -- only need to provide good enough information FOR high LEVEL reservation, only one row will do
3903 		       l_serial_number => l_serial_number,
3904 		       l_to_serial_number => l_to_serial_number,
3905 		       l_quantity_reserved => l_quantity_reserved,
3906 		       l_quantity_reserved2 => l_quantity_reserved2,
3907 		       l_rsv_id => l_rsv_id,
3908 		       x_return_status => l_return_status,
3909 		       x_msg_count => x_msg_count,
3910 		       x_msg_data => x_msg_data
3911 		       );
3912 
3913 		     IF (l_return_status <> FND_API.G_RET_STS_SUCCESS) THEN
3914 			IF (l_debug = 1) THEN
3915 			   print_debug('Error returned from create_reservation API: ' || l_return_status);
3916 			END IF;
3917 			l_line_num := l_line_num - 1;
3918 			l_trolin_tbl.DELETE(l_order_count);
3919 			GOTO next_consol_rec;
3920 		      ELSE -- reservation creation successful
3921 			IF (l_debug = 1) THEN
3922 			   print_debug('Successfully created a RSV record');
3923 			END IF;
3924 
3925 		     END IF;
3926 
3927 		   ELSE -- means l_mtl_reservation_count <> 0, rsv already exists
3928 		     --DO NOTHING
3929 		     NULL;
3930 
3931 		  END IF; -- for l_mtl_reservation_count ==  0
3932 
3933 		  -- Put the WDDs to 'Replenishment Requested' RR status
3934 		  -- Call Shipping API to mark the Delivery Detail to 'RR'
3935 
3936 		  IF l_demand_type_id <> 4 THEN
3937 		     -- Mark wdd RR only for first level
3938 		     -- WHEN demand is WDD and NOT mover order of next level
3939 		     IF (l_debug = 1) THEN
3940 			print_debug('Mark Delivery Detail to RR');
3941 		     END IF;
3942 		     update_wdd_repl_status (p_deliv_detail_id   =>  l_demand_line_detail_id
3943 					     , p_repl_status     => 'R' -- for completed status
3944 					     , x_return_status   => l_return_status
3945 					     );
3946 
3947 		     IF l_return_status <> fnd_api.g_ret_sts_success THEN
3948 			l_line_num := l_line_num - 1;
3949 			l_trolin_tbl.DELETE(l_order_count);
3950 			GOTO next_consol_rec;
3951 		     END IF;
3952 		  END IF; -- for   IF l_demand_type_id <> 4 THEN
3953 
3954 		  -- Add an entry into WRD table for consumed Demand lines
3955 		  -- STORE DATA here and do BULK INSERT later
3956 		  l_organization_id_tab(l_index) := p_consol_item_repl_tbl(i).organization_id;
3957 		  l_mo_header_id_tab(l_index) := l_x_trolin_tbl(l_order_count).header_id;
3958 		  l_mo_line_id_tab(l_index) := l_x_trolin_tbl(l_order_count).line_id;
3959 		  l_demand_header_id_tab(l_index) := l_demand_header_id;
3960 		  l_demand_line_id_tab(l_index) := l_demand_line_id;
3961 		  l_demand_line_detail_id_tab(l_index) :=  l_demand_line_detail_id;
3962 		  l_demand_type_id_tab(l_index) := l_demand_type_id;
3963 		  l_item_id_tab(l_index) :=  p_consol_item_repl_tbl(i).item_id;
3964 		  l_demand_uom_code_tab(l_index) :=  l_demand_uom_code;
3965 		  l_demand_quantity_tab(l_index) := l_demand_quantity;
3966 		  l_sequence_id_tab(l_index) := l_sequence_id;
3967 		  l_repl_level_tab(l_index)  := l_repl_level;
3968 		  l_repl_type_tab(l_index)   := l_repl_type;
3969 		  l_index := l_index +1;
3970 
3971 
3972 		  -- NOTE: For all demand records that would be consumed by newly created MO lines, corresponding
3973 		  -- entry in the GTMP table will be deleted at the end of the processing of the replenishment calls
3974 
3975 	       END LOOP; -- for each demand line for an item
3976 	       CLOSE c_demand_lines_for_item;
3977 
3978 	       IF (l_debug = 1) THEN
3979 		  print_debug('Bulk Upload records in WRD');
3980 	       END IF;
3981 
3982 	       -- BULK UPLOAD ALL DEMAND RECORDS IN THE WRD TABLE
3983 	       FORALL k in 1 .. l_demand_line_detail_id_tab.COUNT()
3984 		 INSERT INTO wms_replenishment_details
3985 		 (Replenishment_id,
3986 		  Organization_id,
3987 		  source_header_id,
3988 		  Source_line_id,
3989 		  Source_line_detail_id,
3990 		  Source_type_id,
3991 		  demand_header_id,
3992 		  demand_line_id,
3993 		  demand_line_detail_id,
3994 		  demand_type_id,
3995 		  Inventory_item_id,
3996 		  Primary_UOM,
3997 		  Primary_Quantity,
3998 		  demand_sort_order,
3999 		  repl_level,
4000 		  repl_type,
4001 		  CREATION_DATE,
4002 		  LAST_UPDATE_DATE,
4003 		  CREATED_BY,
4004 		  LAST_UPDATED_BY,
4005 		  LAST_UPDATE_LOGIN
4006 		  )VALUES (
4007 			   WMS_REPLENISHMENT_DETAILS_S.NEXTVAL,
4008 			   l_organization_id_tab(k),
4009 			   l_mo_header_id_tab(k),
4010 			   l_mo_line_id_tab(k),
4011 			   NULL,
4012 			   4, --  For Move Orders
4013 			   l_demand_header_id_tab(k),
4014 			   l_demand_line_id_tab(k),
4015 			   l_demand_line_detail_id_tab(k),
4016 			   l_demand_type_id_tab(k),
4017 			   l_item_id_tab(k),
4018 			   l_demand_uom_code_tab(k),
4019 			   l_demand_quantity_tab(k),
4020 			   l_sequence_id_tab(k),
4021 			   l_repl_level_tab(k),
4022 			   l_repl_type_tab(k),
4023 			   Sysdate,
4024 			   Sysdate,
4025 			   fnd_global.user_id,
4026 			   fnd_global.user_id,
4027 			   fnd_global.user_id);
4028 
4029 	       -- CLEAR all entries in the tables
4030 	       l_organization_id_tab.DELETE;
4031 	       l_mo_header_id_tab.DELETE;
4032 	       l_mo_line_id_tab.DELETE;
4033 	       l_demand_header_id_tab.DELETE;
4034 	       l_demand_line_id_tab.DELETE;
4035 	       l_demand_line_detail_id_tab.DELETE;
4036 	       l_demand_type_id_tab.DELETE;
4037 	       l_item_id_tab.DELETE;
4038 	       l_demand_uom_code_tab.DELETE;
4039 	       l_demand_quantity_tab.DELETE;
4040 	       l_sequence_id_tab.DELETE;
4041 	       l_repl_level_tab.DELETE;
4042 	       l_repl_type_tab.DELETE;
4043 
4044 
4045 	       IF (l_debug = 1) THEN
4046 		  print_debug('After Bulk Upload records in WRD');
4047 	       END IF;
4048 
4049 
4050 	     ELSIF  ( p_repl_level > 1 AND  p_Create_Reservation = 'N') THEN
4051 
4052 		-- means next level of replenishment
4053 		-- just insert records into the WRD table
4054 		IF L_DEBUG = 1 THEN
4055 		   print_debug('******Create_Reservation = N and Next LEVEL repl');
4056 		   print_debug('Bulk Upload records in WRD');
4057 		END IF;
4058 
4059 
4060 		-----------------------
4061 		-- this is within the loop for each item
4062 
4063 		IF inv_cache.set_item_rec(p_consol_item_repl_tbl(i).ORGANIZATION_ID, p_consol_item_repl_tbl(i).item_id) THEN
4064 		   l_txn_prim_qty :=
4065 		     ROUND((p_consol_item_repl_tbl(i).final_replenishment_qty * get_conversion_rate(p_consol_item_repl_tbl(i).Item_id,
4066 							 p_consol_item_repl_tbl(i).repl_uom_code,
4067 							 inv_cache.item_rec.primary_uom_code)),
4068 		   g_conversion_precision);
4069 
4070 
4071 		   INSERT INTO wms_replenishment_details
4072 		     (Replenishment_id,
4073 		       Organization_id,
4074 		       source_header_id,
4075 		       Source_line_id,
4076 		       Source_line_detail_id,
4077 		       Source_type_id,
4078 		       demand_header_id,
4079 		       demand_line_id,
4080 		       demand_line_detail_id,
4081 		       demand_type_id,
4082 		       Inventory_item_id,
4083 		       Primary_UOM,
4084 		       Primary_Quantity,
4085 		       demand_sort_order,
4086 		       repl_level,
4087 		       repl_type,
4088 		       CREATION_DATE,
4089 		       LAST_UPDATE_DATE,
4090 		       CREATED_BY,
4091 		       LAST_UPDATED_BY,
4092 		       LAST_UPDATE_LOGIN
4093 		       )
4094       		      SELECT
4095 		      WMS_REPLENISHMENT_DETAILS_S.NEXTVAL,       --Replenishment_id,
4096 		      p_consol_item_repl_tbl(i).organization_id, --Organization_id,
4097 		     l_x_trolin_tbl(1).header_id, --  source_header_id,
4098 		     l_x_trolin_tbl(1).line_id,   --  Source_line_id,
4099 		     NULL,                        --  Source_line_detail_id,
4100 		     4,                           --  Source_type_id,
4101 		     demand_header_id,
4102 		     demand_line_id,
4103 		     demand_line_detail_id,       -- stored as -9999 for next level
4104 		     demand_type_id,              -- stored as 4 for next level
4105 		     p_consol_item_repl_tbl(i).item_id,   -- Inventory_item_id,
4106 		     inv_cache.item_rec.primary_uom_code, --  Primary_UOM,
4107 		     l_txn_prim_qty,                      --  Primary_Quantity,
4108 		     repl_sequence_id ,                   --demand_sort_order,
4109 		     repl_level,
4110 		     repl_type,
4111 		     Sysdate,
4112 		     Sysdate,
4113 		     fnd_global.user_id,
4114 		     fnd_global.user_id,
4115 		     fnd_global.user_id
4116 		     FROM WMS_REPL_DEMAND_GTMP
4117 		     WHERE ORGANIZATION_ID = p_consol_item_repl_tbl(i).ORGANIZATION_ID
4118 		     AND inventory_item_id = p_consol_item_repl_tbl(i).item_id
4119 		     AND REPL_TO_SUBINVENTORY_CODE =  p_consol_item_repl_tbl(i).repl_to_subinventory_code;
4120 
4121 		END IF;
4122 
4123 		  IF (l_debug = 1) THEN
4124 		  print_debug('After Bulk Upload records in WRD FOR NEXT LEVEL');
4125 		  END IF;
4126 
4127 
4128 	     ELSE -- means p_Create_Reservation    = 'N'
4129 		     -- Do not need to do anything here. We do not need to call the shipping API to revert to original
4130 		     --line status because For dynamic/pull replenishment p_create_Reservation  will
4131 		     -- always be 'Y' and hence the code will never come here. For Push replenishemnt, The demand
4132 		     -- line would not have been touched yet. So it will remain in its orignal status.
4133 
4134 		     NULL;
4135 	    END IF; -- for p_Create_Reservation    = 'Y'
4136 
4137 	    -- Create Allocation if parameter is Y. For simplicity, only those mover orders will be considered for
4138 	    -- allocation that are created newly in this program. Already existing open move orders that could
4139 	    -- partly satisfy current demands will not be detailed.
4140 	    -- Note: parameter p_Auto_Allocate will be 'N' if p_Create_Reservation   = 'N', UI ensures it
4141 
4142 	    IF p_Auto_Allocate = 'Y' THEN
4143 	       -- Call the allocation engine
4144 
4145 	       IF (l_debug = 1) THEN
4146 		  print_debug('l_x_trolin_tbl count :'||l_x_trolin_tbl.COUNT());
4147 		  print_debug('Auto Allocate is Y, Calling rules engine ..MOL:' ||l_x_trolin_tbl(1).line_id);
4148 	       END IF;
4149 
4150 	       IF p_Plan_Tasks = 'Y' THEN
4151 		  L_Plan_Tasks := TRUE;
4152 		ELSE
4153 		  L_Plan_Tasks := FALSE;
4154 	       END IF;
4155 
4156 	       WMS_Engine_PVT.create_suggestions(
4157 						 p_api_version => 1.0,
4158 						 p_init_msg_list => fnd_api.g_false,
4159 						 p_commit => fnd_api.g_false,
4160 						 p_validation_level => fnd_api.g_valid_level_none,
4161 						 x_return_status => l_return_status,
4162 						 x_msg_count => x_msg_count,
4163 						 x_msg_data => x_msg_data,
4164 						 p_transaction_temp_id => l_x_trolin_tbl(1).line_id,
4165 						 p_reservations => l_rsv_tbl_tmp, --NULL value  AS no rsv FOR repl MO
4166 						 p_suggest_serial => fnd_api.g_false,
4167 						 p_plan_tasks => l_plan_tasks);
4168 
4169 	       IF (l_debug = 1) THEN
4170 		  print_debug('after calling create_suggestions API');
4171 	       END IF;
4172 
4173 
4174 	       IF (l_return_status <> FND_API.G_RET_STS_SUCCESS) THEN
4175 		  IF (l_debug = 1) THEN
4176 		     print_debug('Error returned from create_suggestions API: ' || l_return_status);
4177 		  END IF;
4178 		  -- even though it is failing
4179 		  -- we want to process the replenishment mo
4180 		  -- it can be allocated later
4181 		  -- no reverting so passing success to go to next
4182 		  -- consol rec. Also should not do any next level
4183 		  -- stuff which this will help to skip.
4184 		  l_return_status := fnd_api.g_ret_sts_success;
4185 		  GOTO next_consol_rec;
4186 
4187 
4188 		ELSE
4189 
4190 		  IF (l_debug = 1) THEN
4191 		     print_debug('Success returned from create_suggestions API');
4192 		     print_debug('Now Assign Task Type for all Repl tasks created FOR the MO Line');
4193 		  END IF;
4194 		  l_mo_line_id:=l_x_trolin_tbl(1).line_id;
4195 
4196 		  OPEN c_mmtt_rec;
4197 		  LOOP
4198 		     FETCH c_mmtt_rec INTO l_task_id;
4199 		     EXIT WHEN c_mmtt_rec%notfound;
4200 
4201 		     IF (l_debug = 1) THEN
4202 			print_debug('Assign Task Type for MMTT_id: '||l_task_id);
4203 		     END IF;
4204 
4205 		     wms_rule_pvt.assigntt(
4206 					   p_api_version                => 1.0
4207 					   , p_task_id                    => l_task_id
4208 					   , x_return_status              => l_return_status
4209 					   , x_msg_count                  => x_msg_count
4210 					   , x_msg_data                   => x_msg_data
4211 					   );
4212 
4213 		  END LOOP;
4214 		  CLOSE c_mmtt_rec;
4215 
4216 
4217 	       END IF;
4218 
4219 
4220 	       --*************
4221 	       --update the MO line quantity_detailed field or close the MO
4222                BEGIN
4223 		  SELECT NVL(SUM(primary_quantity), 0)
4224 		    ,NVL(sum(transaction_quantity),0)
4225 		    ,COUNT(*)
4226 		    INTO l_prim_quantity_detailed
4227 		    ,l_quantity_detailed_conv
4228 		    ,l_num_detail_recs
4229 		    FROM mtl_material_transactions_temp
4230 		    WHERE move_order_line_id = l_x_trolin_tbl(1).line_id;
4231 
4232 		  IF (l_debug = 1) THEN
4233 		     print_debug('primary l_quantity detailed is :'|| l_prim_quantity_detailed);
4234 		     print_debug('l_num_detail_recs is :'|| l_num_detail_recs);
4235 		     print_debug('Primary UOM code     :'||inv_cache.item_rec.primary_uom_code);
4236 		  END IF;
4237 
4238 		  --Convert the MOL detailed qty into MOL UOM code qty
4239 		  IF inv_cache.item_rec.primary_uom_code <> p_consol_item_repl_tbl(i).repl_uom_code THEN
4240 
4241 		     l_quantity_detailed :=
4242 		       ROUND((l_prim_quantity_detailed* get_conversion_rate(p_consol_item_repl_tbl(i).item_id,
4243 									    inv_cache.item_rec.primary_uom_code,
4244 									    p_consol_item_repl_tbl(i).Repl_UOM_Code )),
4245 			     g_conversion_precision);
4246 
4247 		   ELSE
4248 		     l_quantity_detailed := l_prim_quantity_detailed;
4249 		  END IF;
4250 
4251 
4252 	       EXCEPTION
4253 		  WHEN NO_DATA_FOUND THEN
4254 		     IF (l_debug = 1) THEN
4255 			print_debug('no detail records found');
4256 		     END IF;
4257 		     l_quantity_detailed       := 0;
4258 		     l_quantity_detailed_conv  := 0;
4259 		     l_num_detail_recs         := 0;
4260 	       END;
4261 
4262 		 IF (l_debug = 1) THEN
4263 		    print_debug('Qty Detailed           :'||l_quantity_detailed );
4264 		    print_debug('MOL Line Qty           :'||l_x_trolin_tbl(1).quantity);
4265 		    print_debug('MOL Line Qty Delivered :'||l_x_trolin_tbl(1).quantity_delivered);
4266 		 END IF;
4267 
4268 	       -- NOTE: l_quantity_detailed contains all qty of MMTT related TO CURRENT mo line whether in this
4269 	       -- RUN OR ANY previous runs
4270 	       IF  l_quantity_detailed < (l_x_trolin_tbl(1).quantity - Nvl(l_x_trolin_tbl(1).quantity_delivered,0))  THEN -- partial allocation
4271 		  -- update the quantity detailed correctly
4272 		  UPDATE mtl_txn_request_lines mtrl
4273 		    SET mtrl.quantity_detailed = l_quantity_detailed
4274 		    where line_id = l_x_trolin_tbl(1).line_id;
4275 
4276 		  IF (l_debug = 1) THEN
4277 		     print_debug('Updated the detailed qty on the MO line');
4278 		  END IF;
4279 
4280 		ELSE -- Fully allocated
4281 		  -- it has been completely detailed
4282 		  -- do not close the MO, otherwise pick Drop of repl task fails
4283 		  UPDATE mtl_txn_request_lines mtrl
4284 		    SET mtrl.quantity_detailed = l_quantity_detailed
4285 		    where line_id = l_x_trolin_tbl(1).line_id;
4286 
4287 		  IF (l_debug = 1) THEN
4288 		     print_debug('MO line completely detailed');
4289 		  END IF;
4290 
4291 	       END IF; -- for partial allocation
4292 
4293 	       --*************
4294     -- Calling Custom API. This call is for post replenishment custom logic eg. Backorder some lines
4295     IF (WMS_REPL_CUSTOM_APIS_PUB.g_is_api_implemented) THEN
4296          IF (l_debug = 1) THEN
4297 	       print_debug('custom API enabled. Calling WMS_REPL_CUSTOM_APIS_PUB.POST_REPL_ALLOCATION_CUST');
4298 	     END IF;
4299 
4300 
4301        WMS_REPL_CUSTOM_APIS_PUB.POST_REPL_ALLOCATION_CUST(x_return_status => x_return_status,
4302 														  x_msg_count => x_msg_count,
4303 														  x_msg_data  => x_msg_data,
4304 														  p_mol_id    => l_x_trolin_tbl(1).line_id);
4305 
4306     ELSE --  custom API is NOT implemented
4307 	       -- Multi step change
4308 	       -- Call to check to insert into temp table next level record after
4309 	       --
4310 	       IF (( l_prev_item_id IS NULL AND
4311 		     l_prev_sub_code IS NULL ) OR
4312 		   l_prev_org_id <> p_consol_item_repl_tbl(i).organization_id  OR
4313 		   l_prev_item_id <> p_consol_item_repl_tbl(i).Item_id OR
4314 		   l_prev_sub_code <> l_src_sub) THEN
4315 		  l_source_sub_atr := NULL;
4316 	       END IF;
4317 
4318 	       IF (l_debug = 1) THEN
4319 		  print_debug('Ging to check for Next Level of Replenishment');
4320 	       END IF;
4321 
4322 	       check_for_next_level_repl(p_move_order_header_id => l_x_trolin_tbl(1).header_id
4323 					 , p_move_order_line_id => l_x_trolin_tbl(1).line_id
4324 					 , p_organization_id => p_consol_item_repl_tbl(i).organization_id
4325 					 , p_inventory_item_id => p_consol_item_repl_tbl(i).Item_id
4326 					 , p_repl_level => p_repl_level
4327 					 , x_source_sub_atr => l_source_sub_atr
4328 					 , x_create_qty => l_create_qty
4329 					 , x_return_status => l_return_status
4330 					 , x_msg_count => l_msg_count
4331 					 , x_msg_data => l_msg_data
4332 					 );
4333 
4334 	       -- if above api did end up computing the atr
4335 	       -- it will return a non null value else it will return a null
4336 	       -- value. If it returns a null, we would like to force a check
4337 	       -- next time around.
4338 	       IF l_source_sub_atr IS NULL THEN
4339 		  l_prev_item_id := NULL;
4340 		  l_prev_sub_code := NULL;
4341 		ELSE
4342 		  l_prev_item_id := p_consol_item_repl_tbl(i).item_id;
4343 		  l_prev_sub_code := l_src_sub;
4344 	       END IF;
4345 
4346 	       IF l_create_qty > 0 THEN
4347 		  l_item_id_tb(l_next_repl_cntr) := p_consol_item_repl_tbl(i).Item_id;
4348 		  l_org_id_tb(l_next_repl_cntr)  := p_consol_item_repl_tbl(i).organization_id;
4349 		  l_demand_header_id_tb(l_next_repl_cntr) := l_x_trolin_tbl(1).header_id;
4350 		  l_demand_line_id_tb(l_next_repl_cntr)   := l_x_trolin_tbl(1).line_id;
4351 		  l_demand_type_id_tb(l_next_repl_cntr)   := 4;
4352 		  l_repl_to_sub_code_tb(l_next_repl_cntr) := l_src_sub;
4353 		  l_requested_quantity_tb(l_next_repl_cntr)     := l_create_qty;
4354 		  l_requested_quantity_uom_tb(l_next_repl_cntr) := p_consol_item_repl_tbl(i).Repl_UOM_Code;
4355 		  l_quantity_in_repl_uom_tb(l_next_repl_cntr)   := l_create_qty;
4356 		  l_repl_uom_code_tb(l_next_repl_cntr)          := p_consol_item_repl_tbl(i).Repl_UOM_Code;
4357 		  l_expected_ship_date_tb(l_next_repl_cntr)     := NULL;
4358 		  l_next_repl_cntr := l_next_repl_cntr + 1;
4359 	       END IF;
4360 
4361 
4362     END IF; -- for custom API is implemented
4363 
4364 	    END IF; -- for p_Auto_Allocate
4365 
4366 	 END IF; -- for p_consol_item_repl_tbl(i).final_replenishment_qty  <> -9999
4367 
4368 	 l_prev_org_id := p_consol_item_repl_tbl(i).ORGANIZATION_ID;
4369 
4370       END IF; --   IF p_consol_item_repl_tbl(i).final_replenishment_qty <= 0
4371       <<next_consol_rec>>
4372 
4373 	IF l_return_status <> fnd_api.g_ret_sts_success then
4374 
4375 	IF (l_debug = 1) THEN
4376 	 print_debug('At the nexT_consol_rec rolling back as the l_return_status is ' || l_return_status);
4377 	END IF;
4378 				IF c_demand_lines_for_item%ISOPEN THEN --BUG14054260
4379 					CLOSE c_demand_lines_for_item;
4380 				END IF;
4381 	   l_return_status := fnd_api.g_ret_sts_success;
4382 	   ROLLBACK TO current_mol_sp;
4383 	   -- if repl_type 2 and demand_type_id <> 4 then revert that WDD to original status
4384 	   -- remove all entries for that item from gtmp
4385 	   -- both done in following API
4386 	   Revert_Consol_item_changes
4387 	     ( p_repl_type         => l_repl_type
4388 	       , p_demand_type_id  => l_demand_type_id
4389 	       , P_item_id         => p_consol_item_repl_tbl(i).item_ID
4390 	       , p_org_id          => p_consol_item_repl_tbl(i).ORGANIZATION_ID
4391 	       , x_return_status   => l_return_status
4392 	       );
4393 
4394 	   -- Remove element from consol table, can not do inside this loop
4395 	   -- AS iterating through the same consol record
4396 	   -- store the index of the consol table to be deleted outside the loop
4397 	   l_del_index := l_del_index +1;
4398 	   l_del_consol_item_tb(l_del_index) := i;
4399 
4400 	END IF;
4401 
4402       END IF; --    IF (NOT p_consol_item_repl_tbl.exists(i))
4403    END LOOP; -- For each consolidated demand Items
4404    END IF;
4405 
4406    --REMOVE CONSOL RECORDS THAT HAS BEEN REMOVED FROM MOVE ORDER CREATION
4407    -- THIS WILL KEEP DATA IN SYNC. Remember to use 'FORALL k IN INDICES OF'
4408    --  CREATE_REPL_MOVE_ORDER() is last call for a level. so it does not matter
4409    FOR j IN 1..l_del_consol_item_tb.COUNT() LOOP
4410       p_consol_item_repl_tbl.DELETE(l_del_consol_item_tb(j));
4411    END LOOP;
4412 
4413     -- TODO: Blocking Multi-Level Code changes
4414    -- Multi step change
4415    -- Bulk upload all eligible demand lines
4416    FORALL k IN INDICES OF l_demand_line_id_tb
4417      INSERT INTO WMS_REPL_DEMAND_GTMP
4418      (Repl_Sequence_id,
4419       repl_level,
4420       Inventory_item_id,
4421       Organization_id,
4422       demand_header_id,
4423       demand_line_id,
4424       DEMAND_LINE_DETAIL_ID,
4425       demand_type_id,
4426       quantity_in_repl_uom,
4427       REPL_UOM_code,
4428       Quantity,
4429       Uom_code,
4430       Expected_ship_date,
4431       Repl_To_Subinventory_code,
4432       filter_item_flag,
4433       repl_type)
4434      VALUES
4435      (WMS_REPL_DEMAND_GTMP_S.NEXTVAL,
4436       Nvl(p_repl_level,1) + 1,
4437       l_item_id_tb(k),
4438       l_org_id_tb(k),
4439       l_demand_header_id_tb(k),
4440       l_demand_line_id_tb(k),
4441       -9999,
4442       l_demand_type_id_tb(k),
4443       l_quantity_in_repl_uom_tb(k),
4444       l_repl_uom_code_tb(k),
4445       l_requested_quantity_tb(k),
4446       l_requested_quantity_uom_tb(k),
4447       l_expected_ship_date_tb(k),
4448       l_repl_to_sub_code_tb(k),
4449       NULL,
4450       2);
4451 
4452 
4453 
4454 EXCEPTION
4455    WHEN OTHERS THEN
4456       IF l_debug = 1 THEN
4457 	 print_debug('CREATE_REPL_MOVE_ORDER: Error creating move order: ' || sqlcode || ', ' || sqlerrm);
4458       END IF;
4459       x_return_status := fnd_api.g_ret_sts_error;
4460 
4461 END CREATE_REPL_MOVE_ORDER;
4462 
4463 
4464 
4465 PROCEDURE  GET_OPEN_MO_QTY(p_Repl_level           IN NUMBER,
4466 			   p_repl_type            IN NUMBER,
4467 			   p_Create_Reservation   IN VARCHAR2,
4468 			   x_consol_item_repl_tbl IN OUT NOCOPY CONSOL_ITEM_REPL_TBL,
4469 			   x_return_status        OUT NOCOPY VARCHAR2,
4470 			   x_msg_count            OUT NOCOPY NUMBER,
4471 			   x_msg_data             OUT NOCOPY VARCHAR2)
4472   IS
4473 
4474      L_demand_header_id            NUMBER;
4475      L_demand_line_id              NUMBER;
4476      L_demand_line_detail_id       NUMBER;
4477      L_demand_quantity             NUMBER;
4478      L_demand_quantity_in_repl_uom NUMBER;
4479      L_demand_uom_code             VARCHAR2(3);
4480      L_demand_type_id              NUMBER;
4481      L_sequence_id                 NUMBER;
4482      L_expected_ship_date          date;
4483 
4484      L_mo_line_id           NUMBER;
4485      L_mo_header_id         NUMBER;
4486      L_mo_quantity          NUMBER;
4487      L_mo_uom_code          VARCHAR2(3);
4488      L_mo_quantity_detailed NUMBER;
4489 
4490      l_rsv_temp_rec_2       inv_reservation_global.mtl_reservation_rec_type;
4491      l_rsv_temp_rec       inv_reservation_global.mtl_reservation_rec_type;
4492      l_rsv_rec            inv_reservation_global.mtl_reservation_tbl_type;
4493      l_serial_number      inv_reservation_global.serial_number_tbl_type;
4494      l_to_serial_number   inv_reservation_global.serial_number_tbl_type;
4495      l_quantity_reserved  NUMBER;
4496      l_quantity_reserved2 NUMBER;
4497      l_rsv_id             NUMBER;
4498 
4499      l_mtl_reservation_count NUMBER;
4500      l_error_code            NUMBER;
4501      l_conversion_rate       NUMBER;
4502      l_debug number := NVL(FND_PROFILE.VALUE('INV_DEBUG_TRACE'),0);
4503 
4504 
4505      l_repl_level NUMBER;
4506      l_repl_type NUMBER;
4507 
4508      l_detail_info_tab             WSH_INTERFACE_EXT_GRP.delivery_details_Attr_tbl_Type;
4509      l_in_rec                      WSH_INTERFACE_EXT_GRP.detailInRecType;
4510      l_out_rec                     WSH_INTERFACE_EXT_GRP.detailOutRecType;
4511 
4512      -- For bulk upload in the WRD table
4513      l_organization_id_tab  num_tab;
4514      l_mo_header_id_tab  num_tab;
4515      l_mo_line_id_tab  num_tab;
4516      l_demand_header_id_tab  num_tab;
4517      l_demand_line_id_tab  num_tab;
4518      l_demand_line_detail_id_tab  num_tab;
4519      l_demand_type_id_tab  num_tab;
4520      l_item_id_tab  num_tab;
4521      l_demand_uom_code_tab  uom_tab;
4522      l_demand_quantity_tab  num_tab;
4523      l_sequence_id_tab  num_tab;
4524      l_repl_level_tab   num_tab;
4525      l_repl_type_tab    num_tab;
4526 
4527      l_index NUMBER;
4528 
4529      -- For bulk delete from the WRDG table
4530      l_detail_id_delete_tab num_tab;
4531      l_del_index NUMBER;
4532 
4533      l_return_status VARCHAR2(3) := fnd_api.g_ret_sts_success;
4534 	 l_detail_removed VARCHAR2(1) := 'N'; -- For bug#10185153
4535 
4536      CURSOR c_demand_lines_for_item(P_ORG_ID NUMBER, p_item_id number, p_fp_sub VARCHAR2) IS
4537 	SELECT Repl_Sequence_id,
4538 	  demand_header_id,
4539 	  demand_line_id,
4540 	  demand_line_detail_id,
4541 	  demand_type_id,
4542 	  Nvl(quantity,0),
4543 	  uom_code,
4544 	  expected_ship_date,
4545 	  Nvl(quantity_in_repl_uom,0),
4546 	  repl_level,
4547 	  repl_type
4548 	  FROM WMS_REPL_DEMAND_GTMP
4549 	  WHERE ORGANIZATION_ID = P_ORG_ID
4550 	  AND inventory_item_id = p_item_id
4551 	  AND repl_to_subinventory_code = p_fp_sub
4552 	  order by Repl_Sequence_id;
4553 
4554 
4555      -- TEST: make sure that all qty in correct UOM here
4556      --Store all open MO for the Sub
4557      CURSOR c_open_mo_lines(P_ORG_ID NUMBER, p_item_id NUMBER, P_FP_SUB VARCHAR2) IS
4558 	select mtrl.line_id,
4559 	  mtrl.header_id,
4560 	  -- get all open move order qty that are not part of WRD
4561 	  -- once fully transacted, mtrl.QUANTITY = mtrl.QUANTITY_DETAILED + mtrl.QUANTITY_DELIVERED
4562 	  -- here quantity containes  QUANTITY_DETAILED at the current sub as
4563 	  -- well AS untouched move ORDER qty
4564 	  (mtrl.QUANTITY - NVL(mtrl.QUANTITY_DELIVERED,0)) AS quantity,
4565 	    mtrl.uom_code,
4566 	    Nvl(mtrl.quantity_detailed,0) AS quantity_detailed
4567 	      from mtl_txn_request_lines mtrl, mtl_txn_request_headers mtrh
4568 	      where mtrl.header_id = mtrh.header_id
4569 	      and mtrl.organization_id = P_ORG_ID
4570 	      and mtrl.inventory_item_id = p_item_id
4571 	      and mtrl.to_subinventory_code = P_FP_SUB
4572 	      and mtrl.line_status in (3, 7) -- only approved and pre-approved
4573 	      and mtrh.move_order_type = 2 -- for replenishment only
4574 	      AND not exists
4575 	      (select WRD.Source_line_id
4576 	       from WMS_REPLENISHMENT_DETAILS wrd
4577 	       where WRD.source_header_id = MTRL.HEADER_ID
4578                AND WRD.Source_line_id = MTRL.LINE_ID
4579                And wrd.organization_id = mtrl.organization_id
4580                And wrd.organization_id = p_org_id )
4581 	      UNION
4582 	      -- get all Open Move Order qty that are left out due to rounding or other reason
4583 	      select mtrl.line_id,
4584 	      mtrl.header_id,
4585 	      -- qty inside function Round(**) below might NOT be allocated yet based on
4586 	      -- how the stock up was RUN but we have earmarked that much mo qty through WRD for certain demands
4587 	      -- so we need to subtract that much qty from existing_mo_qty for availble_mo_qty
4588 	      (mtrl.QUANTITY- NVL(mtrl.QUANTITY_DELIVERED,0) -
4589 	       ROUND((WMS_REPLENISHMENT_PVT.get_conversion_rate(p_item_id, x.primary_uom, mtrl.uom_code)* Nvl(X.quantity,0)),5)) AS quantity,
4590 
4591 		 mtrl.uom_code,
4592 		 Nvl(mtrl.quantity_detailed,0) AS quantity_detailed
4593 		   FROM
4594 		   mtl_txn_request_lines mtrl,
4595 		   (
4596 		    SELECT WRD.Source_line_id, WRD.source_header_id,
4597 		    wrd.inventory_item_id, SUM(wrd.Primary_quantity) quantity,
4598 		    wrd.organization_id,wrd.primary_uom
4599 		    FROM  WMS_REPLENISHMENT_DETAILS wrd, wsh_delivery_details wdd
4600 		    WHERE wrd.demand_line_detail_id = wdd.delivery_detail_id
4601 		    AND  wrd.demand_line_id = wdd.source_line_id
4602 		    AND  wrd.organization_id = P_ORG_ID
4603 		    AND  wrd.organization_id = wdd.organization_id
4604 		    GROUP BY  wrd.organization_id,
4605 		    WRD.source_header_id,
4606 		    WRD.Source_line_id,
4607 		    wrd.inventory_item_id,
4608 		    wrd.primary_uom) X
4609 		   WHERE X.inventory_item_id = mtrl.inventory_item_id
4610 		   and x.source_header_id = MTRL.HEADER_ID
4611 		   AND x.Source_line_id = MTRL.LINE_ID
4612 		   and x.organization_id = mtrl.organization_id
4613 		   and mtrl.organization_id = P_ORG_ID
4614 		   and mtrl.inventory_item_id = p_item_id
4615 		   and mtrl.to_subinventory_code = P_FP_SUB
4616 		   and mtrl.line_status in (3, 7)
4617 		   order by quantity DESC;
4618 
4619 
4620 
4621 		 CURSOR c_demands_for_mo(p_org_id NUMBER, p_mo_header_id NUMBER, p_mo_line_id NUMBER) IS
4622 		    SELECT demand_line_detail_id, demand_line_id
4623 		      FROM WMS_REPLENISHMENT_DETAILS WRD
4624 		      WHERE WRD.organization_id = P_ORG_ID
4625 		      AND WRD.source_header_id = P_mo_header_id
4626 		      AND WRD.Source_line_id = P_mo_line_id;
4627 BEGIN
4628    x_return_status := l_return_status;
4629    -- For all Items in the pl/sql table
4630    IF (l_debug = 1) THEN
4631       print_debug('Inside the API GET_OPEN_MO_QTY');
4632    END IF;
4633    l_index := 1;
4634    l_del_index := 1;
4635    IF (x_consol_item_repl_tbl.count>0) THEN --bug#10185153
4636    FOR i IN x_consol_item_repl_tbl.FIRST .. x_consol_item_repl_tbl.LAST LOOP
4637 
4638       IF (NOT x_consol_item_repl_tbl.exists(i)) THEN
4639 
4640 	 IF (l_debug = 1) THEN
4641 	    print_debug('CURRENT INDEX IN THE CONSOL TABLE HAS BEEN Discarded - moving TO next consol RECORD' );
4642 
4643 	 END IF;
4644 
4645        ELSE
4646 
4647 	 IF (l_debug = 1) THEN
4648 	    print_debug('Going through consolidated item :'|| x_consol_item_repl_tbl(i).item_id ||
4649 			' , Index :'|| i);
4650 	 END IF;
4651 
4652       --For all Open Move Orders for the item, see if there is any demand lines that can be consumed
4653       -- Loop through all open MO for the item
4654       OPEN c_open_mo_lines(x_consol_item_repl_tbl(i).ORGANIZATION_ID,
4655 			   x_consol_item_repl_tbl(i).item_id,
4656 			   x_consol_item_repl_tbl(i).repl_to_subinventory_code);
4657       LOOP
4658 	 FETCH c_open_mo_lines INTO L_mo_line_id, L_mo_header_id, L_mo_quantity, L_mo_uom_code, L_mo_quantity_detailed;
4659 	 EXIT WHEN c_open_mo_lines%NOTFOUND;
4660 	 IF (l_debug = 1) THEN
4661 	    print_debug('Curent open MO Line Id-'|| L_mo_line_id ||' ,Qty :'||L_mo_quantity||' ,UOM :'||L_mo_uom_code);
4662 	 END IF;
4663 
4664 	 -- Loop through all demand lines for the item to see if any demand line can be consumed against open MOL
4665 	 OPEN c_demand_lines_for_item(x_consol_item_repl_tbl(i).ORGANIZATION_ID,
4666 				      x_consol_item_repl_tbl(i).item_id,
4667 				      x_consol_item_repl_tbl(i).repl_to_subinventory_code);
4668 	 LOOP
4669 	    FETCH c_demand_lines_for_item INTO L_sequence_id,
4670 	      L_demand_header_id, L_demand_line_id,
4671 	      L_demand_line_detail_id, l_demand_type_id, L_demand_quantity,
4672 	      L_demand_uom_code,
4673 	      l_expected_ship_date, l_demand_quantity_in_repl_uom, l_repl_level,l_repl_type ;
4674 	    EXIT WHEN c_demand_lines_for_item%NOTFOUND;
4675 
4676 		l_detail_removed := 'N'; -- For bug#10185153
4677 
4678 	    IF (l_debug = 1) THEN
4679 	       print_debug('Netting delivery_detail :'||L_demand_line_detail_id||
4680 			   ' ,Qty_in_repl_uom :'||l_demand_quantity_in_repl_uom);
4681 	    END IF;
4682 
4683 	    SAVEPOINT Current_Demand_SP;
4684 
4685 		-- For bug#10185153 start
4686 	    IF (l_detail_id_delete_tab.COUNT()>0) THEN
4687 			FOR d in 1 .. l_detail_id_delete_tab.COUNT() LOOP
4688 				IF (l_detail_id_delete_tab(d) = l_demand_line_detail_id) THEN
4689 					l_detail_removed := 'Y';
4690 					EXIT;
4691 				END IF;
4692 			END LOOP;
4693 		END IF;
4694 
4695 		IF (l_detail_removed = 'Y') THEN
4696 			IF (l_debug = 1) THEN
4697 				print_debug('Delivery_detail :'||L_demand_line_detail_id||
4698 			   ' , already processed. So skipping it');
4699 			END IF;
4700 			GOTO next_record;
4701 		END IF;
4702 		-- For bug#10185153 end
4703 
4704 
4705 	    -- All quantity comparison should happen in repl_UOM_code because there can be multiple demand for a
4706 	    --  single MO. It will save the computation.
4707 	    IF L_mo_uom_code <> x_consol_item_repl_tbl(i).Repl_UOM_Code then
4708 
4709 	       l_conversion_rate := get_conversion_rate(x_consol_item_repl_tbl(i).Item_id,
4710 							L_mo_uom_code,
4711 							x_consol_item_repl_tbl(i).Repl_UOM_Code);
4712 
4713 	       IF (l_conversion_rate < 0) THEN
4714 		  IF (l_debug = 1) THEN
4715 		     print_debug('Error while obtaining L_mo_uom_code conversion rate for demand qty');
4716 		  END IF;
4717 		  -- Process the next existing demand record.
4718 		  GOTO next_record;
4719 	       END IF;
4720 
4721 	       L_mo_quantity := ROUND(l_conversion_rate * L_mo_quantity,
4722 				      g_conversion_precision);
4723 
4724 	    END IF;
4725 
4726 	    IF L_mo_quantity < L_demand_quantity_in_repl_uom THEN
4727 	       -- For simplicity, we will consume only those MOLs that have qty greater than WDD qty
4728 	       IF (l_debug = 1) THEN
4729 		  print_debug('MO Qty < Demand Line qty, NOTHING TO DO..');
4730 	       END IF;
4731 
4732 	       GOTO next_record;
4733 
4734 	     ELSIF L_mo_quantity >= L_demand_quantity_in_repl_uom THEN
4735 	       -- The specific demand order will be consumed with this Move Order
4736 	       IF (l_debug = 1) THEN
4737 		  print_debug('MO Qty > Demand Line qty, Consume Against it');
4738 	       END IF;
4739 
4740 	       IF p_Create_Reservation = 'Y' THEN
4741 
4742 		  IF (l_debug = 1) THEN
4743 		     print_debug('Create RSV =Y, Mark Replenishment Status as RR');
4744 		  END IF;
4745 
4746 		  -- Call Shipping API to mark the Delivery Detail to 'RR'
4747 		  update_wdd_repl_status (p_deliv_detail_id   =>  l_demand_line_detail_id
4748 					  , p_repl_status     => 'R' -- for completed status
4749 					  , x_return_status   => l_return_status
4750 					  );
4751 
4752 		  IF l_return_status <> fnd_api.g_ret_sts_success THEN
4753 		     GOTO next_record;
4754 		  END IF;
4755 
4756 
4757 		  IF (l_debug = 1) THEN
4758 		     print_debug('Check if Org level RSV exists');
4759 		  END IF;
4760 		  -- Check if an Org level reservation exists for corresponding demand line
4761 		  -- Clear out old values
4762 		  l_rsv_temp_rec := l_rsv_temp_rec_2;
4763 
4764 		  -- Assign all new values
4765 		  l_rsv_temp_rec.organization_id := x_consol_item_repl_tbl(i).organization_id;
4766 		  l_rsv_temp_rec.inventory_item_id := x_consol_item_repl_tbl(i).item_id;
4767 		  l_rsv_temp_rec.DEMAND_SOURCE_TYPE_ID := l_demand_type_id;
4768 		  l_rsv_temp_rec.DEMAND_SOURCE_HEADER_ID := l_demand_header_id;
4769 		  l_rsv_temp_rec.DEMAND_SOURCE_LINE_ID := l_demand_line_id;
4770 
4771 
4772 		  inv_reservation_pub.query_reservation(
4773 							p_api_version_number =>1.0,
4774 							x_return_status => l_return_status,
4775 							x_msg_count   => x_msg_count,
4776 							x_msg_data    => x_msg_data,
4777 							p_query_input => l_rsv_temp_rec,
4778 							x_mtl_reservation_tbl  => l_rsv_rec,
4779 							x_mtl_reservation_tbl_count => l_mtl_reservation_count,
4780 							x_error_code => l_error_code);
4781 
4782 		  IF l_RETURN_status = fnd_api.g_ret_sts_success THEN
4783 		     IF (l_debug = 1) THEN
4784 			PRINT_DEBUG('Number of reservations found: ' ||l_mtl_reservation_count);
4785 		     END IF;
4786 
4787 		   ELSE
4788 		     IF (l_debug = 1) THEN
4789 			PRINT_DEBUG('Error: ' || X_msg_data);
4790 		     END IF;
4791 		     GOTO next_record;
4792 		  END IF;
4793 
4794 
4795 		  -- If no org level reservation found then create it
4796 		  IF l_mtl_reservation_count = 0 then
4797 		     IF (l_debug = 1) THEN
4798 			PRINT_DEBUG('NO RSV Found, Create High Level RSV');
4799 		     END IF;
4800 
4801 		     l_rsv_temp_rec.DEMAND_SOURCE_HEADER_ID := l_demand_header_id;
4802 		     l_rsv_temp_rec.demand_source_line_detail :=  l_demand_line_detail_id;
4803 
4804 		     -- Create high-level reservation for the demand line against inventory (sypply_type = 13)
4805 		     Create_RSV(p_replenishment_type    => 1, --  1- Stock Up/Push; 2- Dynamic
4806 				l_debug                 => l_debug,
4807 				l_organization_id       => x_consol_item_repl_tbl(i).ORGANIZATION_ID,
4808 				l_inventory_item_id     => x_consol_item_repl_tbl(i).item_id,
4809 				l_demand_type_id        => l_demand_type_id,
4810 				l_demand_so_header_id   => L_demand_header_id,
4811 				l_demand_line_id        => L_demand_line_id,
4812 				l_split_wdd_id          => NULL,
4813 				l_primary_uom_code      => L_demand_uom_code, --demand uom are prim
4814 				l_supply_uom_code       => L_demand_uom_code, -- 13942999
4815 				l_atd_qty               => L_demand_quantity,
4816 				l_atd_prim_qty          => L_demand_quantity,
4817 				l_supply_type_id        => 13, --Inventory
4818 				l_supply_header_id      => NULL, -- since high level rsv
4819 				l_supply_line_id        => NULL, -- since high level rsv
4820 				l_supply_line_detail_id => NULL, -- since high level rsv
4821 				l_supply_expected_time  => SYSDATE,
4822 				l_demand_expected_time  => l_expected_ship_date,
4823 				l_rsv_rec               => l_rsv_temp_rec, -- only need to provide good enough information FOR high LEVEL reservation, only one row will do
4824 		       l_serial_number         => l_serial_number,
4825 		       l_to_serial_number      => l_to_serial_number,
4826 		       l_quantity_reserved     => l_quantity_reserved,
4827 		       l_quantity_reserved2    => l_quantity_reserved2,
4828 		       l_rsv_id                => l_rsv_id,
4829 		       x_return_status         => l_return_status,
4830 		       x_msg_count             => x_msg_count,
4831 		       x_msg_data              => x_msg_data);
4832 
4833 		     IF (l_return_status <> FND_API.G_RET_STS_SUCCESS) THEN
4834 			IF (l_debug = 1) THEN
4835 
4836 			   print_debug('Error returned from create_reservation API: ' ||
4837 				       l_return_status);
4838 			END IF;
4839 			GOTO next_record;
4840 		      ELSE
4841 			IF (l_debug = 1) THEN
4842 			   print_debug('Successfully created a RSV record for MO Line');
4843 			END IF;
4844 		     END IF;
4845 
4846 		  END IF; -- for l_mtl_reservation_count = 0
4847 
4848 		  IF (l_debug = 1) THEN
4849 		     print_debug('Add entry into the WRD Table dmd_detail_id :'||l_demand_line_detail_id);
4850 		  END IF;
4851 		  -- Add an entry into WRD table
4852 		  -- STORE DATA here and do BULK INSERT later
4853 		  l_organization_id_tab(l_index) := x_consol_item_repl_tbl(i).organization_id;
4854 		  l_mo_header_id_tab(l_index) := l_mo_header_id;
4855 		  l_mo_line_id_tab(l_index) := l_mo_line_id;
4856 		  l_demand_header_id_tab(l_index) := l_demand_header_id;
4857 		  l_demand_line_id_tab(l_index) := l_demand_line_id;
4858 		  l_demand_line_detail_id_tab(l_index) :=  l_demand_line_detail_id;
4859 		  l_demand_type_id_tab(l_index) := l_demand_type_id;
4860 		  l_item_id_tab(l_index) :=  x_consol_item_repl_tbl(i).item_id;
4861 		  l_demand_uom_code_tab(l_index) :=  l_demand_uom_code;
4862 		  l_demand_quantity_tab(l_index) := l_demand_quantity;
4863 		  l_sequence_id_tab(l_index) := l_sequence_id;
4864 		  l_repl_level_tab(l_index)  := l_repl_level;
4865 		  l_repl_type_tab(l_index)   := l_repl_type;
4866 		  l_index := l_index +1;
4867 
4868 		ELSE --means p_create_Reservation = 'N'
4869 		  -- Do not need to do anything here. We do not need to call the shipping API to revert to original
4870 		  --line status because For dynamic/pull replenishment p_create_Reservation  will
4871 		  -- always be 'Y' and hence the code will never come here. For Push replenishemnt, The demand
4872 		  -- line would not have been touched yet. So it will remain in its orignal status.
4873 		  NULL;
4874 		  IF (l_debug = 1) THEN
4875 		     print_debug('Create RSV =N, Do not add in WRD table');
4876 		  END IF;
4877 	       END IF; --For p_Create_Reservation  = 'Y'
4878 
4879 
4880 	       IF (l_debug = 1) THEN
4881 		  print_debug('Remove the Demand_detail_id from the GTMP: '||l_demand_line_detail_id);
4882 	       END IF;
4883 	       -- Remove this DEMAND from the WMS_REPL_DEMAND_GTMP table
4884 	       -- IRRESPECTIVE OF p_create_reservation value. This demand is already consumed
4885 	       -- This set can be different than set inserted in the WRD table
4886 	       -- Store here to BULK DELETE later
4887 	       l_detail_id_delete_tab(l_del_index) := l_demand_line_detail_id;
4888 	       l_del_index := l_del_index +1;
4889 
4890 
4891 	       IF (l_debug = 1) THEN
4892 		  print_debug('Add to the open MO Qty in the Consol table');
4893 	       END IF;
4894 	       -- In PL/SQL table, increase the open MO qty in repl_UOM by L_demand_quantity_in_repl_uom
4895 	       x_consol_item_repl_tbl(i).open_mo_qty := x_consol_item_repl_tbl(i).open_mo_qty +L_demand_quantity_in_repl_uom;
4896 
4897 
4898 	       -- Decrease the L_mo_quantity to reflect correct available MO qty for next demand line
4899 	       -- All quantity comparision is in the repl_uom unit
4900 	       L_mo_quantity := L_mo_quantity - L_demand_quantity_in_repl_uom;
4901 
4902 
4903 	    END IF; -- L_mo_quantity >= L_demand_quantity
4904 
4905 	    <<next_record>>
4906 	      IF (l_debug = 1) THEN
4907 		 print_debug('At the end of current demand Available Open MO qty: '||L_mo_quantity);
4908 	      END IF;
4909 	      IF l_return_status <> fnd_api.g_ret_sts_success THEN
4910 		 l_return_status := fnd_api.g_ret_sts_success;
4911 		 ROLLBACK TO current_demand_sp;
4912 	      END IF;
4913 	 END LOOP; -- for each demand line
4914 	 CLOSE c_demand_lines_for_item;
4915 
4916 	 IF (l_debug = 1) THEN
4917 	    print_debug('Done with Current OPEN MO record');
4918 	    print_debug('Final Open MO qty that cound not be consumed: '||L_mo_quantity);
4919 	 END IF;
4920 
4921       END LOOP;  --for each open MO
4922       CLOSE c_open_mo_lines;
4923 
4924       --At the end for Each item In PL/SQL table, update the final_replenishment_qty in Repl_UOM
4925       x_consol_item_repl_tbl(i).final_replenishment_qty :=
4926 	(x_consol_item_repl_tbl(i).final_replenishment_qty - x_consol_item_repl_tbl(i).open_mo_qty);
4927 
4928       --Note: the final replenishment qty will be upp by the p_Repl_Lot_Size in Create_repl_Move_order() API
4929       IF (l_debug = 1) THEN
4930 	 print_debug('Done with Current Consolidated  record');
4931       END IF;
4932 
4933 
4934       END IF ; --  IF not x_consol_item_repl_tbl.exists(i)
4935 
4936    END LOOP; -- For each consolidated demand lines
4937    END IF;
4938 
4939 
4940 
4941    IF (l_debug = 1) THEN
4942       print_debug('BULK INSERT ALL CONSUMED DEMANDS IN WRD table' );
4943    END IF;
4944 
4945    -- BULK INSERT ALL consumed demands IN wms_replenishment_details table
4946    FORALL k IN INDICES OF l_demand_line_detail_id_tab
4947      INSERT INTO WMS_REPLENISHMENT_DETAILS
4948      (Replenishment_id,
4949       Organization_Id,
4950       source_header_id,
4951       Source_line_id,
4952       Source_line_detail_id,
4953       Source_type_id,
4954       demand_header_id,
4955       demand_line_id,
4956       demand_line_detail_id,
4957       demand_type_id,
4958       Inventory_item_id,
4959       Primary_UOM,
4960       Primary_Quantity,
4961       demand_sort_order,
4962       repl_level,
4963       repl_type,
4964       CREATION_DATE,
4965       LAST_UPDATE_DATE,
4966       CREATED_BY,
4967       LAST_UPDATED_BY,
4968       LAST_UPDATE_LOGIN
4969       )VALUES (
4970 	       WMS_REPLENISHMENT_DETAILS_S.NEXTVAL,
4971 	       l_organization_id_tab(k),
4972 	       l_mo_header_id_tab(k),
4973 	       l_mo_line_id_tab(k),
4974 	       NULL,
4975 	       4, --  For Move Orders
4976 	       l_demand_header_id_tab(k),
4977 	       l_demand_line_id_tab(k),
4978 	       l_demand_line_detail_id_tab(k),
4979 	       l_demand_type_id_tab(k),
4980 	       l_item_id_tab(k),
4981 	       l_demand_uom_code_tab(k),
4982 	       l_demand_quantity_tab(k),
4983 	       l_sequence_id_tab(k),
4984 	       l_repl_level_tab(k),
4985 	       l_repl_type_tab(k),
4986 	       Sysdate,
4987 	       Sysdate,
4988 	       fnd_global.user_id,
4989 	       fnd_global.user_id,
4990 	       fnd_global.user_id
4991 	       );
4992 
4993    -- CLEAR all entries in the tables
4994    l_organization_id_tab.DELETE;
4995    l_mo_header_id_tab.DELETE;
4996    l_mo_line_id_tab.DELETE;
4997    l_demand_header_id_tab.DELETE;
4998    l_demand_line_id_tab.DELETE;
4999    l_demand_line_detail_id_tab.DELETE;
5000    l_demand_type_id_tab.DELETE;
5001    l_item_id_tab.DELETE;
5002    l_demand_uom_code_tab.DELETE;
5003    l_demand_quantity_tab.DELETE;
5004    l_sequence_id_tab.DELETE;
5005    l_repl_level_tab.DELETE;
5006    l_repl_type_tab.DELETE;
5007 
5008    IF (l_debug = 1) THEN
5009       print_debug('BULK REMOVE ALL CONSUMED DEMANDS FROM GTMP table' );
5010    END IF;
5011    -- BULK Remove all consumed demands from WMS_REPL_DEMAND_GTMP table
5012    FORALL k in 1 .. l_detail_id_delete_tab.COUNT()
5013      DELETE  From WMS_REPL_DEMAND_GTMP
5014      WHERE demand_line_detail_id = l_detail_id_delete_tab(k);
5015 
5016    -- CLEAR all entries in the tables
5017    l_detail_id_delete_tab.DELETE;
5018 
5019    IF (l_debug = 1) THEN
5020       print_debug('DONE WITH API - GET_OPEN_MO_QTY' );
5021    END IF;
5022    x_return_status := fnd_api.g_ret_sts_success;
5023 EXCEPTION
5024    WHEN OTHERS THEN
5025       x_return_status := fnd_api.g_ret_sts_error;
5026       IF c_demand_lines_for_item%ISOPEN THEN
5027 	 CLOSE c_demand_lines_for_item;
5028       END IF;
5029       IF c_open_mo_lines%ISOPEN THEN
5030 	 CLOSE c_open_mo_lines;
5031       END IF;
5032 
5033       IF (l_debug = 1) THEN
5034 	 print_debug('Error in GET_OPEN_MO_QTY SQLCODE: '||SQLCODE ||' : '||SQLERRM );
5035       END IF;
5036 
5037 END GET_OPEN_MO_QTY;
5038 
5039 
5040 PROCEDURE  GET_AVAILABLE_ONHAND_QTY(p_Repl_level           IN NUMBER,
5041 				    p_repl_type            IN NUMBER,
5042 				    p_Create_Reservation   IN VARCHAR2,
5043 				    x_consol_item_repl_tbl IN OUT NOCOPY CONSOL_ITEM_REPL_TBL,
5044 				    x_return_status        OUT NOCOPY VARCHAR2,
5045 				    x_msg_count            OUT NOCOPY NUMBER,
5046 				    x_msg_data             OUT NOCOPY VARCHAR2)
5047   IS
5048 
5049 
5050      l_debug              NUMBER      := NVL(fnd_profile.VALUE('INV_DEBUG_TRACE'), 0);
5051      l_demand_header_id NUMBER;
5052      l_demand_type_id NUMBER;
5053      l_sequence_id      NUMBER;
5054      l_demand_line_id NUMBER;
5055      l_demand_line_detail_id NUMBER;
5056      l_demand_quantity NUMBER;
5057      l_demand_uom_code VARCHAR2(3);
5058      l_expected_ship_date   DATE;
5059      l_demand_quantity_in_repl_uom NUMBER;
5060 
5061      l_last_sub VARCHAR2(30) := NULL;
5062      l_qoh NUMBER;
5063      l_rqoh NUMBER;
5064      l_qr   NUMBER;
5065      l_qs NUMBER;
5066      l_att NUMBER;
5067      l_atr NUMBER;
5068      l_mtl_reservation_count NUMBER;
5069 
5070      l_rsv_temp_rec   inv_reservation_global.mtl_reservation_rec_type;
5071      l_rsv_temp_rec_2 inv_reservation_global.mtl_reservation_rec_type;
5072      l_rsv_rec            inv_reservation_global.mtl_reservation_tbl_type;
5073 
5074      l_prev_org_id NUMBER;
5075      l_prev_item_id NUMBER;
5076      l_prev_sub_code VARCHAR2(10);
5077      l_qty_tree_demand_line_id NUMBER;
5078 
5079      l_rsv_id_tb num_tab;
5080      l_detail_info_tab             WSH_INTERFACE_EXT_GRP.delivery_details_Attr_tbl_Type;
5081      l_in_rec                      WSH_INTERFACE_EXT_GRP.detailInRecType;
5082      l_out_rec                     WSH_INTERFACE_EXT_GRP.detailOutRecType;
5083 
5084      l_serial_number      inv_reservation_global.serial_number_tbl_type;
5085      l_to_serial_number   inv_reservation_global.serial_number_tbl_type;
5086      l_quantity_reserved  NUMBER;
5087      l_quantity_reserved2 NUMBER;
5088      l_rsv_id             NUMBER;
5089      l_error_code         NUMBER;
5090 
5091      l_is_revision_ctrl BOOLEAN;
5092      l_is_lot_ctrl  BOOLEAN;
5093      l_is_serial_ctrl  BOOLEAN;
5094 
5095      l_del_index NUMBER;
5096      l_del_consol_item_tb num_tab;
5097      l_repl_status VARCHAR2(1);
5098      l_bkorder_cnt NUMBER;
5099 
5100      CURSOR c_demand_lines_for_item(p_org_id NUMBER, p_item_id number, p_fp_sub VARCHAR2) IS
5101 	SELECT repl_sequence_id, demand_header_id, demand_line_id,
5102 	  demand_line_detail_id,
5103 	  demand_type_id, quantity, uom_code, expected_ship_date,
5104 	  quantity_in_repl_uom, repl_status
5105 	  FROM  WMS_REPL_DEMAND_GTMP
5106 	  WHERE  ORGANIZATION_ID = P_ORG_ID
5107 	  AND inventory_item_id = p_item_id
5108 	  AND  repl_to_subinventory_code = p_fp_sub
5109 	  order by Repl_Sequence_id;
5110 
5111      l_return_status VARCHAR2(3) := fnd_api.g_ret_sts_success;
5112 BEGIN
5113 
5114    x_return_status := l_return_status;
5115 
5116    IF (l_debug = 1) THEN
5117       print_debug('Inside GET_AVAILABLE_ONHAND_QTY API' );
5118    END IF;
5119 
5120    -- For all Items in the pl/sql table
5121    IF (x_consol_item_repl_tbl.count>0) THEN --bug#10185153
5122    FOR i IN x_consol_item_repl_tbl.FIRST.. x_consol_item_repl_tbl.LAST LOOP
5123       IF (l_debug = 1) THEN
5124 	 print_debug('Consol record Index :' || i);
5125       END IF;
5126 
5127       IF (NOT x_consol_item_repl_tbl.exists(i)) THEN
5128 
5129 	 IF (l_debug = 1) THEN
5130 	    print_debug('CURRENT INDEX IN THE CONSOL TABLE HAS BEEN Discarded - moving TO next consol RECORD' );
5131 
5132 	 END IF;
5133        ELSE
5134 
5135 
5136       SAVEPOINT onhd_consol_rec_sp;
5137       -- For all demand lines net the available OnHand
5138       OPEN  c_demand_lines_for_item(x_consol_item_repl_tbl(i).ORGANIZATION_ID,
5139 				    x_consol_item_repl_tbl(i).item_id,
5140 				    x_consol_item_repl_tbl(i).repl_to_subinventory_code);
5141       LOOP
5142 	 SAVEPOINT onhd_demand_line_sp;
5143 
5144 	 FETCH  c_demand_lines_for_item INTO L_sequence_id,
5145 	   L_demand_header_id, L_demand_line_id,
5146 	   L_demand_line_detail_id, l_demand_type_id, L_demand_quantity,
5147 	   L_demand_uom_code,
5148 	   l_expected_ship_date, l_demand_quantity_in_repl_uom, l_repl_status;
5149 	 EXIT WHEN c_demand_lines_for_item%notfound;
5150 
5151 	 IF (l_debug = 1) THEN
5152 	    print_debug('=======Netting onhand for NEW Demand line=======');
5153 	    print_debug('Next Demand for consol Item Record :' ||l_demand_line_detail_id ||', Dmd_QTY :'||l_demand_quantity
5154 			||', Qty_in_repl_UOM :'||l_demand_quantity_in_repl_uom);
5155 	    print_debug('l_demand_type_id :'||l_demand_type_id);
5156 	 END IF;
5157 
5158 	 -- For an Org+item+Sub combination, the qty tree should be called only once
5159 	 IF (( l_prev_org_id IS NULL AND l_prev_item_id IS NULL AND
5160 	       l_prev_sub_code IS NULL ) OR
5161 	     l_prev_org_id <> x_consol_item_repl_tbl(i).ORGANIZATION_ID  OR
5162 	     l_prev_item_id <> x_consol_item_repl_tbl(i).item_id OR
5163 	     l_prev_sub_code <> x_consol_item_repl_tbl(i).repl_to_subinventory_code ) THEN
5164 
5165 	    l_atr := 0;
5166 	    -- Get all item details
5167 	    IF inv_cache.set_item_rec(x_consol_item_repl_tbl(i).ORGANIZATION_ID, x_consol_item_repl_tbl(i).item_id)  THEN
5168 
5169 	       IF (l_debug = 1) THEN
5170 		  print_debug('Getting Item Attribute Details' );
5171 	       END IF;
5172 
5173 	       IF inv_cache.item_rec.revision_qty_control_code = 2 THEN
5174 		  l_is_revision_ctrl := TRUE;
5175 		ELSE
5176 		  l_is_revision_ctrl := FALSE;
5177 	       END IF;
5178 
5179 	       IF inv_cache.item_rec.lot_control_code = 2 THEN
5180 		  l_is_lot_ctrl := TRUE;
5181 		ELSE
5182 		  l_is_lot_ctrl := FALSE;
5183 	       END IF;
5184 
5185 	       IF inv_cache.item_rec.serial_number_control_code NOT IN (1,6) THEN
5186 		  l_is_serial_ctrl := FALSE;
5187 		ELSE
5188 		  l_is_serial_ctrl := TRUE;
5189 	       END IF;
5190 
5191 	     ELSE
5192 	       IF (l_debug = 1) THEN
5193 		  print_debug('Error: Item detail not found');
5194 	       END IF;
5195 	       l_return_status := fnd_api.g_ret_sts_error;
5196 	       GOTO next_onhd_consol_rec;
5197 	    END IF; -- for inv_cache.set_item_rec
5198 
5199 
5200 	    IF (l_debug = 1) THEN
5201 	       print_debug('Clearing Qty Tree' );
5202 	    END IF;
5203 	    --Query Quantity Tree
5204 	    inv_quantity_tree_pub.clear_quantity_cache;
5205 
5206 	    IF (l_debug = 1) THEN
5207 	       print_debug('Calling Qty Tree API' );
5208 	    END IF;
5209 
5210 	    inv_quantity_tree_pub.query_quantities
5211 	      (
5212 	       p_api_version_number         => 1.0
5213 	       , p_init_msg_lst               => fnd_api.g_false
5214 	       , x_return_status              => l_return_status
5215 	       , x_msg_count                  => x_msg_count
5216 	       , x_msg_data                   => x_msg_data
5217 	       , p_organization_id            => x_consol_item_repl_tbl(i).organization_id
5218 	       , p_inventory_item_id          => x_consol_item_repl_tbl(i).item_id
5219 	       , p_tree_mode                  => inv_quantity_tree_pub.g_transaction_mode
5220 	       , p_is_revision_control        =>  l_is_revision_ctrl
5221 	       , p_is_lot_control             =>  l_is_lot_ctrl
5222 	       , p_is_serial_control          =>  l_is_serial_ctrl
5223 	       , p_demand_source_type_id    => l_demand_type_id  -- 2 (OE) / 8 for Internal Order
5224 	       , p_demand_source_header_id  => L_demand_header_id
5225 	       , p_demand_source_line_id    => L_demand_line_id
5226 	       , p_revision                 => NULL
5227 	       , p_lot_number                => NULL
5228 	      , p_subinventory_code          => x_consol_item_repl_tbl(i).repl_to_subinventory_code
5229 	      , p_locator_id                 => NULL
5230 	      , x_qoh                        => l_qoh
5231 	      , x_rqoh                       => l_rqoh
5232 	      , x_qr                         => l_qr
5233 	      , x_qs                         => l_qs
5234 	      , x_att                        => l_att
5235 	      , x_atr                        => l_atr
5236 	      );
5237 
5238 	    IF (l_debug = 1) THEN
5239 	       print_debug( 'Return status from QTY TREE:' ||l_return_status);
5240 	       print_debug( 'l_atr is: '||l_atr);
5241 	    END IF;
5242 	    IF (l_return_status <> fnd_api.g_ret_sts_success) THEN
5243 	       GOTO next_onhd_consol_rec;
5244 	    END IF;
5245 	    -- Store the demand line for which the qty tree was called
5246 	    l_qty_tree_demand_line_id := l_demand_line_id;
5247 
5248 
5249 	 END IF; --For an Org+item+Sub combination
5250 
5251 
5252 	 -- In transaction_mode call to API inv_quantity_tree_pub.query_quantities pass parameters: item_id, demand header, demand line, subinventory
5253 
5254 	 --For l_atr calculation for all high level reservations, qty_tree first consumes all available material from outside the current SUB then bite from the current sub if remaining any.
5255 
5256 	 --(l_atr) will be available qty to reserve. It includes rsv_qty
5257 	 --for current demand line  (if detailed at current sub OR high level rsv).
5258 	 --It does not include qty if the current demand is detailed at other sub.
5259 	 --It deduct any detailed rsv by other demand lines at the current sub
5260 
5261 	 --l_qr - detailed resv by ALL Other demands at the CURRENT sub (does not include rsv_qty by current demand line)
5262 
5263 	 IF l_atr > 0 THEN
5264 
5265 	    -- Note:  if l_atr < l_demand_qty, then we would rather
5266 	    --create new replenishment MO than splitting the demand line FOR simplicity
5267 
5268 	    IF l_atr >= l_demand_quantity THEN
5269 	       IF (l_debug = 1) THEN
5270 		  PRINT_DEBUG('Enough Qty - Consuming this demand :' ||L_demand_line_detail_id);
5271 	       END IF;
5272 
5273 	       -- Check if rsv exists for the current demand line from table mtl_reservations
5274 	       -- Use Query_reservation() API
5275 	       -- Make sure that if rsv exists all qty must be either high level rsv or must be all completely detailed.
5276 	       -- Lets say that we get l_existing_rsv_qty from MR table for current demand which
5277 	       -- should be less than or equal to l_demand_qty
5278 
5279 	       IF (l_debug = 1) THEN
5280 		  PRINT_DEBUG('****Check if Reservation exists for current demand');
5281 	       END IF;
5282 
5283 	       -- Check if reservation exists for corresponding order line
5284 	       -- Clear out old values
5285 	       l_rsv_temp_rec := l_rsv_temp_rec_2;
5286 
5287 	       -- Assign all new values
5288 	       l_rsv_temp_rec.organization_id := x_consol_item_repl_tbl(i).organization_id;
5289 	       l_rsv_temp_rec.inventory_item_id := x_consol_item_repl_tbl(i).item_id;
5290 	       l_rsv_temp_rec.DEMAND_SOURCE_TYPE_ID := l_demand_type_id;
5291 	       l_rsv_temp_rec.DEMAND_SOURCE_HEADER_ID := l_demand_header_id;
5292 	       l_rsv_temp_rec.DEMAND_SOURCE_LINE_ID := l_demand_line_id;
5293 
5294 	       inv_reservation_pub.query_reservation(
5295 						     p_api_version_number =>1.0,
5296 						     x_return_status => l_return_status,
5297 						     x_msg_count   => x_msg_count,
5298 						     x_msg_data    => x_msg_data,
5299 						     p_query_input => l_rsv_temp_rec,
5300 						     x_mtl_reservation_tbl  => l_rsv_rec,
5301 						     x_mtl_reservation_tbl_count => l_mtl_reservation_count,
5302 						     x_error_code => l_error_code);
5303 
5304 	       IF l_RETURN_status = fnd_api.g_ret_sts_success THEN
5305 		  IF (l_debug = 1) THEN
5306 		     PRINT_DEBUG('*****Number of reservations found: ' ||l_mtl_reservation_count);
5307 		  END IF;
5308 
5309 		ELSE
5310 		  IF (l_debug = 1) THEN
5311 		     PRINT_DEBUG('Error: ' || X_msg_data);
5312 		  END IF;
5313 		  GOTO next_dmd_record;
5314 	       END IF;
5315 
5316 	       -- IMP NOTE: only HIGH LEVEL RSV can exists for 'demands slated for replenishment' at this point for
5317 	       -- BOTH type of replenishments since detailed rsv has been discarded from the original demand cursor
5318 	       -- BUT if somehow in between the time duration, user details one of the high
5319 	       -- LEVEL reservation demand line, we assume that he does not
5320 	       -- break reservation across different sub TO consume the demand qty
5321 
5322 
5323 	       IF l_mtl_reservation_count <> 0 THEN -- RSV EXISTS
5324 
5325 		  -- FIND IF ALL RECORDS HAVE SAME TYPE OF RSV
5326 		  -- means EITHER HIGH LEVEL OR detail LEVEL at the SAME subinventory
5327 		  -- Note: Reservation can not be made for qty greater than demand_qty on the order
5328 
5329 
5330 		  l_rsv_id_tb.DELETE;
5331 		  IF (l_rsv_rec.count>0) THEN --bug#10185153
5332 		  FOR i IN l_rsv_rec.first.. l_rsv_rec.last LOOP
5333 		     l_rsv_id_tb(i) := l_rsv_rec(i).reservation_id;
5334 		     IF i <> 1 THEN
5335 			IF (l_rsv_rec(i).subinventory_code IS NULL AND l_last_sub IS NOT NULL)
5336 			  OR
5337 			  (l_rsv_rec(i).subinventory_code IS NOT NULL AND l_last_sub IS NULL)
5338 			    OR (l_rsv_rec(i).subinventory_code IS NOT NULL AND
5339 				l_last_sub IS NOT NULL AND l_rsv_rec(i).subinventory_code <> l_last_sub)
5340 				  THEN
5341 			   IF (l_debug = 1) THEN
5342 			      print_debug('SKIP Current Demand: Mixed level of reservation');
5343 			   END IF;
5344 			   -- means mixed level of rsv, we will rather CREATE NEW replenishment
5345 			   -- We will not account for these rsv in this case
5346 			   -- Since we need to skip to next demand and
5347 			   -- behave as if this demand is in error
5348 			   l_return_status := fnd_api.g_ret_sts_error;
5349 			   GOTO next_dmd_record;
5350 			END IF;
5351 
5352 		     END IF;
5353 		     l_last_sub := l_rsv_rec(i).subinventory_code;
5354 
5355 		     -- What if the reserved qty is less than the demand
5356 		     -- qty, there IS left OUT qty FOR the line TO be reserved
5357 		  END LOOP;
5358 		  END IF;
5359 
5360 		  IF (l_debug = 1) THEN
5361 		     print_debug('If Sub Level RSV, SUB :'||l_last_sub);
5362 		  END IF;
5363 
5364 		  -- If the l_last_sub is not null, means detailed rsv
5365 		  -- because all rsv data has to be of same type either NULL OR same subinventory
5366 
5367 		  IF l_last_sub is NULL THEN -- high level rsv
5368 
5369 		     IF (l_debug = 1) THEN
5370 			print_debug('****** It is High Level RSV Exists');
5371 			print_debug('****** Call WSH to make Lines as RC');
5372 		     END IF;
5373 
5374 		     -- Call Shipping API to mark the Delivery Detail TO 'RC'.
5375 		     update_wdd_repl_status (p_deliv_detail_id   =>  l_demand_line_detail_id
5376 					     , p_repl_status     => 'C'  -- for completed status
5377 					     , x_return_status   => l_return_status
5378 					     );
5379 
5380 		     IF l_return_status <> fnd_api.g_ret_sts_success THEN
5381 			GOTO next_dmd_record;
5382 		     END IF;
5383 
5384 
5385 		     -- Remove the entry from the WMS_REPL_DEMAND_GTMP table
5386 		     IF (l_debug = 1) THEN
5387 			print_debug('Remove Entry from WRDG table');
5388 		     END IF;
5389 		     DELETE FROM wms_repl_demand_gtmp
5390 		       WHERE  Organization_id = x_consol_item_repl_tbl(i).organization_id
5391 		       AND INVENTORY_ITEM_ID =  x_consol_item_repl_tbl(i).item_id
5392 		       AND demand_type_id = l_demand_type_id
5393 		       AND DEMAND_LINE_DETAIL_ID = l_demand_line_detail_id
5394 		       AND demand_header_id = l_demand_header_id
5395 		       AND demand_line_id = l_demand_line_id;
5396 
5397 		     -- Detail the reservation to the current sub. We will consume right here
5398 		     IF (l_debug = 1) THEN
5399 			print_debug('Detail High Level Rsv to Detailed CURRENT sub :'
5400 				    || x_consol_item_repl_tbl(i).repl_to_subinventory_code);
5401 		     END IF;
5402 		     FORALL k in 1 .. l_rsv_rec.COUNT()
5403 		       UPDATE mtl_reservations
5404 		       SET     subinventory_code = x_consol_item_repl_tbl(i).repl_to_subinventory_code
5405 		       WHERE   reservation_id = l_rsv_id_tb(k);
5406 
5407 
5408 		     IF (l_debug = 1) THEN
5409 			print_debug('Add to the available onhand for this item');
5410 		     END IF;
5411 		     -- In PL/SQL table, increase the available OnHand qty in repl_UOM by L_demand_quantity_in_repl_uom
5412 		     x_consol_item_repl_tbl(i).available_onhand_qty :=
5413 		       x_consol_item_repl_tbl(i).available_onhand_qty + L_demand_quantity_in_repl_uom;
5414 
5415 
5416 		     --Decrease the l_atr to reflect correct available OnHand qty for next demand line.
5417 		     --This seems to be a pessimistic approach. If all demands are at high level in the set and all material is in the current, then l_atr
5418 		     --  would already have deducted for all demands. If we deduct it again, we are asking for twice the qty than it should.
5419 
5420 		     --  But above will not be a very common business scenario because if all material is in the current sub, then we will not be talking of replenishment here.
5421 		     --  In general pick areas will have minial quantity and major qty are stores in bulk areas in the facility
5422 
5423 		     IF (l_debug = 1) THEN
5424 			print_debug('decrese the consumed qty from the curent atr FOR this demand');
5425 		     END IF;
5426 		     -- All quantity comparision is in the primary unit
5427 		     l_atr := l_atr - l_demand_quantity;
5428 
5429 
5430 		   ELSIF l_last_sub = x_consol_item_repl_tbl(i).repl_to_subinventory_code THEN
5431 		     -- means detailed at Current sub
5432 		     IF (l_debug = 1) THEN
5433 			print_debug('It is Detailed RSV at the current FP sub');
5434 			print_debug('Call WSH to mark current dmand RC');
5435 		     END IF;
5436 
5437 
5438 		     -- Call Shipping API to mark the Delivery Detail TO 'RC'.
5439 		     update_wdd_repl_status (p_deliv_detail_id   =>  l_demand_line_detail_id
5440 					     , p_repl_status     => 'C'  -- for completed status
5441 					     , x_return_status   => l_return_status
5442 					     );
5443 
5444 		     IF l_return_status <> fnd_api.g_ret_sts_success THEN
5445 			GOTO next_dmd_record;
5446 		     END IF;
5447 
5448 		     IF (l_debug = 1) THEN
5449 			print_debug('Remove the entry from the WRDG table');
5450 		     END IF;
5451 		     -- Remove the entry from the WMS_REPL_DEMAND_GTMP table
5452 		     DELETE FROM wms_repl_demand_gtmp
5453 		       WHERE  Organization_id = x_consol_item_repl_tbl(i).organization_id
5454 		       AND INVENTORY_ITEM_ID =  x_consol_item_repl_tbl(i).item_id
5455 		       AND demand_type_id = l_demand_type_id
5456 		       AND DEMAND_LINE_DETAIL_ID = l_demand_line_detail_id
5457 		       AND demand_header_id = l_demand_header_id
5458 		       AND demand_line_id = l_demand_line_id;
5459 
5460 
5461 		     IF (l_debug = 1) THEN
5462 			print_debug('Add to the available onhand for this item');
5463 		     END IF;
5464 		     -- In PL/SQL table, increase the available OnHand qty in repl_UOM by L_demand_quantity_in_repl_uom
5465 		     x_consol_item_repl_tbl(i).available_onhand_qty := x_consol_item_repl_tbl(i).available_onhand_qty + L_demand_quantity_in_repl_uom;
5466 
5467 
5468 		     --If the qty_tree is run the current_demand in the set then there we must decrease the demand_qty from l_atr BUT if the qty_tree was not run for
5469 		     --the current_demand then demand_qty should not be decreased from
5470 		     --  l_atr becse it has already been deducted when qty_tree returned
5471 		     --  l_atr.
5472 
5473 		     IF (l_debug = 1) THEN
5474 			print_debug('decrese the consumed qty only if atr was calculated FOR curent demand');
5475 		     END IF;
5476 
5477 		     IF  l_qty_tree_demand_line_id = l_demand_line_id THEN
5478 			-- All quantity comparision is in the primary unit
5479 			l_atr := l_atr - l_demand_quantity;
5480 		     END IF;
5481 
5482 
5483 		   ELSE -- menas detailed at other sub
5484 		     -- SKIP current demand line assuming it will be fulfilled up by other sub
5485 		     -- Since we need to skip to next demand and
5486 		     -- behave as if this demand is in error
5487 		     l_return_status := fnd_api.g_ret_sts_error;
5488 		     GOTO next_dmd_record;
5489 		  END IF;
5490 
5491 
5492 
5493 		ELSE --means rsv does not exists
5494 
5495 		  IF (l_debug = 1) THEN
5496 		     print_debug('NO RESERVATION EXISTS FOR CURRENT DEMAND');
5497 		  END IF;
5498 
5499 
5500 		  IF p_Create_Reservation  = 'Y' THEN
5501 
5502 		     IF (l_debug = 1) THEN
5503 			print_debug('p_Create_Rsv is Y and qty available - Creating detailed rsv AT FP sub' );
5504 		     END IF;
5505 
5506 		     --TEST: CALL Create_RSV() API to create reservation AT DETAILED LEVEL to this sub
5507 		     l_return_status := fnd_api.g_ret_sts_success;
5508 		     Create_RSV(p_replenishment_type => 1, --  1- Stock Up/Push; 2- Dynamic/Pull
5509 				l_debug => l_debug,
5510 				l_organization_id => x_consol_item_repl_tbl(i).ORGANIZATION_ID,
5511 				l_inventory_item_id => x_consol_item_repl_tbl(i).item_id,
5512 				l_demand_type_id => l_demand_type_id,
5513 				l_demand_so_header_id => L_demand_header_id,
5514 				l_demand_line_id => L_demand_line_id,
5515 				l_split_wdd_id => NULL,
5516 				l_primary_uom_code => l_demand_uom_code,
5517 				l_supply_uom_code => l_demand_uom_code,
5518 				l_atd_qty => L_demand_quantity,
5519 				l_atd_prim_qty => L_demand_quantity,
5520 				l_supply_type_id => 13,
5521 				l_supply_header_id => NULL, -- since sub LEVEL from inventory
5522 				l_supply_line_id => NULL, -- since sub LEVEL from inventory
5523 				l_supply_line_detail_id => NULL, -- since sub LEVEL from inventory
5524 				l_supply_expected_time => SYSDATE,
5525 				l_demand_expected_time => l_expected_ship_date,
5526 				l_subinventory_code => x_consol_item_repl_tbl(i).repl_to_subinventory_code,
5527 		       l_rsv_rec => l_rsv_temp_rec,
5528 		       l_serial_number => l_serial_number,
5529 		       l_to_serial_number => l_to_serial_number,
5530 		       l_quantity_reserved => l_quantity_reserved,
5531 		       l_quantity_reserved2 => l_quantity_reserved2,
5532 		       l_rsv_id => l_rsv_id,
5533 		       x_return_status => l_return_status,
5534 		       x_msg_count => x_msg_count,
5535 		       x_msg_data => x_msg_data
5536 		       );
5537 
5538 		     IF (l_return_status <> FND_API.G_RET_STS_SUCCESS) THEN
5539 			IF (l_debug = 1) THEN
5540 			   print_debug('Error returned from create_reservation API: ' || l_return_status);
5541 			END IF;
5542 			-- Proceed to next record. In this case we might have extra amount on MOL than rsv
5543 			GOTO next_dmd_record;
5544 
5545 		      ELSE -- reservation creation successful
5546 			IF (l_debug = 1) THEN
5547 			   print_debug('Successfully created a RSV for demand ');
5548 			END IF;
5549 
5550 		     END IF;
5551 
5552 		   ELSE -- means p_Create_Reservation  = 'N'
5553 		     -- DO nothing
5554 		     IF (l_debug = 1) THEN
5555 			print_debug('p_Create_Rsv is N and qty available' );
5556 		     END IF;
5557 		  END IF; --p_Create_Reservation  = 'Y'
5558 
5559 		  -- Mark these demand records as 'RC'.
5560 		  -- These demand lines Status go directly from Ready to
5561 		  -- release to RC because  material is physically present AT the sub
5562 		  -- < in case of open move order, we will not it will NOT be marked RC though>
5563 		  -- Note:  In some cases lines might already by in
5564 		  -- repl_status = RC here BECS original demand cursol includes repl_status = 'C' demand lines
5565 
5566 		  IF (l_debug = 1) THEN
5567 		     print_debug('call WSH to mark lines as RC' );
5568 		  END IF;
5569 
5570 		  IF l_repl_status <> 'C' THEN
5571 		     update_wdd_repl_status (p_deliv_detail_id   =>  l_demand_line_detail_id
5572 					     , p_repl_status     => 'C'  -- for completed status
5573 					     , x_return_status   => l_return_status
5574 					     );
5575 
5576 		     IF l_return_status <> fnd_api.g_ret_sts_success THEN
5577 			GOTO next_dmd_record;
5578 		     END IF;
5579 
5580 		  END IF; -- FOR IF l_repl_status <> 'C'
5581 
5582 
5583 
5584 		  IF (l_debug = 1) THEN
5585 		     print_debug('Remove entry from GTMP table');
5586 		  END IF;
5587 		  -- Remove the demand entry from the WMS_REPL_DEMAND_GTMP table
5588 		  DELETE FROM wms_repl_demand_gtmp
5589 		    WHERE  Organization_id = x_consol_item_repl_tbl(i).organization_id
5590 		    AND INVENTORY_ITEM_ID =  x_consol_item_repl_tbl(i).item_id
5591 		    AND demand_type_id = l_demand_type_id
5592 		    AND DEMAND_LINE_DETAIL_ID = l_demand_line_detail_id
5593 		    AND demand_header_id = l_demand_header_id
5594 		    AND demand_line_id = l_demand_line_id;
5595 
5596 
5597 		  IF (l_debug = 1) THEN
5598 		     print_debug('Increase availble onhand and decrese l_atr');
5599 		  END IF;
5600 		  -- In PL/SQL table, increase the available OnHand qty in repl_UOM by L_demand_quantity_in_repl_uom
5601 		  x_consol_item_repl_tbl(i).available_onhand_qty
5602 		    := x_consol_item_repl_tbl(i).available_onhand_qty + L_demand_quantity_in_repl_uom;
5603 
5604 		  -- Decrease the l_atr to reflect correct available OnHand qty for next demand line
5605 		  -- All quantity comparision is in the primary unit
5606 		  l_atr := l_atr - l_demand_quantity;
5607 
5608 
5609 	       END IF; -- FOR RSV EXISTS
5610 
5611 
5612 	     ELSE -- means l_atr < l_demand_qty
5613 	       --  Here it can come in one case when
5614 	       --  L_atr > 0 and l_atr < l_demand_qty in subsequent loops after consuming from l_atr
5615 	       --   Once l_atr becomes 0, it goes to other part of the else condition below
5616 
5617 	       --  Available onhand (atr) = 22 at location [ out of this 22 QTY,  20 was for D1 initially but in this run another high priority otrder D2 has come above D1]
5618 
5619 	       --    Demand  demand_qty  priority  status      Action/new status
5620 	       --    D2    10    high           RC
5621 	       --    D1    20   low  RC  (no rsv exists for d1)      Revert to original stat
5622 	       --    D3    2    lower          Will be marked RC
5623 	       --    D4    5    lowest  RC  (no rsv exists for d1)    Revert to original stat
5624 	       --    D5    10   lowest            Do not touch
5625 	       --    After D2 gets processed and the at the time of processing D1, l_atr = 12 and l_demand_qty = 20
5626 	       --    D3 will be processed in the conditional block of 'l_atr >= l_demand_qty' above
5627 	       --  D5 will be processed in the conditional block ELSE -- means l_atr <= 0 below
5628 
5629 	       IF (l_debug = 1) THEN
5630 		  print_debug('Here l_atr < l_demand_qty. Nothing to do..');
5631 	       END IF;
5632 
5633 
5634 	       IF l_repl_status = 'C' THEN
5635 
5636 		  IF (l_debug = 1) THEN
5637 		     print_debug('DmdLine alredy RC, but this run does NOT have enough qty any longer ');
5638 		     print_debug('Backorder delivery_detail - l_demand_line_detail_id ');
5639 		  END IF;
5640 		  -- Code will come here only for Push Repl if Create_rsv = N
5641 		  -- Add to the global variable table to be backordered later
5642 
5643 		  l_bkorder_cnt := g_backorder_deliv_tab.COUNT()+1;
5644 
5645 		  g_backorder_deliv_tab(l_bkorder_cnt):= l_demand_line_detail_id;
5646 		  g_backorder_qty_tab(l_bkorder_cnt) := l_demand_quantity;
5647 		  -- since we are backordering entire qty parameters
5648 		  -- p_bo_qtys AND  p_req_qtys will have same value
5649 		  g_dummy_table(l_bkorder_cnt)       := 0;
5650 
5651 	       END IF; -- FOR l_repl_status = 'C'
5652 
5653 
5654 
5655 	    END IF; -- l_atr > l_demand_qty
5656 
5657 	  ELSE -- MEANS l_atr <= 0
5658 
5659 	    IF (l_debug = 1) THEN
5660 	       print_debug('Here l_atr <= 0 '||l_atr);
5661 	    END IF;
5662 
5663 	    IF l_repl_status = 'C' THEN
5664 
5665 	       IF (l_debug = 1) THEN
5666 		  print_debug('DmdLine already RC - but this run does NOT have enough qty any longer');
5667 		  print_debug('Backorder delivery_detail - l_demand_line_detail_id ');
5668 	       END IF;
5669 	       -- Code will come here only for Push Repl if Create_rsv = N
5670 	       -- Add to the global variable table to be backordered later
5671 
5672 	       l_bkorder_cnt := g_backorder_deliv_tab.COUNT()+1;
5673 
5674 	       g_backorder_deliv_tab(l_bkorder_cnt):= l_demand_line_detail_id;
5675 	       g_backorder_qty_tab(l_bkorder_cnt) := l_demand_quantity;
5676 	       -- since we are backordering entire qty parameters
5677 	       -- p_bo_qtys AND  p_req_qtys will have same value
5678 	       g_dummy_table(l_bkorder_cnt)       := 0;
5679 
5680 	    END IF; --FOR l_repl_status = 'C'
5681 
5682 	 END IF; -- FOR 	l_atr > 0
5683 
5684 	 <<next_dmd_record>>
5685 	 l_prev_org_id := x_consol_item_repl_tbl(i).ORGANIZATION_ID ;
5686 	 l_prev_item_id := x_consol_item_repl_tbl(i).item_id;
5687 	 l_prev_sub_code := x_consol_item_repl_tbl(i).repl_to_subinventory_code;
5688 	 print_debug( 'l_atr AT THE END OF CURRENT DEMAND LINE: '||l_atr);
5689 
5690 	 IF l_return_status <> fnd_api.g_ret_sts_success THEN
5691 	    IF (l_debug = 1 ) THEN
5692 	       print_debug('Move to next demand record ignoring this one');
5693 	    END IF;
5694 	    ROLLBACK TO onhd_demand_line_sp;
5695 	    l_return_status := fnd_api.g_ret_sts_success;
5696 	    x_consol_item_repl_tbl(i).total_demand_qty :=
5697 	      x_consol_item_repl_tbl(i).total_demand_qty - l_demand_quantity_in_repl_uom;
5698 
5699 	    -- For pull and demand_type_id<>4, Backorder the WDD
5700 	    -- Add to the global variable table to be called at the end of
5701 	    -- the dynamic repl process
5702 
5703 	    -- We do not need to do it for Push repl since rollback takes care
5704 	    -- of it whereas for Pull repl, shipping has committed his change and
5705 	    -- hence we need to make explicit call to backorder it
5706 
5707 	    IF l_demand_type_id <> 4 AND p_repl_type = g_dynamic_repl AND
5708 	      Nvl(p_repl_level,1) = 1 THEN
5709 
5710 	       l_bkorder_cnt := g_backorder_deliv_tab.COUNT()+1;
5711 
5712 	       g_backorder_deliv_tab(l_bkorder_cnt):= l_demand_line_detail_id;
5713 	       g_backorder_qty_tab(l_bkorder_cnt) := l_demand_quantity;
5714 	       -- since we are backordering entire qty parameters
5715 	       -- p_bo_qtys AND  p_req_qtys will have same value
5716 	       g_dummy_table(l_bkorder_cnt)       := 0;
5717 
5718 	    END IF;
5719 
5720 
5721 	    DELETE FROM wms_repl_demand_gtmp
5722 	      WHERE  Organization_id = x_consol_item_repl_tbl(i).organization_id
5723 	      AND INVENTORY_ITEM_ID =  x_consol_item_repl_tbl(i).item_id
5724 	      AND demand_type_id = l_demand_type_id
5725 	      AND DEMAND_LINE_DETAIL_ID = l_demand_line_detail_id
5726 	      AND demand_header_id = l_demand_header_id
5727 	      AND demand_line_id = l_demand_line_id;
5728 
5729 	 END IF;
5730 
5731       END LOOP; -- for each demand line
5732       CLOSE c_demand_lines_for_item;
5733 
5734       --At the end for Each item+Sub In PL/SQL table, update the final_replenishment_qty in Repl_UOM
5735       x_consol_item_repl_tbl(i).final_replenishment_qty
5736 	:= (x_consol_item_repl_tbl(i).total_demand_qty - x_consol_item_repl_tbl(i).available_onhand_qty);
5737 
5738       --Note: the final replenishment qty will be upp by the p_Repl_Lot_Size in Create_repl_Move_order() API
5739       <<next_onhd_consol_rec>>
5740 	IF l_return_status <> fnd_api.g_ret_sts_success then
5741 	   l_return_status := fnd_api.g_ret_sts_success;
5742 	   ROLLBACK TO onhd_consol_rec_sp;
5743 	   -- if repl_type 2 and demand_type_id <> 4 then revert that WDD to original status
5744 	   -- remove all entries for that item from gtmp
5745 	   -- both done in following API
5746 	   Revert_Consol_item_changes
5747 	     ( p_repl_type         => p_repl_type
5748 	       , p_demand_type_id  => l_demand_type_id
5749 	       , P_item_id         => x_consol_item_repl_tbl(i).item_ID
5750 	       , p_org_id          => x_consol_item_repl_tbl(i).ORGANIZATION_ID
5751 	       , x_return_status   => l_return_status
5752 	       );
5753 
5754 	   -- Remove element from consol table, can not do inside this loop
5755 	   -- AS iterating through the same consol record
5756 	   -- store the index of the consol table to be deleted outside the loop
5757 	   l_del_index := l_del_index +1;
5758 	   l_del_consol_item_tb(l_del_index) := i;
5759 
5760 	END IF;
5761 
5762 
5763       END IF; --IF  not x_consol_item_repl_tbl.exists(i)
5764 
5765    END LOOP; -- main loop on pl/sql table
5766    END IF;
5767 
5768   --REMOVE CONSOL RECORDS THAT HAS BEEN REMOVED FROM MOVER ORDER CREATION
5769    -- THIS WILL KEEP DATA IN SYNC
5770    FOR j IN 1..l_del_consol_item_tb.COUNT() LOOP
5771       x_consol_item_repl_tbl.DELETE(l_del_consol_item_tb(j));
5772    END LOOP;
5773 
5774 
5775    IF (l_debug = 1 ) THEN
5776       print_debug('DONE WITH GET_AVAILABLE_ONHAND_QTY API');
5777    END IF;
5778    x_return_status := fnd_api.g_ret_sts_success;
5779 EXCEPTION
5780    WHEN OTHERS THEN
5781       IF c_demand_lines_for_item%ISOPEN THEN
5782 	 CLOSE c_demand_lines_for_item;
5783       END IF;
5784       IF (l_debug = 1) THEN
5785 	 print_debug('Error in GET_AVAILABLE_ONHAND_QTY SQLCODE:'||SQLCODE ||' '||SQLERRM );
5786       END IF;
5787       x_return_status := fnd_api.g_ret_sts_error;
5788 END GET_AVAILABLE_ONHAND_QTY;
5789 
5790 
5791 
5792 
5793 PROCEDURE CREATE_RSV(p_replenishment_type    IN NUMBER, --  1- Stock Up/Push; 2- Dynamic
5794 		     l_debug                 IN NUMBER,
5795 		     l_organization_id       IN NUMBER,
5796 		     l_inventory_item_id     IN NUMBER,
5797 		     l_demand_type_id        IN NUMBER,
5798 		     l_demand_so_header_id   IN NUMBER,
5799 		     l_demand_line_id        IN NUMBER,
5800 		     l_split_wdd_id          IN NUMBER,
5801 		     l_primary_uom_code      IN VARCHAR2,
5802 		     l_supply_uom_code       IN VARCHAR2,
5803 		     l_atd_qty               IN NUMBER,
5804 		     l_atd_prim_qty          IN NUMBER,
5805 		     l_supply_type_id        IN NUMBER,
5806 		     l_supply_header_id      IN NUMBER,
5807 		     l_supply_line_id        IN NUMBER,
5808 		     l_supply_line_detail_id IN NUMBER,
5809 		     l_supply_expected_time  IN DATE,
5810 		     l_demand_expected_time  IN DATE,
5811 		     l_subinventory_code     IN VARCHAR2 DEFAULT NULL,
5812 		     l_rsv_rec               IN OUT NOCOPY inv_reservation_global.mtl_reservation_rec_type,
5813 		     l_serial_number         IN OUT NOCOPY inv_reservation_global.serial_number_tbl_type,
5814   l_to_serial_number      IN OUT NOCOPY inv_reservation_global.serial_number_tbl_type,
5815   l_quantity_reserved     IN OUT NOCOPY NUMBER,
5816   l_quantity_reserved2    IN OUT NOCOPY NUMBER,
5817   l_rsv_id                IN OUT NOCOPY NUMBER,
5818   x_return_status         IN OUT NOCOPY VARCHAR2,
5819   x_msg_count             IN OUT NOCOPY NUMBER,
5820   x_msg_data              IN OUT NOCOPY VARCHAR2)
5821   IS
5822 
5823 
5824      l_progress VARCHAR2(10);
5825 
5826 BEGIN
5827 
5828    --
5829    -- Set the values for the reservation record to be created
5830    IF (l_debug = 1) THEN
5831       print_debug('Requirement Date: ' || l_demand_expected_time);
5832    END IF;
5833 
5834    l_rsv_rec.reservation_id          := NULL;
5835    l_rsv_rec.requirement_date        := l_demand_expected_time;
5836    l_rsv_rec.organization_id         := l_organization_id;
5837    l_rsv_rec.inventory_item_id       := l_inventory_item_id;
5838    l_rsv_rec.demand_source_name      := NULL;
5839    l_rsv_rec.demand_source_type_id   := l_demand_type_id;
5840    l_rsv_rec.demand_source_header_id := l_demand_so_header_id;
5841    -- here l_demand_so_header_id is inv_salesorder.get_salesorder_for_oeheader(wdd.source_header_id)
5842    l_rsv_rec.demand_source_line_id        := l_demand_line_id;
5843    l_rsv_rec.orig_demand_source_type_id   := l_demand_type_id;
5844    l_rsv_rec.orig_demand_source_header_id := l_demand_so_header_id;
5845    l_rsv_rec.orig_demand_source_line_id   := l_demand_line_id;
5846 
5847    -- For now supply is only from Inventory supply_source_type_id = 13
5848    l_rsv_rec.demand_source_line_detail      := l_split_wdd_id;
5849    l_rsv_rec.orig_demand_source_line_detail := l_split_wdd_id;
5850 
5851    l_rsv_rec.demand_source_delivery         := NULL;
5852    l_rsv_rec.primary_uom_code               := l_primary_uom_code;
5853    l_rsv_rec.primary_uom_id                 := NULL;
5854    l_rsv_rec.secondary_uom_code             := null;
5855    l_rsv_rec.secondary_uom_id               := NULL;
5856    l_rsv_rec.reservation_uom_code           := l_supply_uom_code;
5857    l_rsv_rec.reservation_uom_id             := NULL;
5858    l_rsv_rec.reservation_quantity           := l_atd_qty;
5859    l_rsv_rec.primary_reservation_quantity   := l_atd_prim_qty;
5860    l_rsv_rec.secondary_reservation_quantity := null;
5861    l_rsv_rec.detailed_quantity              := NULL;
5862    l_rsv_rec.secondary_detailed_quantity    := NULL;
5863    l_rsv_rec.autodetail_group_id            := NULL;
5864    l_rsv_rec.external_source_code           := 'REPL'; -- Mark the external source
5865    l_rsv_rec.external_source_line_id        := NULL;
5866    l_rsv_rec.supply_source_type_id          := l_supply_type_id;
5867    l_rsv_rec.orig_supply_source_type_id     := l_supply_type_id;
5868    l_rsv_rec.supply_source_name             := NULL;
5869 
5870    l_rsv_rec.supply_source_header_id        := l_supply_header_id;
5871    l_rsv_rec.supply_source_line_id          := l_supply_line_id;
5872    l_rsv_rec.supply_source_line_detail      := l_supply_line_detail_id;
5873    l_rsv_rec.orig_supply_source_header_id   := l_supply_header_id;
5874    l_rsv_rec.orig_supply_source_line_id     := l_supply_line_id;
5875    l_rsv_rec.orig_supply_source_line_detail := l_supply_line_detail_id;
5876 
5877    l_rsv_rec.revision           := NULL;
5878    l_rsv_rec.subinventory_code  := l_subinventory_code;
5879    l_rsv_rec.subinventory_id    := NULL;
5880    l_rsv_rec.locator_id         := NULL;
5881    l_rsv_rec.lot_number         := NULL;
5882    l_rsv_rec.lot_number_id      := NULL;
5883    l_rsv_rec.pick_slip_number   := NULL;
5884    l_rsv_rec.lpn_id             := NULL;
5885    l_rsv_rec.attribute_category := NULL;
5886    l_rsv_rec.attribute1         := NULL;
5887    l_rsv_rec.attribute2         := NULL;
5888    l_rsv_rec.attribute3         := NULL;
5889    l_rsv_rec.attribute4         := NULL;
5890    l_rsv_rec.attribute5         := NULL;
5891    l_rsv_rec.attribute6         := NULL;
5892    l_rsv_rec.attribute7         := NULL;
5893    l_rsv_rec.attribute8         := NULL;
5894    l_rsv_rec.attribute9         := NULL;
5895    l_rsv_rec.attribute10        := NULL;
5896    l_rsv_rec.attribute11        := NULL;
5897    l_rsv_rec.attribute12        := NULL;
5898    l_rsv_rec.attribute13        := NULL;
5899    l_rsv_rec.attribute14        := NULL;
5900    l_rsv_rec.attribute15        := NULL;
5901    l_rsv_rec.ship_ready_flag    := NULL;
5902    l_rsv_rec.staged_flag        := NULL;
5903 
5904    l_rsv_rec.crossdock_flag        := NULL;
5905    l_rsv_rec.crossdock_criteria_id := NULL;
5906 
5907    l_rsv_rec.serial_reservation_quantity := NULL;
5908    l_rsv_rec.supply_receipt_date         := l_supply_expected_time;
5909    l_rsv_rec.demand_ship_date            := l_demand_expected_time;
5910    l_rsv_rec.project_id                  := NULL;
5911    l_rsv_rec.task_id                     := NULL;
5912    l_rsv_rec.serial_number               := NULL;
5913 
5914    IF (l_debug = 1) THEN
5915       print_debug('Call the create_reservation API to create the replenishemnt reservation');
5916    END IF;
5917 
5918    INV_RESERVATION_PVT.create_reservation(p_api_version_number          => 1.0,
5919 					  p_init_msg_lst                => fnd_api.g_false,
5920 					  x_return_status               => x_return_status,
5921 					  x_msg_count                   => x_msg_count,
5922 					  x_msg_data                    => x_msg_data,
5923 					  p_rsv_rec                     => l_rsv_rec,
5924 					  p_serial_number               => l_serial_number,
5925 					  x_serial_number               => l_to_serial_number,
5926 					  p_partial_reservation_flag    => fnd_api.g_false,
5927 					  p_force_reservation_flag      => fnd_api.g_false,
5928 					  p_validation_flag             => fnd_api.g_true,
5929 					  x_quantity_reserved           => l_quantity_reserved,
5930 					  x_secondary_quantity_reserved => l_quantity_reserved2,
5931 					  x_reservation_id              => l_rsv_id);
5932 
5933    IF (x_return_status <> FND_API.G_RET_STS_SUCCESS) THEN
5934       IF (l_debug = 1) THEN
5935 
5936 	 print_debug('Error returned from INV create_reservation API: ' ||
5937 		     x_return_status);
5938       END IF;
5939       -- Raise an exception.  The caller will do the rollback, cleanups,
5940       RAISE FND_API.G_EXC_ERROR;
5941 
5942    END IF;
5943 
5944    l_progress := '20';
5945 
5946 EXCEPTION
5947    WHEN OTHERS THEN
5948       x_return_status := fnd_api.g_ret_sts_error;
5949       fnd_msg_pub.count_and_get(p_count => x_msg_count,
5950                                 p_data  => x_msg_data);
5951       IF (l_debug = 1) THEN
5952 	 print_debug('Exiting Create_RSV - Execution error: ' || l_progress || ' ' ||
5953 		     TO_CHAR(SYSDATE, 'YYYY-MM-DD HH:DD:SS')|| ' ' ||x_msg_data);
5954       END IF;
5955 
5956 END Create_RSV;
5957 
5958 
5959 
5960 
5961 FUNCTION  Get_Expected_Time(p_demand_type_id in number,
5962 			    p_source_header_id in number,
5963 			    p_source_line_id          in number,
5964 			    p_delivery_line_id in number) RETURN DATE
5965   IS
5966 
5967 
5968 
5969      l_demand_expected_time DATE := null;
5970 
5971      l_debug number := NVL(FND_PROFILE.VALUE('INV_DEBUG_TRACE'),0);
5972 
5973 
5974      CURSOR wdd_rec_cursor IS
5975 	SELECT  NVL(wts.planned_departure_date,
5976 		    NVL(wdd.date_scheduled,
5977 			NVL(ool.schedule_ship_date, ool.promise_date))) AS expected_ship_date
5978 			  FROM wsh_delivery_details wdd, oe_order_lines_all ool,
5979 			  wsh_delivery_assignments_v wda, wsh_new_deliveries wnd, wsh_delivery_legs wdl,
5980 			  wsh_trip_stops wts, wsh_trips wt
5981 			  WHERE wdd.delivery_detail_id = p_delivery_line_id
5982 			  AND ool.line_id = p_source_line_id
5983 			  AND wdd.source_line_id = ool.line_id
5984 			  AND wdd.source_header_id = p_source_header_id
5985 			  AND wdd.delivery_detail_id = wda.delivery_detail_id (+)
5986 			  AND wda.delivery_id = wnd.delivery_id (+)
5987 			  AND wnd.delivery_id = wdl.delivery_id (+)
5988 			  AND (wdl.sequence_number IS NULL OR
5989 			       wdl.sequence_number = (SELECT MIN(sequence_number)
5990 						      FROM wsh_delivery_legs wdl_first_leg
5991 						      WHERE wdl_first_leg.delivery_id = wdl.delivery_id))
5992 			    AND wdl.pick_up_stop_id = wts.stop_id (+)
5993 			    AND wts.trip_id         = wt.trip_id  (+);
5994 
5995 BEGIN
5996 
5997    IF (p_demand_type_id NOT IN (2, 8)) THEN
5998       RETURN NULL;
5999    END IF;
6000 
6001    --     IF (l_debug = 1) THEN
6002    --       print_debug('===============================');
6003    --       print_debug('p_demand_type_id : ' ||p_demand_type_id);
6004    --       print_debug(' p_source_header_id : ' || p_source_header_id);
6005    --       print_debug('p_source_line_id : ' ||p_source_line_id  );
6006    --       print_debug('p_delivery_line_id : ' ||p_delivery_line_id);
6007    --       END IF;
6008 
6009 
6010    OPEN wdd_rec_cursor;
6011    FETCH wdd_rec_cursor INTO l_demand_expected_time;
6012    IF (wdd_rec_cursor%NOTFOUND) THEN
6013       IF (l_debug = 1) THEN
6014 	 print_debug('WDD cursor did not return any records!');
6015       END IF;
6016       l_demand_expected_time := NULL;
6017    END IF;
6018    CLOSE wdd_rec_cursor;
6019 
6020    IF l_debug = 1 THEN
6021       print_debug('******Returning Get_Expected_Time : '||l_demand_expected_time );
6022    END IF;
6023 
6024    RETURN l_demand_expected_time;
6025 
6026 EXCEPTION
6027    WHEN OTHERS THEN
6028       IF l_debug = 1 THEN
6029 	 print_debug('Get_Expected_Time: ' || sqlcode || ', ' || sqlerrm);
6030       END IF;
6031 END Get_Expected_Time;
6032 
6033 
6034 
6035 
6036 FUNCTION GET_SORT_TRIP_STOP_DATE(P_delivery_detail_id  IN NUMBER,
6037 				 P_TRIP_STOP_DATE_SORT IN VARCHAR2)
6038   RETURN NUMBER
6039   IS
6040 
6041      -- If the current delivery detail is a part of a trip that has multiple
6042      -- deliveries each HAVING its own planned_departure_date, THEN MIN needs to
6043      -- be selected
6044 
6045      CURSOR c_planned_departure_date IS
6046 	SELECT  MIN(NVL(wts.planned_departure_date, wdd.date_scheduled))
6047 	  --	    MIN(NVL(wts.planned_departure_date,
6048 	  --	    NVL(wdd.date_scheduled,
6049 	  --	    NVL(ool.schedule_ship_date, ool.promise_date)))) AS min_expected_ship_date,
6050 	  FROM wsh_new_deliveries wnd,  wsh_delivery_details wdd, wsh_delivery_assignments_v wda,
6051 	  wsh_delivery_legs wdl, wsh_trip_stops wts
6052 	  --	    oe_order_lines_all ool
6053 
6054 	  WHERE wdd.delivery_detail_id = p_delivery_detail_id
6055 	  --	    AND wdd.source_line_id = ool.line_id (+)
6056 	  AND wnd.shipment_direction = 'O'
6057 	  AND wnd.delivery_id = wda.delivery_id (+)
6058 	  AND wda.delivery_detail_id = wdd.delivery_detail_id (+)
6059 	  AND wnd.delivery_id = wdl.delivery_id (+)
6060 	  AND (wdl.sequence_number IS NULL OR
6061 	       wdl.sequence_number = (SELECT MIN(sequence_number)
6062 				      FROM wsh_delivery_legs wdl_first_leg
6063 				      WHERE wdl_first_leg.delivery_id = wdl.delivery_id))
6064 	    AND wdl.pick_up_stop_id = wts.stop_id (+)
6065 	    GROUP BY wnd.organization_id, wnd.delivery_id, wts.stop_id;
6066 
6067 
6068 	  l_planned_departure_date date;
6069 	  l_debug number := NVL(FND_PROFILE.VALUE('INV_DEBUG_TRACE'),0);
6070 
6071 BEGIN
6072 
6073    -- <<c_planned_departure_date(wdd.delivery_detail_id) will return planned trip date based on WTS.PLANNED_DEPARTURE_DATE if any exists>>
6074 
6075    --TEST: correst planned date is passed
6076    OPEN c_planned_departure_date;
6077    LOOP
6078       FETCH c_planned_departure_date INTO  l_planned_departure_date;
6079       EXIT WHEN c_planned_departure_date%NOTFOUND;
6080    END LOOP;
6081    CLOSE c_planned_departure_date;
6082 
6083    IF (l_debug = 1) THEN
6084       print_debug('get_planned_departure_date: '||l_planned_departure_date);
6085    END IF;
6086 
6087 
6088    IF l_planned_departure_date is NULL THEN
6089       RETURN NULL;
6090 
6091     ELSE
6092 
6093       IF P_TRIP_STOP_DATE_SORT = 'ASC' then
6094 	 RETURN (l_planned_departure_date - TO_DATE('01-01-1700 23:59:59', 'DD-MM-YYYY HH24:MI:SS'));
6095 
6096        ELSIF P_TRIP_STOP_DATE_SORT = 'DESC' then
6097 	 RETURN (TO_DATE('01-01-1700 23:59:59', 'DD-MM-YYYY HH24:MI:SS') - l_planned_departure_date);
6098 
6099        ELSE
6100 	 --means P_TRIP_STOP_DATE_SORT is NULL
6101 	 RETURN  NULL;
6102       END IF;
6103 
6104    END IF;
6105 
6106 EXCEPTION
6107    WHEN OTHERS THEN
6108       IF l_debug = 1 THEN
6109 	 print_debug('GET_SORT_TRIP_STOP_DATE: ' || sqlcode || ', ' || sqlerrm);
6110       END IF;
6111 END GET_SORT_TRIP_STOP_DATE;
6112 
6113 
6114 
6115 
6116 FUNCTION GET_SORT_INVOICE_VALUE(P_SOURCE_HEADER_ID NUMBER, P_INVOICE_VALUE_SORT VARCHAR2)
6117   RETURN NUMBER
6118   IS
6119      l_debug number := NVL(FND_PROFILE.VALUE('INV_DEBUG_TRACE'),0);
6120 BEGIN
6121 
6122 
6123    IF P_INVOICE_VALUE_SORT = 'ASC' THEN
6124       RETURN  WSH_PICK_CUSTOM.OUTSTANDING_ORDER_VALUE(p_SOURCE_HEADER_ID);
6125 
6126     ELSIF P_INVOICE_VALUE_SORT = 'DESC' THEN
6127       RETURN (-1 *  WSH_PICK_CUSTOM.OUTSTANDING_ORDER_VALUE(p_SOURCE_HEADER_ID));
6128 
6129     ELSE
6130       RETURN  NULL;
6131    END IF;
6132 
6133 
6134 EXCEPTION
6135    WHEN OTHERS THEN
6136       IF l_debug = 1 THEN
6137 	 print_debug('GET_SORT_INVOICE_VALUE: ' || sqlcode || ', ' || sqlerrm);
6138       END IF;
6139 
6140 END GET_SORT_INVOICE_VALUE;
6141 
6142 
6143 FUNCTION  get_available_capacity(p_quantity_function    IN NUMBER,
6144 				 p_organization_id      IN NUMBER,
6145 				 p_subinventory_code    IN VARCHAR2,
6146 				 p_locator_id           IN NUMBER,
6147 				 p_inventory_item_id    IN NUMBER,
6148 				 p_unit_volume          IN NUMBER,
6149 				 p_unit_volume_uom_code IN VARCHAR2,
6150 				 p_unit_weight          IN NUMBER,
6151 				 p_unit_weight_uom_code IN VARCHAR2,
6152 				 p_primary_uom          IN VARCHAR2,
6153 				 p_transaction_uom      IN VARCHAR2,
6154 				 p_base_uom             IN VARCHAR2,
6155 				 p_transaction_quantity IN NUMBER)
6156   RETURN NUMBER
6157 
6158   IS
6159      l_debug number := NVL(FND_PROFILE.VALUE('INV_DEBUG_TRACE'),0);
6160      l_possible_quantity NUMBER;
6161      l_sec_possible_quantity NUMBER;
6162 
6163 BEGIN
6164    IF (l_debug = 1) THEN
6165       print_debug('get_available_capacity - qty function code: ' || p_quantity_function);
6166    END IF;
6167 
6168 
6169    IF p_quantity_function is NOT NULL THEN
6170       IF p_quantity_function = 530003 THEN
6171 	 l_possible_quantity  :=
6172 	   wms_parameter_pvt.getavailableunitcapacity
6173 	   (
6174 	    p_organization_id            => p_organization_id
6175 	    , p_subinventory_code          => p_subinventory_code
6176 	    , p_locator_id                 => p_locator_id
6177 	    );
6178        ELSIF p_quantity_function = 530007 THEN
6179 	 l_possible_quantity  :=
6180 	   wms_parameter_pvt.getavailablevolumecapacity
6181 	   (
6182 	    p_organization_id            => p_organization_id
6183 	    , p_subinventory_code          => p_subinventory_code
6184 	    , p_locator_id                 => p_locator_id
6185 	    , p_inventory_item_id          => p_inventory_item_id
6186 	    , p_unit_volume                => p_unit_volume
6187 	    , p_unit_volume_uom_code       => p_unit_volume_uom_code
6188 	    , p_primary_uom                => p_primary_uom
6189 	    , p_transaction_uom            => p_transaction_uom
6190 	    , p_base_uom                   => p_base_uom
6191 	    );
6192        ELSIF p_quantity_function = 530011 THEN
6193 	 l_possible_quantity  :=
6194 	   wms_parameter_pvt.getavailableweightcapacity
6195 	   (
6196 	    p_organization_id            => p_organization_id
6197 	    , p_subinventory_code          => p_subinventory_code
6198 	    , p_locator_id                 => p_locator_id
6199 	    , p_inventory_item_id          => p_inventory_item_id
6200 	    , p_unit_weight                => p_unit_weight
6201 	    , p_unit_weight_uom_code       => p_unit_weight_uom_code
6202 	    , p_primary_uom                => p_primary_uom
6203 	    , p_transaction_uom            => p_transaction_uom
6204 	    , p_base_uom                   => p_base_uom
6205 	    );
6206        ELSIF p_quantity_function = 530015 THEN
6207 	 l_possible_quantity  :=
6208 	   wms_parameter_pvt.getminimumavailablevwcapacity
6209 	   (
6210 	    p_organization_id            => p_organization_id
6211 	    , p_subinventory_code          => p_subinventory_code
6212 	    , p_locator_id                 => p_locator_id
6213 	    , p_inventory_item_id          => p_inventory_item_id
6214 	    , p_unit_volume                => p_unit_volume
6215 	    , p_unit_volume_uom_code       => p_unit_volume_uom_code
6216 	    , p_unit_weight                => p_unit_weight
6217 	    , p_unit_weight_uom_code       => p_unit_weight_uom_code
6218 	    , p_primary_uom                => p_primary_uom
6219 	    , p_transaction_uom            => p_transaction_uom
6220 	    , p_base_uom                   => p_base_uom
6221 	    );
6222        ELSIF p_quantity_function = 530019 THEN
6223 	 l_possible_quantity  :=
6224 	   wms_parameter_pvt.getminimumavailableuvwcapacity
6225 	   (
6226 	    p_organization_id            => p_organization_id
6227 	    , p_subinventory_code          => p_subinventory_code
6228 	    , p_locator_id                 => p_locator_id
6229 	    , p_inventory_item_id          => p_inventory_item_id
6230 	    , p_unit_volume                => p_unit_volume
6231 	    , p_unit_volume_uom_code       => p_unit_volume_uom_code
6232 	    , p_unit_weight                => p_unit_weight
6233 	    , p_unit_weight_uom_code       => p_unit_weight_uom_code
6234 	    , p_primary_uom                => p_primary_uom
6235 	    , p_transaction_uom            => p_transaction_uom
6236 	    , p_base_uom                   => p_base_uom
6237 	    );
6238        ELSIF p_quantity_function = 530023 THEN
6239 	 l_possible_quantity  :=
6240 	   wms_re_custom_pub.getavailablelocationcapacity
6241 	   (
6242 	    p_organization_id            => p_organization_id
6243 	    , p_subinventory_code          => p_subinventory_code
6244 	    , p_locator_id                       =>    p_locator_id
6245 	    , p_inventory_item_id          => p_inventory_item_id
6246 	    , p_transaction_quantity       => p_transaction_quantity
6247 	    , p_transaction_uom            =>  p_transaction_uom
6248 	    );
6249        ELSE
6250 	 l_possible_quantity  := 0;
6251 	 IF (l_debug = 1) THEN
6252 	    print_debug('bad_qtyF - Invalid Quantity Function');
6253 	 END IF;
6254       END IF;
6255 
6256     ELSE -- means p_quantity_function is null
6257       -- capacity should not be considered
6258       l_possible_quantity := 1e125;
6259       l_sec_possible_quantity := 1e125;
6260    END IF;
6261 
6262    IF l_debug = 1 THEN
6263       print_debug('Avail. capacity: ' || l_possible_quantity);
6264 
6265    END IF;
6266 
6267    RETURN l_possible_quantity ;
6268 
6269 EXCEPTION
6270    WHEN OTHERS THEN
6271       IF l_debug = 1 THEN
6272 	 print_debug('Exception in Get_Available_Capacity: ' || sqlcode || ', ' || sqlerrm);
6273       END IF;
6274 
6275 END Get_Available_Capacity;
6276 
6277 
6278 
6279 
6280 PROCEDURE Get_to_Sub_For_Dynamic_Repl(P_Org_id               IN NUMBER,
6281 				      P_Item_id              IN NUMBER,
6282 				      P_PRIMARY_DEMAND_QTY   IN NUMBER,
6283 				      X_TO_SUBINVENTORY_CODE IN OUT NOCOPY VARCHAR2,
6284 				      X_REPL_UOM_CODE        OUT NOCOPY VARCHAR2)
6285   IS
6286      CURSOR c_destination_sub IS
6287 	SELECT SECONDARY_INVENTORY, PICK_UOM_CODE
6288 	  FROM (select MISI.SECONDARY_INVENTORY,
6289 		MSI.PICK_UOM_CODE,
6290 		MSIB.PRIMARY_UOM_CODE,
6291 		get_conversion_rate(MISI.INVENTORY_ITEM_id,
6292 				    MSI.PICK_UOM_CODE,
6293 				    MSIB.PRIMARY_UOM_CODE) AS CONVERSION_RATE
6294 		from MTL_ITEM_SUB_INVENTORIES  MISI,
6295 		MTL_SECONDARY_INVENTORIES MSI,
6296 		MTL_SYSTEM_ITEMS_B        MSIB
6297 		WHERE MISI.organization_id = P_Org_id
6298 		and MISI.INVENTORY_ITEM_ID = P_Item_id
6299 		AND MISI.SECONDARY_INVENTORY = MSI.SECONDARY_INVENTORY_NAME
6300 		AND MISI.ORGANIZATION_ID = MSI.ORGANIZATION_ID
6301 		AND MSI.PICK_UOM_CODE IS NOT NULL
6302 		--AND MOD(P_PRIMARY_DEMAND_QTY,(get_conversion_rate(MISI.INVENTORY_ITEM_id,MSI.PICK_UOM_CODE,MSIB.PRIMARY_UOM_CODE)))=0
6303         AND P_PRIMARY_DEMAND_QTY/get_conversion_rate(MISI.INVENTORY_ITEM_id,MSI.PICK_UOM_CODE,MSIB.PRIMARY_UOM_CODE) >= 1 --13419401
6304         AND get_conversion_rate(MISI.INVENTORY_ITEM_id,
6305 					MSI.PICK_UOM_CODE,
6306 					MSIB.PRIMARY_UOM_CODE) > 0
6307 		AND MISI.INVENTORY_ITEM_id = MSIB.INVENTORY_ITEM_id
6308 		AND MISI.ORGANIZATION_ID = MSIB.ORGANIZATION_ID
6309 		ORDER BY CONVERSION_RATE DESC, MSI.PICKING_ORDER) X
6310 		  WHERE ROWNUM = 1;
6311 
6312 		l_debug number := NVL(FND_PROFILE.VALUE('INV_DEBUG_TRACE'),0);
6313 
6314 
6315 BEGIN
6316 
6317    IF (l_debug = 1) THEN
6318       print_debug('Inside Get_to_Sub_For_Dynamic_Repl: TO_SUB :' ||X_TO_SUBINVENTORY_CODE);
6319    END IF;
6320 
6321 
6322    IF x_to_subinventory_code IS NOT NULL THEN
6323       -- THIS SUB VALUE WAS SPECIFIED WHILE CREATING THE SO, JUST FIND THE UOM CODE
6324 
6325       SELECT PICK_UOM_CODE INTO  x_repl_uom_code
6326 	FROM  MTL_SECONDARY_INVENTORIES MSI
6327 	WHERE MSI.ORGANIZATION_ID = p_org_id
6328 	and secondary_inventory_name = x_to_subinventory_code;
6329 
6330 
6331     ELSE
6332       -- FIND THE TO_SUB BASED ON LOGIC BELOW
6333 
6334       -- 2.1- Get the item and find out possible destination-sub candidates
6335       --from the item-subinventory table (MTL_ITEM_SUB_INVENTORIES).
6336       --  Make sure that these subinventories have pick-uom defined as well.
6337 
6338       --2.2- Rank these subinventories in the decreasing order of pick-uom
6339       --conversion (with respect to primary UOM for the item) and 'Picking
6340       --  order defined for the sub (Note: it does not matter whether source subinventory is defined for these destination subs in the item-subinventory form)
6341 
6342       --2.3- Among all these destination Sub with pick-UOM, pick the one that has the replenishment_qty as a whole number multiple of conversion qty.
6343       --  (Example: Consider the hierarchy PALLET(PLT) > CASE(CS) > EACH(Ea);
6344       --  Conversion factors of PLT= 100Ea and CS = 10 Ea;
6345       --  If the repl_qty = 23; then chosen destination sub will be EACH
6346       --  If the repl_qty = 30; then chosen destination sub will be CASE
6347       --  If the repl_qty = 123; then chosen destination sub will be EACH
6348       --  If the repl_qty = 130; then chosen destination sub will be CASE
6349       --  If the repl_qty = 100; then chosen destination sub will be PALLET)
6350 
6351       --  Justification:  in 80% of the cases, qty need to be replenished for small orders from small pick uom areas. For all big orders they order in whole numbers only (like PLT or CS)
6352 
6353       -- Note: conversion rate is in from higher UOM to lower UOM
6354 
6355       OPEN c_destination_sub;
6356       LOOP
6357 	 FETCH c_destination_sub
6358 	   INTO X_TO_SUBINVENTORY_CODE, X_REPL_UOM_CODE;
6359 	 EXIT WHEN c_destination_sub%NOTFOUND;
6360       END LOOP;
6361       CLOSE c_destination_sub;
6362 
6363       -- Value of X_TO_SUBINVENTORY_CODE and  X_REPL_UOM_CODE is NULL menas
6364       -- Either no record for the item exist in the item-sub form
6365       -- OR Conversion UOM was not specified the identified sub and corresponding picking uom for the sub
6366       -- OR PICK_UOM_CODE was not specified for the sub that is specified in the item-sub form
6367 
6368    END IF; -- FOR  x_to_subinventory_code IS NOT NULL
6369 
6370 
6371    IF (l_debug = 1) THEN
6372 
6373       print_debug( 'Dynamic Repl: X_TO_SUBINVENTORY_CODE :' || X_TO_SUBINVENTORY_CODE);
6374       print_debug( 'Dynamic Repl: X_REPL_UOM_CODE :'        || X_REPL_UOM_CODE);
6375 
6376    END IF;
6377 
6378 EXCEPTION
6379    WHEN OTHERS THEN
6380 
6381       IF c_destination_sub%ISOPEN THEN
6382 	 CLOSE c_destination_sub;
6383       END IF;
6384       IF l_debug = 1 THEN
6385 	 print_debug('Exception in Get_to_Sub_For_Dynamic_Repl: ' || sqlcode || ', ' || sqlerrm);
6386       END IF;
6387 
6388 END Get_to_Sub_For_Dynamic_Repl;
6389 
6390 
6391 
6392 PROCEDURE POPULATE_DYNAMIC_REPL_DEMAND(p_repl_level  IN NUMBER,
6393 				       p_org_id      IN NUMBER,
6394 				       P_Batch_id                 IN NUMBER,
6395 				       p_Release_Sequence_Rule_Id IN NUMBER,
6396 				       x_consol_item_repl_tbl     OUT NOCOPY CONSOL_ITEM_REPL_TBL,
6397 				       x_return_status            OUT NOCOPY VARCHAR2,
6398 				       x_msg_count                OUT NOCOPY NUMBER,
6399 				       x_msg_data                 OUT NOCOPY VARCHAR2)
6400   IS
6401 
6402      L_ORDER_ID_SORT           VARCHAR2(4) := NULL;
6403      L_INVOICE_VALUE_SORT      VARCHAR2(4) := NULL;
6404      L_SCHEDULE_DATE_SORT      VARCHAR2(4) := NULL;
6405      L_TRIP_STOP_DATE_SORT     VARCHAR2(4) := NULL;
6406      L_SHIPMENT_PRI_SORT       VARCHAR2(4) := NULL;
6407      l_debug              NUMBER      := NVL(fnd_profile.VALUE('INV_DEBUG_TRACE'), 0);
6408 
6409   CURSOR c_dynamic_repl_demand IS
6410      SELECT wdd.inventory_item_id as item_id,
6411        inv_salesorder.get_salesorder_for_oeheader(wdd.source_header_id) AS header_id,
6412        wdd.source_line_id AS line_id,
6413        wdd.delivery_detail_id,
6414        decode(wdd.source_document_type_id, 10, 8, 2) as demand_type_id, -- for SO=2 and Internal Order=8
6415        wdd.requested_quantity, -- this is always stored in primary UOM
6416 	 wdd.requested_quantity_uom,
6417 	 NVL(WMS_REPLENISHMENT_PVT.Get_Expected_Time(decode(wdd.source_document_type_id, 10, 8, 2),
6418 						 wdd.source_header_id,
6419 						 wdd.source_line_id,
6420 						 wdd.delivery_detail_id),
6421 	 WDD.date_scheduled) as expected_ship_date,
6422 	   wdd.subinventory,
6423 	   wdd.replenishment_status,
6424 	   wdd.released_status,
6425 	   -- get for sort_attribute1
6426             To_number(DECODE(p_Release_Sequence_Rule_Id,
6427                   null,
6428                   null,
6429                   DECODE(g_ordered_psr(1).attribute_name,
6430                          'ORDER_NUMBER',
6431                          DECODE(L_ORDER_ID_SORT,
6432                                 'ASC',
6433                                 To_number(wdd.source_header_number),
6434                                 'DESC',
6435                                 (-1 * To_number(wdd.SOURCE_HEADER_NUMBER)),
6436                                 null),
6437                          'SHIPMENT_PRIORITY',
6438 			 DECODE(WDD.SHIPMENT_PRIORITY_CODE,
6439 				'High',
6440 				20,
6441 				'Standard',
6442 				10,
6443 			       NULL),
6444 			 'INVOICE_VALUE',
6445                          GET_SORT_INVOICE_VALUE(WDD.SOURCE_HEADER_ID,
6446                                                 L_INVOICE_VALUE_SORT),
6447                          'SCHEDULE_DATE',
6448                          DECODE(L_SCHEDULE_DATE_SORT,
6449                                 'ASC',
6450                                 (WDD.DATE_SCHEDULED -
6451                                 TO_DATE('01-01-1700 23:59:59',
6452                                          'DD-MM-YYYY HH24:MI:SS')),
6453                                 'DESC',
6454                                 (TO_DATE('01-01-1700 23:59:59',
6455                                          'DD-MM-YYYY HH24:MI:SS') -
6456                                 WDD.DATE_SCHEDULED),
6457                                 null),
6458                          'TRIP_STOP_DATE',
6459                          GET_SORT_TRIP_STOP_DATE(wdd.delivery_detail_id,
6460                                                  L_TRIP_STOP_DATE_SORT),
6461                          NULL))) as sort_attribute1,
6462 
6463            -- get for sort_attribute2
6464             To_number(DECODE(p_Release_Sequence_Rule_Id,
6465                   null,
6466                   null,
6467                   DECODE(g_ordered_psr(2).attribute_name,
6468                          'ORDER_NUMBER',
6469 			 DECODE(L_ORDER_ID_SORT,
6470                                 'ASC',
6471                                 To_number(wdd.source_header_number),
6472                                 'DESC',
6473                                 (-1 * To_number(wdd.SOURCE_HEADER_NUMBER)),
6474                                 null),
6475                          'SHIPMENT_PRIORITY',
6476 			 DECODE(WDD.SHIPMENT_PRIORITY_CODE,
6477 				'High',
6478 				20,
6479 				'Standard',
6480 				10,
6481 				NULL),
6482                          'INVOICE_VALUE',
6483                          GET_SORT_INVOICE_VALUE(WDD.SOURCE_HEADER_ID,
6484                                                 L_INVOICE_VALUE_SORT),
6485                          'SCHEDULE_DATE',
6486                          DECODE(L_SCHEDULE_DATE_SORT,
6487                                 'ASC',
6488                                 (WDD.DATE_SCHEDULED -
6489                                 TO_DATE('01-01-1700 23:59:59',
6490                                          'DD-MM-YYYY HH24:MI:SS')),
6491                                 'DESC',
6492                                 (TO_DATE('01-01-1700 23:59:59',
6493                                          'DD-MM-YYYY HH24:MI:SS') -
6494                                 WDD.DATE_SCHEDULED),
6495                                 null),
6496                          'TRIP_STOP_DATE',
6497                          GET_SORT_TRIP_STOP_DATE(wdd.delivery_detail_id,
6498                                                  L_TRIP_STOP_DATE_SORT),
6499                          NULL))) as sort_attribute2,
6500 
6501            -- get for sort_attribute3
6502             To_number(DECODE(p_Release_Sequence_Rule_Id,
6503                   null,
6504                   null,
6505                   DECODE(g_ordered_psr(3).attribute_name,
6506                          'ORDER_NUMBER',
6507 			 DECODE(L_ORDER_ID_SORT,
6508                                 'ASC',
6509                                 To_number(wdd.source_header_number),
6510                                 'DESC',
6511                                 (-1 * To_number(wdd.SOURCE_HEADER_NUMBER)),
6512                                 null),
6513                          'SHIPMENT_PRIORITY',
6514 			 DECODE(WDD.SHIPMENT_PRIORITY_CODE,
6515 				'High',
6516 				20,
6517 				'Standard',
6518 				10,
6519 				NULL),
6520                          'INVOICE_VALUE',
6521                          GET_SORT_INVOICE_VALUE(WDD.SOURCE_HEADER_ID,
6522                                                 L_INVOICE_VALUE_SORT),
6523                          'SCHEDULE_DATE',
6524                          DECODE(L_SCHEDULE_DATE_SORT,
6525                                 'ASC',
6526                                 (WDD.DATE_SCHEDULED -
6527                                 TO_DATE('01-01-1700 23:59:59',
6528                                          'DD-MM-YYYY HH24:MI:SS')),
6529                                 'DESC',
6530                                 (TO_DATE('01-01-1700 23:59:59',
6531                                          'DD-MM-YYYY HH24:MI:SS') -
6532                                 WDD.DATE_SCHEDULED),
6533                                 null),
6534                          'TRIP_STOP_DATE',
6535                          GET_SORT_TRIP_STOP_DATE(wdd.delivery_detail_id,
6536                                                  L_TRIP_STOP_DATE_SORT),
6537                          NULL))) as sort_attribute3,
6538 
6539            -- get for sort_attribute4
6540             To_number(DECODE(p_Release_Sequence_Rule_Id,
6541                   null,
6542                   null,
6543                   DECODE(g_ordered_psr(4).attribute_name,
6544                          'ORDER_NUMBER',
6545 			 DECODE(L_ORDER_ID_SORT,
6546                                 'ASC',
6547                                 To_number(wdd.source_header_number),
6548                                 'DESC',
6549                                 (-1 * To_number(wdd.SOURCE_HEADER_NUMBER)),
6550                                 null),
6551                          'SHIPMENT_PRIORITY',
6552 			 DECODE(WDD.SHIPMENT_PRIORITY_CODE,
6553 				'High',
6554 				20,
6555 				'Standard',
6556 				10,
6557 				NULL),
6558 			 'INVOICE_VALUE',
6559                          GET_SORT_INVOICE_VALUE(WDD.SOURCE_HEADER_ID,
6560                                                 L_INVOICE_VALUE_SORT),
6561                          'SCHEDULE_DATE',
6562                          DECODE(L_SCHEDULE_DATE_SORT,
6563                                 'ASC',
6564                                 (WDD.DATE_SCHEDULED -
6565                                 TO_DATE('01-01-1700 23:59:59',
6566                                          'DD-MM-YYYY HH24:MI:SS')),
6567                                 'DESC',
6568                                 (TO_DATE('01-01-1700 23:59:59',
6569                                          'DD-MM-YYYY HH24:MI:SS') -
6570                                 WDD.DATE_SCHEDULED),
6571                                 null),
6572                          'TRIP_STOP_DATE',
6573                          GET_SORT_TRIP_STOP_DATE(wdd.delivery_detail_id,
6574                                                  L_TRIP_STOP_DATE_SORT),
6575                          NULL))) as sort_attribute4,
6576 
6577            -- get for sort_attribute5
6578             To_number(DECODE(p_Release_Sequence_Rule_Id,
6579                   null,
6580                   null,
6581                   DECODE(g_ordered_psr(5).attribute_name,
6582                          'ORDER_NUMBER',
6583 			 DECODE(L_ORDER_ID_SORT,
6584                                 'ASC',
6585                                 To_number(wdd.source_header_number),
6586                                 'DESC',
6587                                 (-1 * To_number(wdd.SOURCE_HEADER_NUMBER)),
6588                                 null),
6589                          'SHIPMENT_PRIORITY',
6590 			 DECODE(WDD.SHIPMENT_PRIORITY_CODE,
6591 				'High',
6592 				20,
6593 				'Standard',
6594 				10,
6595 				NULL),
6596                          'INVOICE_VALUE',
6597                          GET_SORT_INVOICE_VALUE(WDD.SOURCE_HEADER_ID,
6598                                                 L_INVOICE_VALUE_SORT),
6599                          'SCHEDULE_DATE',
6600                          DECODE(L_SCHEDULE_DATE_SORT,
6601                                 'ASC',
6602                                 (WDD.DATE_SCHEDULED -
6603                                 TO_DATE('01-01-1700 23:59:59',
6604                                          'DD-MM-YYYY HH24:MI:SS')),
6605                                 'DESC',
6606                                 (TO_DATE('01-01-1700 23:59:59',
6607                                          'DD-MM-YYYY HH24:MI:SS') -
6608                                 WDD.DATE_SCHEDULED),
6609                                 null),
6610                          'TRIP_STOP_DATE',
6611                          GET_SORT_TRIP_STOP_DATE(wdd.delivery_detail_id,
6612                                                  L_TRIP_STOP_DATE_SORT),
6613                          NULL))) as sort_attribute5
6614 	FROM wsh_delivery_details wdd
6615 	WHERE wdd.source_code = 'OE'
6616 	 AND wdd.organization_id = p_org_id
6617 	 AND wdd.requested_quantity > 0
6618           -- excluding Replenishment Requested status
6619        AND wdd.released_status in ('R', 'B') and wdd.replenishment_status = 'R'
6620           -- there might not be reservation
6621        AND NOT EXISTS
6622      (select 1
6623               from mtl_reservations mr
6624              WHERE MR.DEMAND_SOURCE_LINE_ID = wdd.source_line_id
6625                and MR.DEMAND_SOURCE_HEADER_ID =
6626                    inv_salesorder.get_salesorder_for_oeheader(wdd.source_header_id)
6627                and MR.demand_source_type_id =
6628                    decode(wdd.source_document_type_id, 10, 8, 2)
6629                and MR.SUBINVENTORY_CODE IS NOT NULL  --locator is not needed
6630 	       and (nvl(mr.staged_flag,'N') = 'N' and nvl(mr.detailed_quantity,0) = 0))  --13398141 ; Exclude detailed RSV
6631        AND NOT EXISTS
6632      (select wrd.demand_line_detail_id
6633       from WMS_REPLENISHMENT_DETAILS wrd
6634       where wrd.demand_line_detail_id = wdd.delivery_detail_id
6635       and wrd.demand_line_id = wdd.source_line_id
6636       and wrd.organization_id = wdd.organization_id
6637       AND wrd.organization_id = p_org_id)
6638      AND wdd.batch_id = P_Batch_id
6639      ORDER BY sort_attribute1,
6640               sort_attribute2,
6641               sort_attribute3,
6642               sort_attribute4,
6643               sort_attribute5
6644        FOR UPDATE SKIP LOCKED;
6645 
6646 
6647 	       CURSOR c_item_repl_cur IS
6648 		  SELECT inventory_item_id,
6649 		    sum(quantity_in_repl_uom) as total_demand_qty,
6650 		      MIN(expected_ship_date) as date_required,
6651 			repl_to_subinventory_code,
6652 			repl_uom_code
6653 			FROM wms_repl_demand_gtmp
6654 			WHERE organization_id = p_org_id
6655 			GROUP BY inventory_item_id, repl_to_subinventory_code,repl_uom_code
6656 			ORDER BY inventory_item_id, repl_to_subinventory_code;
6657 
6658 
6659 		      l_repl_uom_code             VARCHAR2(3);
6660 		      L_quantity_in_repl_uom      NUMBER;
6661 		      l_conversion_rate           NUMBER;
6662 
6663 		      l_return_value BOOLEAN;
6664 		      l_atr_ORG NUMBER;
6665 
6666 		      l_detail_info_tab             WSH_INTERFACE_EXT_GRP.delivery_details_Attr_tbl_Type;
6667 		      l_in_rec                      WSH_INTERFACE_EXT_GRP.detailInRecType;
6668 		      l_out_rec                     WSH_INTERFACE_EXT_GRP.detailOutRecType;
6669 
6670 		      l_pr_sub VARCHAR2(10);
6671 
6672 		      -- BULK OPERATION: Table to store results from the open demand for replenishment
6673 		      l_item_id_tb num_tab;
6674 		      l_header_id_tb num_tab;
6675 		      l_line_id_tb num_tab;
6676 		      l_delivery_detail_id_tb num_tab;
6677 		      l_demand_type_id_tb num_tab;
6678 		      l_requested_quantity_tb num_tab;
6679 		      l_requested_quantity_uom_tb uom_tab;
6680 		      l_quantity_in_repl_uom_tb num_tab;
6681 		      l_expected_ship_date_tb date_tab;
6682 		      l_repl_status_tb char1_tab;
6683 		      l_released_status_tb char1_tab;
6684 		      l_attr1_tb num_tab;
6685 		      l_attr2_tb num_tab;
6686 		      l_attr3_tb num_tab;
6687 		      l_attr4_tb num_tab;
6688 		      l_attr5_tb num_tab;
6689 		      l_repl_to_sub_code_tb char_tab;
6690 		      l_repl_UOM_CODE_tb uom_tab;
6691 
6692 
6693 		      -- BULK OPERATION:  Table to store consolidate demand results for replenishment
6694 		      l_total_demand_qty_tb num_tab;
6695 		      l_date_required_tb date_tab;
6696 
6697 		      l_temp_cnt NUMBER; -- removei t
6698 
6699 		      l_return_status VARCHAR2(3) := fnd_api.g_ret_sts_success;
6700 		      l_revert_wdd BOOLEAN := FALSE;
6701 
6702 		      l_bkorder_cnt NUMBER;
6703 BEGIN
6704 
6705    x_return_status := l_return_status;
6706    SAVEPOINT populate_dyn_demand_sp;
6707    IF (l_debug = 1) THEN
6708       print_debug('Inside  POPULATE_DYNAMIC_REPL_DEMAND Procedure');
6709       print_debug('Release_Sequence_Rule_Id: '||p_Release_Sequence_Rule_Id);
6710    END IF;
6711 
6712 
6713    -- Get the Order By Clause based on Pick Release Rule
6714    --initialize gloabl variables
6715    -- delete old value
6716    g_ordered_psr.DELETE;
6717    init_rules(p_pick_seq_rule_id    =>  p_Release_Sequence_Rule_Id,
6718 	      x_order_id_sort       =>  l_ORDER_ID_SORT,
6719 	      x_INVOICE_VALUE_SORT  =>  l_INVOICE_VALUE_SORT,
6720 	      x_SCHEDULE_DATE_SORT  =>  l_SCHEDULE_DATE_SORT,
6721 	      x_trip_stop_date_sort =>  l_TRIP_STOP_DATE_SORT,
6722 	      x_SHIPMENT_PRI_SORT   =>  l_shipment_pri_sort,
6723 	      x_ordered_psr         =>  g_ordered_psr,
6724 	      x_api_status          =>  l_return_status );
6725 
6726 
6727    IF (l_debug = 1) THEN
6728       print_debug('Status after calling init_rules'||l_return_status);
6729    END IF;
6730    IF (l_return_status <> fnd_api.g_ret_sts_success) THEN
6731       GOTO end_populate;
6732    END IF;
6733 
6734 
6735    -- 1- Go through all the demand lines that are marked as Replenishement requested and insert them in the
6736    -- WMS_REPL_DEMAND_GTMP table
6737 
6738    -- USE BULK INSERT FROM CURSOR TO THE TABLE AND THEN UPDATE THE TABLE FOR
6739    -- l_repl_to_sub_code, l_repl_uom_code and l_quantity in repl_uom
6740 
6741    l_item_id_tb.DELETE;
6742    l_header_id_tb.DELETE;
6743    l_line_id_tb.DELETE;
6744    l_delivery_detail_id_tb.DELETE;
6745    l_demand_type_id_tb.DELETE;
6746    l_requested_quantity_tb.DELETE;
6747    l_requested_quantity_uom_tb.DELETE;
6748    l_expected_ship_date_tb.DELETE;
6749    l_repl_status_tb.DELETE;
6750    l_released_status_tb.DELETE;
6751    l_attr1_tb.DELETE;
6752    l_attr2_tb.DELETE;
6753    l_attr3_tb.DELETE;
6754    l_attr4_tb.DELETE;
6755    l_attr5_tb.DELETE;
6756    l_repl_to_sub_code_tb.DELETE;
6757    l_quantity_in_repl_uom_tb.DELETE;
6758    l_repl_uom_code_tb.DELETE;
6759 
6760    -- BULK Fetch all data from the demand cursor
6761    BEGIN
6762       OPEN c_dynamic_repl_demand;
6763       FETCH c_dynamic_repl_demand BULK COLLECT INTO
6764 	l_item_id_tb,l_header_id_tb, l_line_id_tb,
6765 	l_delivery_detail_id_tb,l_demand_type_id_tb,
6766 	l_requested_quantity_tb,l_requested_quantity_uom_tb,
6767 	l_expected_ship_date_tb,l_repl_to_sub_code_tb,l_repl_status_tb,	l_released_status_tb,
6768 	l_attr1_tb,l_attr2_tb,l_attr3_tb,l_attr4_tb,l_attr5_tb;
6769       CLOSE c_dynamic_repl_demand;
6770    EXCEPTION
6771       WHEN OTHERS THEN
6772 	 IF (l_debug = 1) THEN
6773 	    print_debug('Exception retrieving open repl demand records');
6774 	 END IF;
6775 	 l_return_status := fnd_api.g_ret_sts_error;
6776 	 GOTO end_populate;
6777    END;
6778 
6779    select pick_from_subinventory INTO l_PR_sub
6780      from wsh_picking_batches where batch_id = p_batch_id;
6781 
6782    IF (l_debug = 1) THEN
6783       print_debug('At this point total number of dd_ids considered  :' ||l_delivery_detail_id_tb.COUNT);
6784       print_debug('Subinventory specified at the time of pick release:'||l_PR_sub);
6785    END IF;
6786 
6787 
6788    -- Now process/calculate ALL records
6789    IF (l_delivery_detail_id_tb.count>0) THEN --bug#10185153
6790    FOR j IN l_delivery_detail_id_tb.FIRST..l_delivery_detail_id_tb.LAST LOOP
6791 
6792       l_revert_wdd := FALSE;
6793 
6794       -- Consider for replenishment
6795       -- Try to get the Destination sub for the to_be_created replenishemnt move order
6796 
6797       -- Subinventory specified at Pick release time should take priority
6798       -- subinvnetory specifeid while creating the SO.
6799       IF l_pr_sub IS NULL THEN
6800 	      l_pr_sub := l_repl_to_sub_code_tb(j);
6801       END IF;
6802 
6803       --Store values in l_repl_to_sub_code_tb and  l_repl_uom_code_tb table
6804       Get_to_Sub_For_Dynamic_Repl(P_Org_id               => p_org_id,
6805 				  P_Item_id              => l_Item_id_tb(j),
6806 				  P_PRIMARY_DEMAND_QTY   => l_requested_quantity_tb(j),
6807 				  X_TO_SUBINVENTORY_CODE => l_PR_sub,
6808 				  X_REPL_UOM_CODE        => l_repl_uom_code_tb(j));
6809 
6810 
6811       l_repl_to_sub_code_tb(j) :=l_pr_sub;
6812       l_pr_sub := NULL ;  --10633351.Null out variable for next iteration of LOOP
6813 
6814       IF l_repl_to_sub_code_tb(j) IS NOT NULL AND l_repl_uom_code_tb(j) IS NOT NULL THEN
6815 	 -- keep only those records which has to_sub_code
6816 
6817 	 l_conversion_rate := get_conversion_rate(l_Item_id_tb(j),
6818 						  l_requested_quantity_uom_tb(j),
6819 						  l_repl_uom_code_tb(j));
6820 
6821 
6822 	 IF (l_conversion_rate < 0) THEN
6823 
6824 	    IF (l_debug = 1) THEN
6825 	       print_debug('Error while obtaining conversion rate');
6826 	       print_debug('Skipping REPL for the delivery detail:'||l_delivery_detail_id_tb(j)  );
6827 	    END IF;
6828 	    -- this records should not be added to the WRDT:
6829 	    -- Must delete this records jth element from the bulk uploaded tables later
6830 	    l_revert_wdd := TRUE;
6831 	    GOTO next_wdd;
6832 
6833 	  ELSE
6834 
6835 	    -- Store values in l_quantity_in_repl_uom_tb table
6836 	    l_quantity_in_repl_uom_tb(j) := ROUND(l_conversion_rate *
6837 						  l_requested_quantity_tb(j));
6838 
6839 	 END IF;
6840 
6841        ELSE
6842 	 --TO_SUB_CODE could not be identified
6843 	 IF (l_debug = 1) THEN
6844 	    print_debug('TO_SUB_CODE could not be identified for delivery_detail');
6845 	    print_debug('Skipping REPL for the delivery detail:'||l_delivery_detail_id_tb(j)  );
6846 	 END IF;
6847 	 -- this records should not be added to the WRDT:
6848 	 -- Must delete this records jth element from the bulk uploaded tables later
6849 	 l_revert_wdd := TRUE;
6850 	 GOTO next_wdd;
6851 
6852       END IF; -- for l_repl_to_sub_code_tb(j) IS NOT NULL
6853 
6854       <<next_wdd>>
6855 	IF (l_revert_wdd) THEN
6856 	   l_revert_wdd := FALSE;
6857 	   -- We can not replenish this line
6858 	   -- Backorder this demand line - Add to the global variable to be
6859 	   -- called AT the END OF the dynamic repl process
6860 
6861 	   IF (l_debug = 1) THEN
6862 	      print_debug('Revert wdd' );
6863 	      print_debug('--Backorder this demand line, add to the global variable :'||l_delivery_detail_id_tb(j));
6864 	   END IF;
6865 
6866 	   l_bkorder_cnt := g_backorder_deliv_tab.COUNT() + 1;
6867 
6868 	   g_backorder_deliv_tab(l_bkorder_cnt):= l_delivery_detail_id_tb(j) ;
6869 	   g_backorder_qty_tab(l_bkorder_cnt) := l_requested_quantity_tb(j);
6870 	   -- since we are backordering entire qty parameters
6871 	   -- p_bo_qtys AND  p_req_qtys will have same value
6872 	   g_dummy_table(l_bkorder_cnt)       := 0;
6873 
6874 
6875 	   -- this records should not be added to the WRDT:
6876 	   -- Must delete this records jth element from the bulk uploaded tables later
6877 	   IF (l_debug = 1) THEN
6878 	      print_debug('Skipping REPL for the delivery detail:'||l_delivery_detail_id_tb(j)  );
6879 	   END IF;
6880 
6881 	   -- Note: these delete in pl/sql table do not reindex
6882 	   -- data. element deleted at J remains NULL. it works sort of
6883 	   -- key-value pair for id and values
6884 
6885 	   l_item_id_tb.DELETE(j);
6886 	   l_header_id_tb.DELETE(j);
6887 	   l_line_id_tb.DELETE(j);
6888 	   l_delivery_detail_id_tb.DELETE(j);
6889 	   l_demand_type_id_tb.DELETE(j);
6890 	   l_requested_quantity_tb.DELETE(j);
6891 	   l_requested_quantity_uom_tb.DELETE(j);
6892 	   l_expected_ship_date_tb.DELETE(j);
6893 	   l_repl_status_tb.DELETE(j);
6894 	   l_released_status_tb.DELETE(j);
6895 	   l_repl_to_sub_code_tb.DELETE(j);
6896 	   l_quantity_in_repl_uom_tb.DELETE(j);
6897 	   l_repl_uom_code_tb.DELETE(j);
6898 
6899 
6900 	   IF (l_return_status <> fnd_api.g_ret_sts_success) THEN
6901 	      -- if we are unable to revert a WDD, we should
6902 	      -- essentially revery everything back
6903 	      -- as if could not do anything in populating
6904 	      l_item_id_tb.DELETE;
6905 	      l_header_id_tb.DELETE;
6906 	      l_line_id_tb.DELETE;
6907 	      l_delivery_detail_id_tb.DELETE;
6908 	      l_demand_type_id_tb.DELETE;
6909 	      l_requested_quantity_tb.DELETE;
6910 	      l_requested_quantity_uom_tb.DELETE;
6911 	      l_expected_ship_date_tb.DELETE;
6912 	      l_repl_status_tb.DELETE;
6913 	      l_released_status_tb.DELETE;
6914 	      l_repl_to_sub_code_tb.DELETE;
6915 	      l_quantity_in_repl_uom_tb.DELETE;
6916 	      l_repl_uom_code_tb.DELETE;
6917 	      l_return_status := fnd_api.g_ret_sts_error;
6918 	      GOTO end_populate;
6919 	   END IF;
6920 	END IF; -- IF (l_revert_wdd) THEN
6921    END LOOP; -- FOR j IN 1..l_delivery_detail_id_tb.COUNT LOOP
6922    END IF;
6923 
6924 
6925    -- Bulk upload all eligible demand lines
6926    -- since some recprds from the l_delivery_detail_id_tb has been deleted,
6927    -- use 'INDICES OF' instead of table count
6928      FORALL k IN INDICES OF l_delivery_detail_id_tb
6929      INSERT INTO WMS_REPL_DEMAND_GTMP
6930      (Repl_Sequence_id,
6931       repl_level,
6932       Inventory_item_id,
6933       Organization_id,
6934       demand_header_id,
6935       demand_line_id,
6936       demand_line_detail_id,
6937       demand_type_id,
6938       quantity_in_repl_uom,
6939       REPL_UOM_code,
6940       Quantity,
6941       Uom_code,
6942       Expected_ship_date,
6943       Repl_To_Subinventory_code,
6944       filter_item_flag,
6945       repl_status,
6946       repl_type,
6947       RELEASED_STATUS)
6948      VALUES
6949      (WMS_REPL_DEMAND_GTMP_S.NEXTVAL,
6950       p_repl_level,
6951       l_item_id_tb(k),
6952       p_org_id,
6953       l_header_id_tb(k),
6954       l_line_id_tb(k),
6955       l_delivery_detail_id_tb(k),
6956       l_demand_type_id_tb(k),
6957       l_quantity_in_repl_uom_tb(k),
6958       l_repl_uom_code_tb(k),
6959       l_requested_quantity_tb(k),
6960       l_requested_quantity_uom_tb(k),
6961       l_expected_ship_date_tb(k),
6962       l_repl_to_sub_code_tb(k),
6963       NULL,
6964       l_repl_status_tb(k),
6965       2,  -- for dynamic replenishment
6966       l_released_status_tb(k));
6967 
6968    IF (l_debug = 1) THEN
6969       print_debug('DONE with storing all records in WRDT table');
6970       print_debug('Now Store consolidated date in the PL/SQL table');
6971    END IF;
6972 
6973 
6974    --=====================TEST CODE STARTS =======
6975    -- for debugging purpise only, entire code should be inside l_debug = 1
6976    IF (l_debug = 1) THEN
6977       SELECT COUNT(1) INTO  l_temp_cnt FROM wms_repl_demand_gtmp;
6978       print_debug('FINAL record count in gtmp :'||l_temp_cnt);
6979    END IF;
6980    --=====================TEST CODE ENDS =======
6981 
6982 
6983 
6984    -- 3- For replenishment MO creation, all demand line qty will be consolidated/grouped for Item_id and destiniation_sub
6985 
6986    -- Clear tables for bulk operation
6987    l_item_id_tb.DELETE;
6988    l_total_demand_qty_tb.DELETE;
6989    l_date_required_tb.DELETE;
6990    l_repl_to_sub_code_tb.DELETE;
6991    l_repl_uom_code_tb.DELETE;
6992 
6993    -- BULK COLLECT  THESE RECORDS
6994    BEGIN
6995       OPEN c_item_repl_cur;
6996       FETCH c_item_repl_cur BULK COLLECT INTO l_item_id_tb,
6997 	l_total_demand_qty_tb,
6998 	l_date_required_tb,l_repl_to_sub_code_tb,l_repl_uom_code_tb;
6999       CLOSE c_item_repl_cur;
7000    EXCEPTION
7001       WHEN OTHERS THEN
7002 	 IF (l_debug = 1) THEN
7003 	    print_debug('Exception retrieving item repl records for Dynamic');
7004 	 END IF;
7005 	 l_return_status := fnd_api.g_ret_sts_error;
7006 	 GOTO end_populate;
7007    END;
7008 
7009    --Clear consolidated table
7010    x_consol_item_repl_tbl.DELETE;
7011 
7012    FOR k IN 1 .. l_item_id_tb.COUNT LOOP
7013       x_consol_item_repl_tbl(k).Organization_id := p_org_id;
7014       x_consol_item_repl_tbl(k).Item_id := l_item_id_tb(k);
7015       x_consol_item_repl_tbl(k).total_demand_qty := l_total_demand_qty_tb(k);
7016       x_consol_item_repl_tbl(k).date_required := l_date_required_tb(k);
7017 
7018       x_consol_item_repl_tbl(k).available_onhand_qty := 0; --calculated later
7019       x_consol_item_repl_tbl(k).open_mo_qty := 0; --calculated later
7020       x_consol_item_repl_tbl(k).final_replenishment_qty := 0; --calculated later
7021 
7022       x_consol_item_repl_tbl(k).repl_to_subinventory_code := l_repl_to_sub_code_tb(k);
7023       x_consol_item_repl_tbl(k).repl_uom_code := l_repl_uom_code_tb(k);
7024    END LOOP;
7025 
7026    -- At this point, we do not know whether the demand could not be fulfilled becs of rules restrictions or
7027    -- material is not available in the entire organization
7028    -- Check the high level availability (atr) at the org level.and adjust  ALL qty accordingly for all items
7029 
7030    IF l_debug = 1 THEN
7031       print_debug('Number of consolidated demand records :'||x_consol_item_repl_tbl.COUNT());
7032    END IF;
7033 
7034 
7035    IF x_consol_item_repl_tbl.COUNT() <> 0 THEN
7036 
7037       ADJUST_ATR_FOR_ITEM  (p_repl_level             => p_repl_level
7038 			    , p_repl_type            => g_dynamic_repl
7039 			    , x_consol_item_repl_tbl => x_consol_item_repl_tbl
7040 			    , x_return_status        => l_return_status
7041 			    );
7042 
7043       IF l_debug = 1 THEN
7044 	 print_debug('Return Status after call to ADJUST_ATR_FOR_ITEM :'|| l_return_status);
7045       END IF;
7046 
7047       IF l_return_status <> FND_API.g_ret_sts_success THEN
7048 	 -- All error out
7049 	 GOTO end_populate;
7050       END IF;
7051    END IF;
7052 
7053 
7054    <<end_populate>>
7055      IF (l_return_status <> fnd_api.g_ret_sts_success) THEN
7056 	-- Raising excetion so that will call revert of WDD status for all WDDs
7057 	-- in the DYNAMIC_REPLENISHMENT api
7058 	RAISE fnd_api.g_exc_unexpected_error;
7059      END IF;
7060 
7061      x_return_status        := FND_API.G_RET_STS_SUCCESS;
7062      IF l_debug = 1 THEN
7063 	print_debug('DONE WITH API POPULATE_DYNAMIC_REPL_DEMAND');
7064      END IF;
7065 
7066 EXCEPTION
7067    WHEN OTHERS THEN
7068       IF l_debug = 1 THEN
7069 	 print_debug('Exception in POPULATE_DYNAMIC_REPL_DEMAND: ' || sqlcode || ', ' || sqlerrm);
7070       END IF;
7071       ROLLBACK TO populate_dyn_demand_sp;
7072       x_return_status := fnd_api.g_ret_sts_error;
7073       x_consol_item_repl_tbl.DELETE;
7074 END POPULATE_DYNAMIC_REPL_DEMAND;
7075 
7076 
7077 
7078 PROCEDURE allocate_repl_move_order(
7079 				   p_Quantity_function_id IN NUMBER,
7080 				   x_return_status             OUT NOCOPY VARCHAR2,
7081 				   x_msg_count                 OUT NOCOPY NUMBER,
7082 				   x_msg_data                  OUT nocopy VARCHAR2
7083 				   )
7084   IS
7085 
7086 
7087 
7088      l_debug              NUMBER      := NVL(fnd_profile.VALUE('INV_DEBUG_TRACE'), 0);
7089 
7090      L_LOC_ID NUMBER;
7091 
7092      l_prev_to_sub VARCHAR2(10);
7093      l_prev_item_id NUMBER;
7094 
7095 
7096      L_PICK_UOM_CODE VARCHAR2(3);
7097      L_FIXED_LOT_MULTIPLE NUMBER;
7098      L_UNIT_CONV_QTY NUMBER;
7099 
7100      l_rsv_tbl_tmp    inv_reservation_global.mtl_reservation_tbl_type;
7101      i NUMBER;
7102 
7103      L_CUR_SUB_HAS_CAPACITY BOOLEAN ;
7104      l_available_capacity NUMBER;
7105      l_base_uom_code VARCHAR2(3);
7106      l_return_status VARCHAR2(1);
7107      l_msg_count     NUMBER;
7108      l_msg_data      VARCHAR2(1000);
7109      l_trigger_allocation BOOLEAN := FALSE;
7110 
7111      l_quantity_detailed  NUMBER;
7112      l_quantity_detailed_conv  NUMBER;
7113      l_num_detail_recs NUMBER;
7114 
7115      l_prim_quantity_detailed NUMBER;
7116      l_mo_line_id NUMBER;
7117      l_task_id NUMBER;
7118 
7119      -- We are NOT doing this at the moment: For the available capacity at the destination sub there can be competing replenishment move order lines.
7120      --  Consume queued and competing repl MO lines in the order of priority of demand lines based on wrd.Demand_Sort_Order
7121      --  (Since Demand_Sort_Order will alredy give priority orders first
7122      --  within a release_batch.Since we want to give high priority to earlier pick releases,
7123      --  the wrd. WRD.Demand_Sort_Order  will take care of this as well as it gets value from a DB sequence.
7124 
7125      CURSOR c_open_repl_mo IS
7126 	select
7127 	  mtrl.organization_id,
7128 	  mtrl.INVENTORY_ITEM_ID,
7129 	  mtrl.FROM_SUBINVENTORY_CODE,
7130 	  mtrl.TO_SUBINVENTORY_CODE,
7131 	  mtrl.quantity mol_qty,
7132 	  Nvl(mtrl.quantity_detailed,0) mol_detailed_qty,
7133 	  Nvl(mtrl.quantity_delivered,0) mol_delivered_qty,
7134 	  mtrl.uom_code,
7135 	  mtrl.header_id,
7136 	  mtrl.line_id
7137 	  FROM mtl_txn_request_lines mtrl,
7138 	  Mtl_txn_request_headers mtrh
7139 	  WHERE  mtrl.header_id = mtrh.header_id
7140 	  And mtrl.organization_id = mtrh.organization_id
7141 	  and mtrl.organization_id in (select organization_id from mtl_parameters where wms_enabled_flag = 'Y')
7142 	  And MTRH.move_order_type = 2
7143 	  and mtrl.line_status in (3,7) -- only approved and pre-approved
7144 	  and (mtrl.quantity - (Nvl(mtrl.quantity_detailed,0) + Nvl(mtrl.quantity_delivered,0)))  > 0
7145 	  and mtrh.transaction_type_id = 64
7146 	  and mtrl.transaction_type_id = 64
7147 	  and mtrl.transaction_source_type_id = 4
7148 	  ORDER BY mtrl.organization_id, mtrl.TO_SUBINVENTORY_CODE, mtrl.line_id, mtrl.INVENTORY_ITEM_ID;
7149 
7150      -- Note we have mtrl.line_Id in the order_by clause to have some predictable consumption of move order behavior in
7151      -- case of conflicting priority among MO lines.
7152      --(Note: We could have put a better consumption order of repl move
7153      --order lines based on assigning the priority number as MIN[priority of associated demand lines].)
7154 
7155      --We need to order by mtrl.INVENTORY_ITEM_ID to process lines more efficiently below
7156 
7157      CURSOR c_locators_in_sub(P_ORGANIZATION_ID NUMBER, p_sub_code VARCHAR2) IS
7158 	SELECT INVENTORY_LOCATION_ID
7159 	  FROM MTL_ITEM_LOCATIONS
7160 	  WHERE SUBINVENTORY_CODE = P_SUB_CODE
7161 	  AND ORGANIZATION_ID = p_organization_id
7162 	  ORDER BY PICKING_ORDER;
7163 
7164      CURSOR c_trigger_parameters(P_ORG_ID NUMBER, p_item_id NUMBER, p_src_sub VARCHAR2, p_dest_sub VARCHAR2) IS
7165 	SELECT MSI.PICK_UOM_CODE, MISI.FIXED_LOT_MULTIPLE
7166 	  from MTL_ITEM_SUB_INVENTORIES  MISI,
7167 	  MTL_SECONDARY_INVENTORIES MSI
7168 	  where MISI.organization_id =  p_org_id
7169 	  AND MISI.SOURCE_SUBINVENTORY = MSI.SECONDARY_INVENTORY_NAME
7170 	  AND MISI.ORGANIZATION_ID = MSI.ORGANIZATION_ID
7171 	  AND nvl(MISI.SOURCE_SUBINVENTORY, '@@@') = NVL(p_src_sub , nvl(MISI.SOURCE_SUBINVENTORY,'@@@'))
7172 	  AND MISI.SECONDARY_INVENTORY = p_dest_sub
7173 	  AND MISI.INVENTORY_ITEM_ID   = p_Item_id
7174 	  and MISI.source_type = 3 --(for Subinventory)
7175 	  AND MISI.source_organization_id =  p_org_id;
7176 
7177      CURSOR c_base_uom(p_txn_uom_code VARCHAR2) IS
7178 	SELECT muom.uom_code
7179 	  FROM  mtl_units_of_measure_tl muom,mtl_units_of_measure_tl muom2
7180 	  WHERE muom2.uom_code = p_txn_uom_code
7181 	  AND muom2.language = userenv('LANG')
7182 	  AND muom.uom_class = muom2.uom_class
7183 	  AND muom.language = userenv('LANG')
7184 	  AND muom.base_uom_flag = 'Y';
7185 
7186 
7187     CURSOR c_mmtt_rec IS
7188       SELECT transaction_temp_id
7189         FROM mtl_material_transactions_temp
7190 	WHERE move_order_line_id = l_mo_line_id;
7191 
7192 BEGIN
7193 
7194    IF l_debug = 1 THEN
7195       print_debug('API allocate_repl_move_order -  quantity function id :'|| p_quantity_function_id) ;
7196    END IF;
7197 
7198    --It will keep looking at the locators of the destination subinventories of the queued replenishemt MO and see if any capacity becomes available.
7199 
7200    --If  there is 'Fixed Lot Multiple' value specified for the item-subinventory form for the destination sub,
7201    --then this value must be used in the decision making to trigger allocation. If the available capacity at
7202    --destination locator is more than single unit 'Fixed Lot Multiple' qty of the source subinventory on
7203    --the queued replenishment MO, then trigger the allocation process of the MO based on the priority of the
7204    --associated demand orders.
7205 
7206    --If  the 'Fixed Lot multiple' value is NOT specified on the item-subinventory form for the tiem and
7207    --destination sub, then see if the source subinventory is stamped on the item_sub Form.
7208    --Check if the 'Pick UOM' for the source sub is set in the subinventory Form. Get the unit qty conversion
7209    --of this pick uom to the primary qty (say l_src_uom_unit_qty).  If l_src_uom_unit_qty
7210    --is less than the available capacity of the destination sub, then trigger the allocation for the open repl MO.
7211 
7212    --Otherwise
7213    --IF
7214    --( 'Fixed Lot Multiple' value is NOT specified on the item-sub form)
7215    --AND (the source_sub is also NOT specified for the item+destination_sub  OR the pick_uom of the
7216    --source_sub is not defined on the source sub ) THEN
7217    --Trigger the allocation anyway.
7218    --END IF;
7219 
7220    -- Get all destination subinventories from the replenishment move
7221    --orders that have some qty to be replenished for demands.
7222 
7223 
7224    L_CUR_SUB_HAS_CAPACITY := TRUE;
7225 
7226    FOR l_open_repl_mo IN c_open_repl_mo LOOP
7227 
7228       IF l_debug = 1 THEN
7229 	 print_debug('Processing MO Line: '||l_open_repl_mo.line_id ||
7230 		     ' ,with destination sub: '||l_open_repl_mo.to_subinventory_code||
7231 		     ' ,FOR ITEM : '||l_open_repl_mo.inventory_item_id
7232 		     ) ;
7233       END IF;
7234 
7235       --IF l_available_capacity <= 0 for ALL locations in the current sub,
7236       --then skip ALL Open move orders in the batch that has destination of the current sub
7237 
7238       IF (NOT l_cur_sub_has_capacity) AND (l_prev_to_sub = l_open_repl_mo.to_subinventory_code) THEN
7239 	 -- Skip to the next open MO
7240 	 IF l_debug = 1 THEN
7241 	    print_debug('DEST SUB HAS NO CAPACITY : SKIPPING allocation of current MO') ;
7242 	 END IF;
7243 	 GOTO next_mo_line;
7244        ELSE
7245 
7246 	 -- Get the available capacity for EACH valid locator in  the l_open_repl_mo.TO_SUBINVENTORY_CODE
7247 	 -- Scan each locator in the sub for capacity
7248 	 L_CUR_SUB_HAS_CAPACITY := FALSE;
7249 
7250 	 -- Setting Item information in the Cache
7251 	 IF inv_cache.set_item_rec(l_open_repl_mo.organization_id, l_open_repl_mo.inventory_item_id)  THEN
7252 	    NULL;
7253 	    IF (l_debug = 1) THEN
7254 	       print_debug('Primary UOM for the Item:' ||inv_cache.item_rec.primary_uom_code);
7255 	    END IF;
7256 	 END IF;
7257 
7258 	 OPEN c_locators_in_sub(l_open_repl_mo.organization_id, l_open_repl_mo.TO_SUBINVENTORY_CODE);
7259 	 LOOP
7260 	    FETCH c_locators_in_sub INTO L_loc_id;
7261 
7262 	    IF l_debug = 1 THEN
7263 	       print_debug('*******Getting capacity for Next LOC :'||L_loc_id) ;
7264 	    END IF;
7265 
7266 	    EXIT WHEN c_locators_in_sub%NOTFOUND;
7267 
7268 	    IF p_quantity_function_id IS NULL THEN  -- not specified
7269 
7270 	       l_available_capacity := 1e125;
7271 
7272 	     ELSIF (p_quantity_function_ID = 530003) THEN  -- Unit Capacity Quantity Function
7273 
7274 	       -- Call capacity calculation function ONLY for each to_sub change
7275 	       IF (l_prev_to_sub IS NULL OR (l_prev_to_sub  <>  l_open_repl_mo.to_subinventory_code)) THEN
7276 		  IF l_debug = 1 THEN
7277 		     print_debug('CALLING Unit Capacity API FOR AVAILABLE CAPACITY') ;
7278 		  END IF;
7279 
7280 		  l_available_capacity := get_available_capacity
7281 		    (
7282 		     p_quantity_function   => p_Quantity_function_id
7283 		     , p_organization_id   => l_open_repl_mo.organization_id
7284 		     , p_subinventory_code => l_open_repl_mo.TO_SUBINVENTORY_CODE
7285 		     , p_locator_id             => l_loc_id
7286 		     , p_inventory_item_id    => NULL
7287 		     , p_unit_volume             => NULL
7288 		     , p_unit_volume_uom_code       => NULL
7289 		     , p_unit_weight              => NULL
7290 		     , p_unit_weight_uom_code       => NULL
7291 		     , p_primary_uom                => NULL
7292 		     , p_transaction_uom            => NULL
7293 		     , p_base_uom                   => NULL
7294 		     , p_transaction_quantity     => NULL        );
7295 	       END IF;
7296 
7297 	     ELSE  -- all other kind of quantity function
7298 
7299 	       -- Call capacity calculation function for EACH to_sub change OR item change
7300 
7301 	       IF (l_prev_to_sub IS NULL OR l_prev_to_sub  <>  l_open_repl_mo.TO_SUBINVENTORY_CODE OR
7302 		   l_prev_item_id IS NULL OR l_prev_item_id <> l_open_repl_mo.INVENTORY_ITEM_ID) THEN
7303 		  IF l_debug = 1 THEN
7304 		     print_debug('CALCULATING AVAILABLE CAPACITY WITH other APIs') ;
7305 		  END IF;
7306 
7307 		  OPEN c_base_uom(l_open_repl_mo.uom_code) ;
7308 		  FETCH c_base_uom INTO l_base_uom_code;
7309 		  IF c_base_uom%NOTFOUND THEN
7310 		     GOTO next_mo_line;
7311 		  END IF;
7312 		  CLOSE c_base_uom;
7313 
7314 		  l_available_capacity := get_available_capacity
7315 		    (
7316 		     p_quantity_function   => p_Quantity_function_id
7317 		     , p_organization_id   => l_open_repl_mo.organization_id
7318 		     , p_subinventory_code => l_open_repl_mo.TO_SUBINVENTORY_CODE
7319 		     , p_locator_id           => l_loc_id
7320 		     , p_inventory_item_id    => l_open_repl_mo.inventory_item_id
7321 		     , p_unit_volume          => inv_cache.item_rec.unit_volume
7322 		     , p_unit_volume_uom_code    =>inv_cache.item_rec.volume_uom_code
7323 		     , p_unit_weight             =>inv_cache.item_rec.unit_weight
7324 		     , p_unit_weight_uom_code    =>inv_cache.item_rec.weight_uom_code
7325 		     , p_primary_uom             =>inv_cache.item_rec.primary_uom_code
7326 		     , p_transaction_uom         => l_open_repl_mo.uom_code
7327 		     , p_base_uom                => l_base_uom_code
7328 		     , p_transaction_quantity    => (l_open_repl_mo.mol_qty - l_open_repl_mo.mol_detailed_qty -  l_open_repl_mo.mol_delivered_qty));
7329 
7330 		ELSE
7331 		  IF (l_debug = 1) THEN
7332 		     print_debug('No data Found and hence no capacity for the Item');
7333 		  END IF;
7334 
7335 		  GOTO next_mo_line;
7336 	       END IF; -- FOR l_prev_to_sub  <>  l_open_repl_mo.TO_SUBINVENTORY_CODE
7337 	    END IF; -- all other kind of quantity function
7338 
7339 	    --Note: CAPACITY changes after each allocation even if the material has not physically moved to the destination.
7340 
7341 	    --So we need to rely on the condition that once L_CUR_SUB_HAS_CAPACITY becomes FALSE for a location,
7342 	    --  there is no chance of it becoming true as the API get_available_capacity() will be
7343 	    --  returning the updated available capacity.
7344 
7345 	    IF (l_debug = 1) THEN
7346 	       print_debug('Capacity of current locator: '||l_available_capacity);
7347 	    END IF;
7348 
7349 	    IF l_available_capacity > 0 then
7350 	       L_CUR_SUB_HAS_CAPACITY := TRUE;
7351 	       -- DO NOT PUT the :  ELSE L_CUR_SUB_HAS_CAPACITY := FALSE;
7352 	    END IF;
7353 
7354 	    -- get the Picking UOM AND  'Fixed Lot Multiple' for l_open_repl_mo.FROM_SUBINVENTORY_CODE,
7355 	    OPEN c_trigger_parameters(l_open_repl_mo.organization_id,
7356 				      l_open_repl_mo.INVENTORY_ITEM_ID,
7357 				      l_open_repl_mo.FROM_SUBINVENTORY_CODE ,l_open_repl_mo.TO_SUBINVENTORY_CODE);
7358 	    LOOP
7359 	       FETCH c_trigger_parameters INTO L_PICK_UOM_CODE, L_FIXED_LOT_MULTIPLE;
7360 	       EXIT WHEN c_trigger_parameters%NOTFOUND;
7361 
7362 	       IF (l_debug = 1) THEN
7363 		  print_debug('Trigger parameter value l_fixed_lot_multiple: '||l_fixed_lot_multiple);
7364 		  print_debug('Trigger parameter value L_PICK_UOM_CODE: '||L_PICK_UOM_CODE);
7365 	       END IF;
7366 
7367 	       -- NOW DECIDE WHETHER TO TRIGGER ALLOCATION OR NOT
7368 	       -- l_available_capacity and l_fixed_lot_multiple are in primary UOM
7369 	       IF l_fixed_lot_multiple IS NOT NULL THEN
7370 		  IF (l_debug = 1) THEN
7371 		     print_debug('USING Fixed Lot Multiplier for decision making');
7372 		  END IF;
7373 		  IF l_available_capacity > 0 AND l_available_capacity >= l_fixed_lot_multiple THEN
7374 		     l_trigger_allocation := TRUE;
7375 		   ELSE
7376 		     l_trigger_allocation := FALSE;
7377 		  END IF;
7378 
7379 		ELSIF l_pick_uom_code IS NOT NULL THEN --see if the source sub pick UOM is valid
7380 		  IF (l_debug = 1) THEN
7381 		     print_debug('USING Src Sub Pick UOM Unit Qty for decision making');
7382 		  END IF;
7383 
7384 		  L_UNIT_CONV_QTY :=  ROUND(1* get_conversion_rate(l_open_repl_mo.inventory_item_id,
7385 								   l_pick_uom_code,
7386 								   inv_cache.item_rec.primary_uom_code),
7387 					    g_conversion_precision);
7388 
7389 		  IF (l_debug = 1) THEN
7390 		     print_debug(' L_UNIT_CONV_QTY:' ||L_UNIT_CONV_QTY);
7391 		  END IF;
7392 
7393 		  IF L_UNIT_CONV_QTY < 0 THEN
7394 		     IF (l_debug = 1) THEN
7395 			print_debug('Error while obtaining L_mo_uom_code conversion rate for demand qty');
7396 		     END IF;
7397 		     l_trigger_allocation := FALSE;
7398 		   ELSE
7399 		     IF l_available_capacity > 0 AND (l_available_capacity >= l_unit_conv_qty) THEN
7400 			l_trigger_allocation := TRUE;
7401 		      ELSE
7402 			l_trigger_allocation := FALSE;
7403 		     END IF;
7404 		  END IF;
7405 
7406 		ELSE --Trigger it anyway
7407 		  IF (l_debug = 1) THEN
7408 		     print_debug('Trigger allocation since fixed_lot_multiplier AND src sub unit qty NOT available');
7409 		  END IF;
7410 		  l_trigger_allocation := TRUE;
7411 
7412 		  -- in case the 'effective qty' that need to be allocated ON MO
7413 		  -- IS more than the available capacity at the destination
7414 		  -- rule engine will allocate whatever it could
7415 		  -- effective qty = (mtrl.quantity - (Nvl(mtrl.quantity_detailed,0) + Nvl(mtrl.quantity_delivered,0)))
7416 	       END IF;  --for l_fixed_lot_multiple IS NOT null
7417 
7418 
7419 	       -- Now actually allocate the MO
7420 	       IF (NOT l_trigger_allocation) THEN
7421 		  --Do nothing, get to the next mo line to allocate
7422 		  IF (l_debug = 1) THEN
7423 		     print_debug('Could not meet capacity Criteria in current Sub/Loc');
7424 		     print_debug('Skip to next Loc in the Sub OR Next repl MO Line......');
7425 		  END IF;
7426 		  GOTO next_loc_in_sub;
7427 
7428 		ELSE -- allocate the replenishment move order
7429 		  -- Call Allocation API
7430 		  IF (l_debug = 1) THEN
7431 		     print_debug('Available capacity is enough to trigger allocation....');
7432 		  END IF;
7433 
7434 		  WMS_Engine_PVT.create_suggestions(
7435 						    p_api_version => 1.0,
7436 						    p_init_msg_list => fnd_api.g_false,
7437 						    p_commit => fnd_api.g_false,
7438 						    p_validation_level => fnd_api.g_valid_level_none,
7439 						    x_return_status => l_return_status,
7440 						    x_msg_count => l_msg_count,
7441 						    x_msg_data => l_msg_data,
7442 						    p_transaction_temp_id => l_open_repl_mo.line_id,
7443 						    p_reservations => l_rsv_tbl_tmp, --NULL value  AS no rsv FOR repl MO
7444 						    p_suggest_serial => fnd_api.g_false,
7445 						    p_plan_tasks => FALSE);
7446 
7447 
7448 		  IF (l_return_status <> FND_API.G_RET_STS_SUCCESS) THEN
7449 		     IF (l_debug = 1) THEN
7450 			print_debug('Error returned from create_suggestions API: '
7451 				    || l_return_status);
7452 		     END IF;
7453 
7454 		     -- If an exception occurs while modifying a database record, rollback the changes
7455 		     -- and raise exception. Should we proceed to next record
7456 		     ROLLBACK TO Current_MOL_SP;
7457 		     RAISE fnd_api.g_exc_error;
7458 		   ELSE
7459 
7460 		     IF (l_debug = 1) THEN
7461 			print_debug('Success returned from create_suggestions API');
7462 			print_debug('Now Assign Task Type for all Repl tasks created FOR the MO Line');
7463 		     END IF;
7464 		     l_mo_line_id:=l_open_repl_mo.line_id;
7465 
7466 		     OPEN c_mmtt_rec;
7467 		     LOOP
7468 			FETCH c_mmtt_rec INTO l_task_id;
7469 			EXIT WHEN c_mmtt_rec%notfound;
7470 
7471 			IF (l_debug = 1) THEN
7472 			   print_debug('Assign Task Type for MMTT_id: '||l_task_id);
7473 			END IF;
7474 
7475 			wms_rule_pvt.assigntt(
7476 					      p_api_version                => 1.0
7477 					      , p_task_id                    => l_task_id
7478 					      , x_return_status              => l_return_status
7479 					      , x_msg_count                  => x_msg_count
7480 					      , x_msg_data                   => x_msg_data
7481 					      );
7482 
7483 		     END LOOP;
7484 		     CLOSE c_mmtt_rec;
7485 
7486 		  END IF;
7487 
7488 		  --update the MO line quantity_detailed field or close the MO
7489                   BEGIN
7490 		     SELECT NVL(SUM(primary_quantity), 0)
7491 		       ,NVL(sum(transaction_quantity),0)
7492 		       ,COUNT(*)
7493 		       INTO l_prim_quantity_detailed
7494 		       ,l_quantity_detailed_conv
7495 		       ,l_num_detail_recs
7496 		       FROM mtl_material_transactions_temp
7497 		       WHERE move_order_line_id = l_open_repl_mo.line_id;
7498 
7499 		     IF (l_debug = 1) THEN
7500 			print_debug('primary l_quantity detailed is '|| l_prim_quantity_detailed);
7501 			print_debug('l_num_detail_recs is '|| l_num_detail_recs);
7502 		     END IF;
7503 		  EXCEPTION
7504 		     WHEN NO_DATA_FOUND THEN
7505 			IF (l_debug = 1) THEN
7506 			   print_debug('no detail records found');
7507 			END IF;
7508 			l_quantity_detailed  := 0;
7509 			l_quantity_detailed_conv  := 0;
7510 			l_num_detail_recs := 0;
7511 		  END;
7512 
7513 
7514 		  --Convert the MOL detailed qty into MOL UOM code qty
7515 		  IF inv_cache.item_rec.primary_uom_code <> l_open_repl_mo.uom_code THEN
7516 
7517 		     l_quantity_detailed :=
7518 		       ROUND((l_prim_quantity_detailed* get_conversion_rate(l_open_repl_mo.inventory_item_id,
7519 									    inv_cache.item_rec.primary_uom_code,
7520 									    l_open_repl_mo.UOM_Code )),
7521 			     g_conversion_precision);
7522 
7523 		   ELSE
7524 		     l_quantity_detailed := l_prim_quantity_detailed;
7525 		  END IF;
7526 
7527 		  IF (l_debug = 1) THEN
7528 		     print_debug('Qty Detailed           :'||l_quantity_detailed );
7529 		     print_debug('MOL Line Qty           :'||l_open_repl_mo.mol_qty);
7530 		     print_debug('MOL Line Qty Delivered :'||l_open_repl_mo.mol_delivered_qty);
7531 		  END IF;
7532 
7533 		  -- NOTE: l_quantity_detailed contains all qty of MMTT related TO CURRENT mo line whether in this
7534 		  -- RUN OR ANY previous runs
7535 		  IF  l_quantity_detailed < (l_open_repl_mo.mol_qty - l_open_repl_mo.mol_delivered_qty)  THEN -- partial allocation
7536 		     -- update the quantity detailed correctly
7537 		     UPDATE mtl_txn_request_lines mtrl
7538 		       SET mtrl.quantity_detailed = l_quantity_detailed
7539 		       where line_id = l_open_repl_mo.line_id;
7540 
7541 		     IF (l_debug = 1) THEN
7542 			print_debug('Updated the detailed qty on the MO line');
7543 		     END IF;
7544 
7545 		   ELSE -- Fully allocated
7546 		     -- it has been completely detailed
7547 		     -- DO NOT Close the MO, otherwise finalize Pick
7548 		     -- Confirm fails WHILE dropping the task
7549 		     UPDATE mtl_txn_request_lines mtrl
7550 		       SET mtrl.quantity_detailed = l_quantity_detailed
7551 		       where line_id = l_open_repl_mo.line_id;
7552 
7553 		     IF (l_debug = 1) THEN
7554 			print_debug('MO line completely detailed');
7555 		     END IF;
7556 
7557 		  END IF; -- for partial allocation
7558 
7559 	       END IF; -- for (NOT l_trigger_allocation)
7560 
7561 	    END LOOP; -- get pick_uom_code and fixed_multiple
7562 	    <<next_loc_in_sub>>
7563 	      CLOSE c_trigger_parameters;
7564 	    IF (l_debug = 1) THEN
7565 	       print_debug('Done with the Capacity of current Locator in the Sub');
7566 	    END IF;
7567 	 END LOOP;  -- For each locator in the sub
7568 	 CLOSE c_locators_in_sub;
7569       END IF; -- for L_CUR_SUB_HAS_CAPACITY
7570 
7571       <<next_mo_line>>
7572 
7573 	IF c_trigger_parameters%isopen THEN
7574 	   CLOSE c_trigger_parameters;
7575 	END IF;
7576 	IF c_locators_in_sub%isopen THEN
7577 	   CLOSE c_locators_in_sub;
7578 	END IF;
7579 
7580 	l_prev_to_sub  :=  l_open_repl_mo.TO_SUBINVENTORY_CODE;
7581 	l_prev_item_id := l_open_repl_mo.INVENTORY_ITEM_ID;
7582 
7583 	IF (l_debug = 1) THEN
7584 	   print_debug('Done Allocating CURRENT MO record ');
7585 	END IF;
7586    END LOOP; -- For each REPL MO line under consideration
7587 
7588 
7589    COMMIT;
7590    x_return_status        := FND_API.G_RET_STS_SUCCESS;
7591 
7592 EXCEPTION
7593    WHEN OTHERS THEN
7594       IF l_debug = 1 THEN
7595 	 print_debug('Exception in ALLOCATE_REPL_MOVE_ORDER: ' || sqlcode || ', ' || sqlerrm);
7596       END IF;
7597        x_return_status        := FND_API.G_RET_STS_ERROR;
7598 END ALLOCATE_REPL_MOVE_ORDER;
7599 
7600 
7601 PROCEDURE UPDATE_DELIVERY_DETAIL (
7602 				  p_delivery_detail_id       IN NUMBER,
7603 				  P_PRIMARY_QUANTITY         IN NUMBER,
7604 				  P_SPLIT_DELIVERY_DETAIL_ID IN NUMBER  DEFAULT NULL,
7605 				  p_split_source_line_id     IN NUMBER DEFAULT NULL,
7606 				  x_return_status            OUT    NOCOPY VARCHAR2
7607 				  )
7608 
7609   IS
7610      l_debug   NUMBER := NVL(fnd_profile.VALUE('INV_DEBUG_TRACE'), 0);
7611      l_orig_pri_qty  NUMBER;
7612 
7613      l_source_header_id NUMBER;
7614      l_source_line_id  NUMBER;
7615      l_source_line_detail_id  NUMBER;
7616      l_source_type_id  NUMBER;
7617      l_demand_header_id  NUMBER;
7618      l_demand_line_id  NUMBER;
7619      l_demand_type_id  NUMBER;
7620      l_primary_uom VARCHAR2(3);
7621      l_demand_sort_order NUMBER;
7622      l_item_id NUMBER;
7623      l_org_id NUMBER;
7624      L_repl_type NUMBER;
7625      L_REPL_LEVEL NUMBER;
7626      l_no_deliv_in_wrd BOOLEAN := FALSE;
7627 
7628 BEGIN
7629 
7630    IF l_debug = 1 THEN
7631       print_debug('P_SPLIT_DELIVERY_DETAIL_ID :'||P_SPLIT_DELIVERY_DETAIL_ID );
7632       print_debug('p_delivery_detail_id: '|| p_delivery_detail_id);
7633       print_debug('p_delivery_detail_id: '|| p_split_source_line_id);
7634       print_debug('p_primary_quantity  :' || p_primary_quantity);
7635    END IF;
7636 
7637    -- This API will be called by the shipping team to update the qty in wrd
7638    -- if the demand qty changes in the process
7639    -- if P_QUANTITY = 0, then WMS will remove those demands from the
7640    -- replenishment consideration
7641 
7642    IF p_split_delivery_detail_id IS NULL THEN
7643 
7644       IF P_PRIMARY_QUANTITY > 0 THEN
7645 	 --UPDATE THE PRIMARY QTY FOR THE DEMAND
7646 
7647 	 UPDATE WMS_REPLENISHMENT_DETAILS
7648 	   SET PRIMARY_QUANTITY = P_PRIMARY_QUANTITY
7649 	   WHERE DEMAND_LINE_DETAIL_ID = p_delivery_detail_id
7650 	   AND primary_quantity >= P_PRIMARY_QUANTITY;
7651 
7652        ELSE
7653 
7654 	 -- NEED TO REMOVE THE ENTRY FROM WRD.
7655 	 -- In this case we will have More qty in the replenishment mover
7656 	 -- ORDER that will be consumed BY later processing
7657 
7658 
7659 	 DELETE FROM WMS_REPLENISHMENT_DETAILS
7660 	   WHERE DEMAND_LINE_DETAIL_ID = P_DELIVERY_DETAIL_ID;
7661 
7662       END IF;
7663 
7664 
7665 
7666     ELSE -- MEANS DELIVERY IS SPLIT
7667 
7668       --Note: There can be case when this API will be called after
7669       -- splitting a delivery detail that was NOT originally tracked in the
7670       -- WRD table to start with
7671 
7672       --  p_delivery_detail_id is tied up with  P_PRIMARY_QUANTITY and
7673       -- remaining qty go with new delivery detail  p_split_delivery_detail_id
7674       BEGIN
7675 	 SELECT
7676 	   source_header_id, Source_line_id,
7677 	   Source_line_detail_id,Source_type_id, demand_header_id,
7678 	   demand_line_id,demand_type_id, Primary_UOM, Primary_Quantity,
7679 	   demand_sort_order, inventory_item_id, organization_id
7680 	   , Nvl(repl_level,1), repl_type
7681 	   INTO l_source_header_id,l_Source_line_id,
7682 	   l_Source_line_detail_id, l_Source_type_id,
7683 	   l_demand_header_id,l_demand_line_id, l_demand_type_id,l_Primary_UOM, l_orig_pri_qty, l_demand_sort_order,
7684 	   l_item_id, l_org_id , l_repl_level, l_repl_type
7685 	   FROM WMS_REPLENISHMENT_DETAILS
7686 	   WHERE DEMAND_LINE_DETAIL_ID = p_delivery_detail_id;
7687       EXCEPTION
7688 	 WHEN no_data_found THEN
7689 	    l_orig_pri_qty := -9999;
7690 	    l_no_deliv_in_wrd := TRUE;
7691       END;
7692 
7693       -- Insert split delivery details id only if the original delivery
7694       --  detail id is found IN WRD
7695       IF (NOT l_no_deliv_in_wrd) AND l_orig_pri_qty <> -9999 AND p_primary_quantity < l_orig_pri_qty THEN
7696 
7697 	 -- Update old delivery with decreased qty
7698 	 UPDATE WMS_REPLENISHMENT_DETAILS
7699 	   SET PRIMARY_QUANTITY = P_PRIMARY_QUANTITY
7700 	   WHERE DEMAND_LINE_DETAIL_ID = p_delivery_detail_id;
7701 
7702 	 -- Insert a new record in WRD with remaining qty
7703 	 -- Note: Priority of the Split demand Order remain same as the
7704 	 -- original one
7705 	 INSERT INTO WMS_REPLENISHMENT_DETAILS
7706 	   (Replenishment_id,
7707 	    Organization_Id,
7708 	    source_header_id,
7709 	    Source_line_id,
7710 	    Source_line_detail_id,
7711 	    Source_type_id,
7712 	    demand_header_id,
7713 	    demand_line_id,
7714 	    demand_line_detail_id,
7715 	    demand_type_id,
7716 	    Inventory_item_id,
7717 	    Primary_UOM,
7718 	    Primary_Quantity,
7719 	    demand_sort_order,
7720 	    repl_type,
7721 	    repl_level,
7722 	    CREATION_DATE,
7723 	    LAST_UPDATE_DATE,
7724 	    CREATED_BY,
7725 	    LAST_UPDATED_BY,
7726 	    LAST_UPDATE_LOGIN
7727 	    )VALUES (
7728 		     WMS_REPLENISHMENT_DETAILS_S.NEXTVAL,
7729 		     l_org_id,
7730 		     l_source_header_id,
7731 		     l_source_line_id,
7732 		     l_Source_line_detail_id,
7733 		     l_Source_type_id,
7734 		     l_demand_header_id,
7735 		     Nvl(p_split_source_line_id,l_demand_line_id),
7736 		     p_split_delivery_detail_id,
7737 		     l_demand_type_id,
7738 		     l_item_id,
7739 		     l_Primary_UOM,
7740 		     (l_orig_pri_qty - p_primary_quantity) ,
7741 		     l_demand_sort_order,
7742 		     L_repl_type,
7743 		     l_repl_level,
7744 		     Sysdate,
7745 		     Sysdate,
7746 		     fnd_global.user_id,
7747 		     fnd_global.user_id,
7748 		     fnd_global.user_id);
7749 
7750       END IF; -- FOR  l_orig_pri_qty <> -9999
7751 
7752    END IF; -- MEANS DELIVERY IS SPLIT
7753 
7754    x_return_status        := FND_API.G_RET_STS_SUCCESS;
7755 EXCEPTION
7756    WHEN OTHERS THEN
7757       IF l_debug = 1 THEN
7758 	 print_debug('Exception in update_delivery_detail: ' || sqlcode || ', ' || sqlerrm);
7759       END IF;
7760 END update_delivery_detail;
7761 
7762 
7763 END wms_replenishment_pvt;