DBA Data[Home] [Help]

PACKAGE BODY: APPS.WMS_REPLENISHMENT_PVT

Source


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