DBA Data[Home] [Help]

PACKAGE BODY: APPS.INV_PICK_RELEASE_PUB

Source


1 PACKAGE BODY INV_Pick_Release_PUB AS
2 /* $Header: INVPPICB.pls 120.41.12020000.7 2013/03/29 10:53:20 brana ship $ */
3 
4 --  Global constant holding the package name
5 G_PKG_NAME                CONSTANT VARCHAR2(30) := 'INV_Pick_Release_PUB';
6 
7 is_debug                  BOOLEAN := NULL;
8 all_del_det_bo_tbl        WSH_INTERFACE.ChangedAttributeTabType;
9 g_org_grouping_rule_id    NUMBER;
10 g_organization_id         NUMBER;
11 g_print_mode              VARCHAR2(1);
12 
13 -- Bug# 4258360: Added these global constants which refer to the allocation method
14 -- stored for the current pick release batch (refers to INV_CACHE.wpb_rec.allocation_method)
15 g_inventory_only          CONSTANT VARCHAR2(1) := 'I';
16 g_crossdock_only          CONSTANT VARCHAR2(1) := 'C';
17 g_prioritize_inventory    CONSTANT VARCHAR2(1) := 'N';
18 g_prioritize_crossdock    CONSTANT VARCHAR2(1) := 'X';
19 
20 
21 -- Start of Comments
22 -- API name 	Pick_Release
23 -- Type		Public
24 -- Purpose
25 --   Pick releases the move order lines passed in.
26 --
27 -- Input Parameters
28 --   p_api_version_number
29 --	   API version number (current version is 1.0)
30 --   p_init_msg_list (optional, default FND_API.G_FALSE)
31 --	   Valid values: FND_API.G_FALSE or FND_API.G_TRUE.
32 --                           if set to FND_API.G_TRUE
33 --                                   initialize error message list
34 --                           if set to FND_API.G_FALSE - not initialize error
35 --                                   message list
36 --   p_commit (optional, default FND_API.G_FALSE)
37 --	   whether or not to commit the changes to database
38 --
39 --   p_mo_line_tbl
40 --       Table of Move Order Line records to pick release
41 --	p_auto_pick_confirm (optional, default 2)
42 --       Overrides org-level parameter for whether to automatically call
43 --		pick confirm after release
44 --	    Valid values: 1 (yes) or 2 (no)
45 --   p_grouping_rule_id
46 --       Overrides org-level and Move Order header-level grouping rule for
47 --		generating pick slip numbers
48 --   p_allow_partial_pick
49 --	    TRUE if the pick release process should continue after a line fails to
50 --		be detailed completely.  FALSE if the process should stop and roll
51 --		back all changes if a line cannot be fully detailed.
52 --	    NOTE: Printing pick slips as the lines are detailed is only supported if
53 --		this parameter is TRUE, since a commit must be done before printing.
54 --
55 -- Output Parameters
56 --   x_return_status
57 --       if the pick release process succeeds, the value is
58 --			fnd_api.g_ret_sts_success;
59 --       if there is an expected error, the value is
60 --             fnd_api.g_ret_sts_error;
61 --       if there is an unexpected error, the value is
62 --             fnd_api.g_ret_sts_unexp_error;
63 --   x_msg_count
64 --       if there is one or more errors, the number of error messages
65 --       	in the buffer
66 --   x_msg_data
67 --       if there is one and only one error, the error message
68 --   	(See fnd_api package for more details about the above output parameters)
69 --   x_pick_release_status
70 --	 This output parameter is a table of records (of type
71 -- 		INV_Release_Status_Tbl_Type) which specifies the pick release status
72 --		for each move order line that is passed in.
73 --
74 
75 procedure print_debug( p_message in varchar2, p_module in varchar2) is
76 begin
77  	inv_trx_util_pub.trace(p_message, 'PICKREL');
78 end;
79 
80 
81 
82 --2509322:Earlier when ever a component in a model is short we backorder all
83 --   components to the difference of new model quantity and original
84 --   and repick release all.But if many components are short then we end
85 --   up splitting many delivery details.
86 --   Now avoided multiple splits by storing back order details and do only once.
87 
88 PROCEDURE  Store_smc_bo_details
89 	   (x_return_status    OUT  NOCOPY VARCHAR2,
90             back_order_det_tbl IN WSH_INTERFACE.ChangedAttributeTabType) IS
91 l_delivery_detail_id       NUMBER;
92 l_new_cycle_count_quantity NUMBER:=0;
93 l_old_cycle_count_quantity NUMBER:=0;
94 
95 
96 
97 BEGIN
98  If is_debug Then
99    print_debug('Inside Store_smc_bo_details','INV_PICK_RELEASE_PUB');
100    print_debug('delivery detail'||back_order_det_tbl(1).delivery_detail_id,
101 	'INV_PICK_RELEASE_PUB');
102  End If;
103  x_return_status := fnd_api.g_ret_sts_success;
104 
105   if back_order_det_tbl.count >0 then
106     l_delivery_detail_id :=back_order_det_tbl(1).delivery_detail_id;
107     If is_debug Then
108       print_debug('Delivery detail'||l_delivery_detail_id,
109 	'INV_PICK_RELEASE_PUB');
110     End If;
111     l_new_cycle_count_quantity :=back_order_det_tbl(1).cycle_count_quantity;
112 
113   end if;
114   IF all_del_det_bo_tbl.EXISTS(l_delivery_detail_id) then
115     l_old_cycle_count_quantity :=
116 	all_del_det_bo_tbl(l_delivery_detail_id).cycle_count_quantity;
117     all_del_det_bo_tbl(l_delivery_detail_id).cycle_count_quantity :=
118         l_old_cycle_count_quantity+l_new_cycle_count_quantity;
119   ELSE
120     all_del_det_bo_tbl(l_delivery_detail_id) :=back_order_det_tbl(1);
121   END IF;
122 
123   If is_debug Then
124     print_debug('New Cycle count Qty: '
125 	||all_del_det_bo_tbl(l_delivery_detail_id).cycle_count_quantity
126         ,'INV_PICK_RELEASE_PUB');
127   End If;
128 EXCEPTION
129      WHEN FND_API.G_EXC_ERROR THEN
130         --
131         x_return_status := FND_API.G_RET_STS_ERROR;
132      WHEN FND_API.G_EXC_UNEXPECTED_ERROR THEN
133         if is_debug then
134           print_debug(SQLERRM,'INV_PICK_RELEASE_PUB');
135         end if;
136         x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
137      WHEN OTHERS THEN
138 	if is_debug then
139           print_debug(SQLERRM,'INV_PICK_RELEASE_PUB');
140         end if;
141         ROLLBACK TO Pick_Release_PUB;
142         x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
143 END;
144 
145 --2509322:Earlier when ever a component in a model is short we backorder all
146 -- components to the difference of new model quantity and original
147 -- and repick release all.But if many components are short then we end
148 -- up splitting many delivery details.
149 -- Now avoided multiple splits by storing back order details and do only once.
150 
151 PROCEDURE Backorder_SMC_DETAILS(x_return_status OUT NOCOPY VARCHAR2,
152                                 x_msg_data OUT NOCOPY VARCHAR2,
153                                 x_msg_count OUT NOCOPY NUMBER
154                                 ) IS
155 l_api_name  VARCHAR2(100):='Backorder_SMC_DETAILS';
156 l_delivery_detail_id NUMBER;
157 l_shipping_attr  WSH_INTERFACE.ChangedAttributeTabType;
158 l_del_index INTEGER;
159 
160 BEGIN
161  x_return_status := fnd_api.g_ret_sts_success;
162 
163 IF all_del_det_bo_tbl.COUNT >0 THEN
164    l_del_index :=all_del_det_bo_tbl.FIRST ;
165   LOOP
166     l_shipping_attr(1).source_header_id :=
167 	all_del_det_bo_tbl(l_del_index).source_header_id;
168     l_shipping_attr(1).source_line_id :=
169 	all_del_det_bo_tbl(l_del_index).source_line_id;
170     l_shipping_attr(1).ship_from_org_id :=
171 	all_del_det_bo_tbl(l_del_index).ship_from_org_id;
172     l_shipping_attr(1).released_status :=
173 	all_del_det_bo_tbl(l_del_index).released_status;
174     l_shipping_attr(1).delivery_detail_id :=
175 	all_del_det_bo_tbl(l_del_index).delivery_detail_id;
176     l_shipping_attr(1).action_flag := 'B';
177     l_shipping_attr(1).cycle_count_quantity :=
178         all_del_det_bo_tbl(l_del_index).cycle_count_quantity;
179 
180     l_shipping_attr(1).subinventory :=
181 	all_del_det_bo_tbl(l_del_index).subinventory ;
182     l_shipping_attr(1).locator_id :=all_del_det_bo_tbl(l_del_index).locator_id;
183 
184     if is_debug then
185       print_debug('Backordering SMC','INV_PICK_RELEASE_PUB');
186       print_debug('Delivery detail'|| l_shipping_attr(1).delivery_detail_id,
187 	'INV_PICK_RELEASE_PUB');
188     end if;
189 
190     WSH_INTERFACE.Update_Shipping_Attributes
191               (p_source_code               => 'INV',
192                p_changed_attributes        => l_shipping_attr,
193                x_return_status             => x_return_status
194     );
195 
196     if( x_return_status = FND_API.G_RET_STS_ERROR ) then
197 		if is_debug then
198                   print_debug('return error from update shipping attributes',
199                               'Inv_Pick_Release_Pub.Pick_Release');
200 		end if;
201                 raise FND_API.G_EXC_ERROR;
202     elsif x_return_status = FND_API.G_RET_STS_UNEXP_ERROR then
203 		if is_debug then
204                   print_debug('return error from update shipping attributes',
205                               'Inv_Pick_Release_Pub.Pick_Release');
206 		end if;
207                 raise FND_API.G_EXC_UNEXPECTED_ERROR;
208     end if;
209 
210     l_shipping_attr.DELETE;
211     EXIT WHEN l_del_index =all_del_det_bo_tbl.LAST;
212     l_del_index :=all_del_det_bo_tbl.NEXT(l_del_index);
213 
214   END LOOP;
215 END IF;
216 all_del_det_bo_tbl.DELETE;
217 x_return_status :=fnd_api.g_ret_sts_success;
218 EXCEPTION
219      WHEN FND_API.G_EXC_ERROR THEN
220         --
221         x_return_status := FND_API.G_RET_STS_ERROR;
222         --
223         FND_MSG_PUB.Count_And_Get(p_count => x_msg_count
224            , p_data => x_msg_data);
225         --
226      WHEN FND_API.G_EXC_UNEXPECTED_ERROR THEN
227         --
228         x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
229         --
230         FND_MSG_PUB.Count_And_Get(p_count => x_msg_count
231            , p_data => x_msg_data);
232         --
233      WHEN OTHERS THEN
234         ROLLBACK TO Pick_Release_PUB;
235         --
236         x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
237         --
238         IF FND_MSG_PUB.Check_Msg_Level(FND_MSG_PUB.G_MSG_LVL_UNEXP_ERROR) THEN
239            FND_MSG_PUB.Add_Exc_Msg(G_PKG_NAME, l_api_name);
240         END IF;
241         --
242         FND_MSG_PUB.Count_And_Get(p_count => x_msg_count
243            , p_data => x_msg_data);
244 END;
245 
246 
247 --Sort
248 --  This procedure sorts the input lines so that lines with the same
249 -- header_id are contiguous. This sort used quick sort, but quick sort
250 -- doesn't preserve the order of the records within a header.  It's
251 -- necessary to preserve this order because of shipsets - lines belonging
252 -- to the same shipset must be consecutive in the table.  Because
253 -- these lines will usually be mostly in order already, we can use the
254 -- InsertionSort algorithm.
255 
256 procedure sort( p_trolin_tbl IN OUT NOCOPY INV_Move_Order_PUB.TROLIN_TBL_TYPE,
257 		p_low_index	IN NUMBER,
258 		p_high_index	IN NUMBER) IS
259    l_low_index 	NUMBER := p_low_index;
260    l_high_index NUMBER := p_high_index;
261    l_pivot_idx  NUMBER;
262    l_prior_index NUMBER;
263    l_trolin_rec INV_MOVE_ORDER_PUB.TROLIN_REC_TYPE;
264    l_pivot_rec  INV_MOVE_ORDER_PUB.TROLIN_REC_TYPE;
265    i NUMBER;
266    j NUMBER;
267 
268 BEGIN
269 
270    IF l_low_Index >= l_high_index THEN
271       RETURN;
272    END IF;
273    -- for each record in table but the first
274    i := p_trolin_tbl.NEXT(l_low_index);
275    LOOP
276        j := i;
277        l_pivot_rec := p_trolin_tbl(i);
278        -- table to left of current location (j) is already sorted.
279        -- Copy current record (pivot rec) from table.
280        -- Look at record to left (prior index).  If record to
281        -- left has header greater than current record, move record to
282        -- left one place to the right (the spot that used to be
283        -- occupied by the currect record). Continue to move current
284        -- record to the left until the prior record's header id is
285        -- <= current record's header id.  At that point, save pivot
286        -- rec into table at current location.
287        While j > l_low_index  Loop
288 	  l_prior_index := p_trolin_tbl.PRIOR(j);
289 	  IF l_pivot_rec.header_id >= p_trolin_tbl(l_prior_index).header_id Then
290 	     EXIT;
291 	  END IF;
292 	  p_trolin_tbl(j) := p_trolin_tbl(l_prior_index);
293 	  j := l_prior_index;
294        End Loop;
295        p_trolin_tbl(j) := l_pivot_rec;
296        EXIT WHEN p_trolin_tbl.LAST = i;
297        i := p_trolin_tbl.NEXT(i);
298    END LOOP;
299 END sort;
300 
301 PROCEDURE test_sort( p_trolin_tbl IN OUT NOCOPY INV_MOVE_ORDER_PUB.Trolin_Tbl_Type) IS
302 BEGIN
303     sort(p_trolin_tbl, p_trolin_tbl.FIRST, p_trolin_tbl.LAST);
304 END test_sort;
305 
306 -- the following API is added for assign pick slip numbers after cartonize
307 -- for patchset J bulk picking
308 PROCEDURE assign_pick_slip_number(
309                     x_return_status	    OUT   NOCOPY VARCHAR2,
310 		    x_msg_count       	    OUT   NOCOPY NUMBER,
311 		    x_msg_data        	    OUT   NOCOPY VARCHAR2,
312 		    p_move_order_header_id  IN    NUMBER   DEFAULT  0,
313 		    p_ps_mode               IN    VARCHAR2,
314 		    p_grouping_rule_id IN    NUMBER,
315 		    p_allow_partial_pick    IN    VARCHAR2) IS
316 
317 
318 l_pick_slip_mode           VARCHAR2(1); -- The print pick slip mode (immediate or deferred) that should be used
319 l_pick_slip_number         NUMBER; -- The pick slip number to put on the Move Order Line Details for a Line.
320 l_ready_to_print           VARCHAR2(1); -- The flag for whether we need to commit and print after receiving
321 -- the current pick slip number.
322 l_api_return_status        VARCHAR2(1); -- The return status of APIs called within the Process Line API.
323 l_api_error_code           NUMBER; -- The error code of APIs called within the Process Line API.
324 l_api_error_msg            VARCHAR2(100); -- The error message returned by certain APIs called within Process_Line
325 l_count                    NUMBER;
326 l_message                  VARCHAR2(255);
327 l_report_set_id            NUMBER;
328 l_request_number           VARCHAR2(80);
329 l_call_mode                VARCHAR2(1); --bug 1968032 will not commit if not null when called from SE.
330 l_grouping_rule_id         NUMBER;
331 l_get_header_rule         NUMBER; -- 1 (yes) if the grouping rule ID was
332                                         -- not passed in and the headers have
333                                         -- different grouping rules, or 2 (no)
334                                         -- otherwise.
335 l_mso_header_id          NUMBER;
336 l_organization_id        NUMBER;
337 l_api_name		CONSTANT VARCHAR2(30) := 'ASSIGN_PICK_SLIP_NUMBER';
338 CURSOR l_mold_crs IS
339   SELECT mmtt.transaction_temp_id
340        , mmtt.subinventory_code
341        , mmtt.locator_id
342        , mmtt.transfer_to_location
343        , mmtt.organization_id
344        , wdd.oe_header_id
345        , wdd.oe_line_id
346        , wdd.customer_id
347        , wdd.freight_code
348        , wdd.ship_to_location
349        , wdd.shipment_priority_code
350        , wdd.trip_stop_id
351        , wdd.shipping_delivery_id
352        , mol.ship_set_id
353        , mol.ship_model_id
354        , mmtt.parent_line_id
355        , mmtt.transfer_subinventory
356        , mmtt.project_id
357        , mmtt.task_id
358        , mmtt.inventory_item_id
359        , mmtt.revision
360     FROM mtl_material_transactions_temp mmtt,mtl_txn_request_lines mol,wsh_inv_delivery_details_v wdd
361    WHERE mmtt.move_order_line_id = mol.line_id
362      AND mol.header_id = p_move_order_header_id
363      AND wdd.move_order_line_id = mol.line_id
364      AND mmtt.pick_slip_number IS NULL;
365 
366  -- the following cursor will be used when calling from concurrent program
367  CURSOR l_mold_crs_con IS
368    SELECT wct.transaction_temp_id
369    FROM wms_cartonization_temp wct
370    WHERE wct.parent_line_id = wct.transaction_temp_id;   -- only parent lines
371 
372  l_debug number := NVL(FND_PROFILE.VALUE('INV_DEBUG_TRACE'),0);
373 
374 BEGIN
375   IF (l_debug = 1) THEN
376 	print_debug('get pick slip number for move order header '||p_move_order_header_id,
377 	            'Inv_Pick_Release_PVT.assign_pick_slip_number');
378    print_debug('p_grouping_rule_id = '||p_grouping_rule_id,'Inv_Pick_Release_PVT.assign_pick_slip_number');
379   END IF;
380   SAVEPOINT assign_pick_slip;
381 
382   IF p_move_order_header_id = -1 THEN
383       IF (l_debug = 1) THEN
384       	print_debug('calling from concurrent program ',
385       	            'Inv_Pick_Release_PVT.assign_pick_slip_number');
386       END IF;
387       For mmtt_line in l_mold_crs_con LOOP
388           UPDATE mtl_material_transactions_temp
389 	  SET pick_slip_number = wsh_pick_slip_numbers_s.nextval
390 	  WHERE transaction_temp_id = mmtt_line.transaction_temp_id;
391       END LOOP;
392   ELSE
393 
394 -- The Move Order Lines may need to have their grouping rule ID defaulted
395 -- from the header.  This is only necessary if the Grouping Rule ID was not
396 -- passed in as a parameter.
397   IF p_grouping_rule_id <> FND_API.G_MISS_NUM THEN
398   l_grouping_rule_id := p_grouping_rule_id;
399   l_get_header_rule := 2;
400   ELSE
401   l_get_header_rule := 1;
402   END IF;
403 
404   IF (l_debug = 1) THEN
405  	     print_debug('l_get_header_rule = '||l_get_header_rule,'Inv_Pick_Release_PVT.assign_pick_slip_number');
406   END IF;
407 
408   IF l_get_header_rule = 1 THEN
409   BEGIN
410   SELECT grouping_rule_id,organization_id
411   INTO l_grouping_rule_id,l_organization_id
412   FROM mtl_txn_request_headers
413   WHERE header_id = p_move_order_header_id;
414   EXCEPTION
415   WHEN no_data_found THEN
416     ROLLBACK TO Assign_Pick_slip;
417     FND_MESSAGE.SET_NAME('INV','INV_NO_HEADER_FOUND');
418     FND_MESSAGE.SET_TOKEN('MO_LINE_ID','');
419     FND_MSG_PUB.Add;
420     RAISE fnd_api.g_exc_unexpected_error;
421   END;
422 
423   IF (l_debug = 1) THEN
424  	     print_debug('l_grouping_rule_id = '||l_grouping_rule_id||',l_organization_id = '||l_organization_id,
425  	                 'Inv_Pick_Release_PVT.assign_pick_slip_number');
426   END IF;
427 
428 -- If the header did not have a grouping rule ID, retrieve it from
429 -- the organization-level default.
430   IF l_grouping_rule_id IS NULL THEN
431   BEGIN
432     SELECT pick_grouping_rule_id
433     INTO l_grouping_rule_id
434     FROM wsh_shipping_parameters    -- Bug 16309114 changed from wsh_parameters
435     WHERE organization_id = l_organization_id;
436     EXCEPTION
437     WHEN no_data_found THEN
438       ROLLBACK TO Assign_pick_slip;
439       FND_MESSAGE.SET_NAME('INV','INV-NO ORG INFORMATION');
440       FND_MSG_PUB.Add;
441       RAISE fnd_api.g_exc_unexpected_error;
442   END;
443   END IF; -- get header rule
444   END IF; -- return status
445 
446   For mmtt_line in l_mold_crs LOOP
447 
448     IF mmtt_line.parent_line_id is not null THEN   -- parent line
449     -- assign a seperate pick slip number for parent task and call WMS's pick slip
450     -- report to print out
451        UPDATE mtl_material_transactions_temp
452 	  SET pick_slip_number = wsh_pick_slip_numbers_s.nextval
453 	WHERE transaction_temp_id = mmtt_line.parent_line_id;
454        IF ( p_ps_mode <> 'I' ) THEN
455 	   	    WSH_INV_INTEGRATION_GRP.FIND_PRINTER
456 	   	    ( p_subinventory    => mmtt_line.subinventory_code
457 	   	    , p_organization_id => mmtt_line.organization_id
458 	   	    , x_error_message   => l_api_error_msg
459 	   	    , x_api_Status      => l_api_return_status
460 	   	    ) ;
461 
462 	   	    IF l_api_return_status <> fnd_api.g_ret_sts_success THEN
463 	   	      IF (l_debug = 1) THEN
464 	   		 print_debug('return error from WSH_INV_INTEGRATION.find_printer',
465 	   			  'Inv_Pick_Release_Pvt.Process_Line');
466 	   	      END IF;
467 	   	      RAISE fnd_api.g_exc_unexpected_error;
468 	   	    END IF;
469 
470        END IF ;
471        IF p_ps_mode = 'I' and
472        	  p_allow_partial_pick = fnd_api.g_true THEN
473        	    COMMIT WORK;
474 
475        	    BEGIN
476 
477 	      /*Added for Bug # 6144354 */
478 	      SELECT request_number
479 	      INTO l_request_number
480 	      FROM mtl_txn_request_headers
481 	      WHERE header_id = p_move_order_header_id;
482 	      --AND organization_id =  mmtt_line.organization_id; --bug 8829363
483 
484 	      IF (l_debug = 1) THEN
485 		print_debug('organization_id '||mmtt_line.organization_id,'Inv_Pick_Release_PVT.assign_pick_slip_number');
486               END IF;
487               /*End of modifications for Bug # 6144354 */
488 
489        	      SELECT document_set_id
490        		INTO l_report_set_id
491        		FROM wsh_picking_batches
492        	       WHERE NAME = l_request_number;
493        	    EXCEPTION
494        	      WHEN NO_DATA_FOUND THEN
495        		x_return_status  := fnd_api.g_ret_sts_error;
496        		RAISE fnd_api.g_exc_error;
497        	    END;
498 
499        	    wsh_pr_pick_slip_number.print_pick_slip(
500        	      p_pick_slip_number           => l_pick_slip_number
501        	    , p_report_set_id              => l_report_set_id
502        	    , p_organization_id            => mmtt_line.organization_id
503        	    , x_api_status                 => l_api_return_status
504        	    , x_error_message              => l_api_error_msg
505        	    );   -- don't need to call WMS new pick slip report, call shipping's api and add new wms report to the
506                  -- proper document set
507 
508        	    IF l_api_return_status <> fnd_api.g_ret_sts_success THEN
509        	      ROLLBACK TO assign_pick_slip;
510        	      fnd_message.set_name('INV', 'INV_PRINT_PICK_SLIP_FAILED');
511        	      fnd_message.set_token('PICK_SLIP_NUM', TO_CHAR(l_pick_slip_number));
512        	      fnd_msg_pub.ADD;
513        	      RAISE fnd_api.g_exc_unexpected_error;
514        	    END IF;
515 	  END IF;
516 
517     ELSE
518 	  l_call_mode  := NULL;
519 	  -- Bug 2666620: Inline branching to call either WSH or INV get_pick_slip_number
520 	  inv_pick_release_pvt.get_pick_slip_number(
521 	    p_ps_mode                    => p_ps_mode
522 	  , p_pick_grouping_rule_id      => l_grouping_rule_id
523 	  , p_org_id                     => mmtt_line.organization_id
524 	  , p_header_id                  => mmtt_line.oe_header_id
525 	  , p_customer_id                => mmtt_line.customer_id
526 	  , p_ship_method_code           => mmtt_line.freight_code
527 	  , p_ship_to_loc_id             => mmtt_line.ship_to_location
528 	  , p_shipment_priority          => mmtt_line.shipment_priority_code
529 	  , p_subinventory               => mmtt_line.subinventory_code
530 	  , p_trip_stop_id               => mmtt_line.trip_stop_id
531 	  , p_delivery_id                => mmtt_line.shipping_delivery_id
532 	  , x_pick_slip_number           => l_pick_slip_number
533 	  , x_ready_to_print             => l_ready_to_print
534 	  , x_api_status                 => l_api_return_status
535 	  , x_error_message              => l_api_error_msg
536 	  , x_call_mode                  => l_call_mode
537 	  , p_dest_subinv                => mmtt_line.transfer_subinventory
538 	  , p_dest_locator_id            => mmtt_line.transfer_to_location
539 	  , p_project_id                 => mmtt_line.project_id
540 	  , p_task_id                    => mmtt_line.task_id
541 	  , p_inventory_item_id          => mmtt_line.inventory_item_id
542 	  , p_locator_id                 => mmtt_line.locator_id
543 	  , p_revision                   => mmtt_line.revision
544 	  );
545 	  IF (l_debug = 1) THEN
546 	     print_debug('l_call_mode'|| l_call_mode, 'Inv_Pick_Release_PVT.Process_Line');
547 	  END IF;
548 
549 	  IF l_api_return_status <> fnd_api.g_ret_sts_success
550 	     OR l_pick_slip_number = -1 THEN
551 	    ROLLBACK TO assign_pick_slip;
552 	    fnd_message.set_name('INV', 'INV_NO_PICK_SLIP_NUMBER');
553 	    fnd_msg_pub.ADD;
554 	    RAISE fnd_api.g_exc_unexpected_error;
555 	  END IF;
556 
557 	  IF ( p_ps_mode <> 'I' ) THEN
558 	    WSH_INV_INTEGRATION_GRP.FIND_PRINTER
559 	    ( p_subinventory    => mmtt_line.subinventory_code
560 	    , p_organization_id => mmtt_line.organization_id
561 	    , x_error_message   => l_api_error_msg
562 	    , x_api_Status      => l_api_return_status
563 	    ) ;
564 
565 	    IF l_api_return_status <> fnd_api.g_ret_sts_success THEN
566 	      IF (l_debug = 1) THEN
567 		 print_debug('return error from WSH_INV_INTEGRATION.find_printer',
568 			  'Inv_Pick_Release_Pvt.Process_Line');
569 	      END IF;
570 	      RAISE fnd_api.g_exc_unexpected_error;
571 	    END IF;
572 
573 	  END IF ;
574           l_mso_header_id     := inv_salesorder.get_salesorder_for_oeheader(mmtt_line.oe_header_id);
575 	  -- Assign the pick slip number to the record in MTL_MATERIAL_TRANSACTIONS_TEMP
576 	  UPDATE mtl_material_transactions_temp
577 	     SET pick_slip_number = l_pick_slip_number
578 	       , transaction_source_id = l_mso_header_id
579 	       , trx_source_line_id = mmtt_line.oe_line_id
580 	       , demand_source_header_id = l_mso_header_id
581 	       , demand_source_line = mmtt_line.oe_line_id
582 	   WHERE transaction_temp_id = mmtt_line.transaction_temp_id;
583 
584 	  -- If the pick slip is ready to be printed (and partial
585 	  -- picking is allowed) commit
586 	  -- and print at this point.
587 	  -- Bug 1663376 - Don't Commit if Ship_set_Id is not null,
588 	  --  since we need to be able to rollback
589 	  IF  l_ready_to_print = fnd_api.g_true
590 	      AND p_allow_partial_pick = fnd_api.g_true
591 	      AND mmtt_line.ship_set_id IS NULL
592 	      AND mmtt_line.ship_model_id IS NULL
593 	      AND l_call_mode IS NULL THEN
594 	    COMMIT WORK;
595 
596 	    BEGIN
597               SELECT request_number
598 	      INTO l_request_number
599 	      FROM mtl_txn_request_headers
600 	      WHERE header_id = p_move_order_header_id;
601 	      	--AND organization_id = l_organization_id; Bug 8829363
602 
603 	      SELECT document_set_id
604 		INTO l_report_set_id
605 		FROM wsh_picking_batches
606 	       WHERE NAME = l_request_number;
607 	    EXCEPTION
608 	      WHEN NO_DATA_FOUND THEN
609 		x_return_status  := fnd_api.g_ret_sts_error;
610 		RAISE fnd_api.g_exc_error;
611 	    END;
612 
613 	    wsh_pr_pick_slip_number.print_pick_slip(
614 	      p_pick_slip_number           => l_pick_slip_number
615 	    , p_report_set_id              => l_report_set_id
616 	    , p_organization_id            => mmtt_line.organization_id
617 	    , x_api_status                 => l_api_return_status
618 	    , x_error_message              => l_api_error_msg
619 	    );
620 
621 	    IF l_api_return_status <> fnd_api.g_ret_sts_success THEN
622 	      ROLLBACK TO process_line_pvt;
623 	      fnd_message.set_name('INV', 'INV_PRINT_PICK_SLIP_FAILED');
624 	      fnd_message.set_token('PICK_SLIP_NUM', TO_CHAR(l_pick_slip_number));
625 	      fnd_msg_pub.ADD;
626 	      RAISE fnd_api.g_exc_unexpected_error;
627 	    END IF;
628 	  END IF;
629       END IF;
630   END LOOP;
631   END IF; -- p_move_ordeR_header <> -1
632 EXCEPTION
633      WHEN FND_API.G_EXC_ERROR THEN
634      ROLLBACK TO   Assign_pick_slip;
635      	--
636      	x_return_status := FND_API.G_RET_STS_ERROR;
637      	--
638      	FND_MSG_PUB.Count_And_Get(p_count => x_msg_count
639      	   , p_data => x_msg_data);
640      	--
641      WHEN FND_API.G_EXC_UNEXPECTED_ERROR THEN
642      ROLLBACK TO   Assign_pick_slip;
643      	--
644      	x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
645      	--
646      	FND_MSG_PUB.Count_And_Get(p_count => x_msg_count
647      	   , p_data => x_msg_data);
648      	--
649      WHEN OTHERS THEN
650 	ROLLBACK TO   Assign_pick_slip;
651      	--
652      	x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
653      	--
654      	IF FND_MSG_PUB.Check_Msg_Level(FND_MSG_PUB.G_MSG_LVL_UNEXP_ERROR) THEN
655      	   FND_MSG_PUB.Add_Exc_Msg(G_PKG_NAME, l_api_name);
656      	END IF;
657      	--
658      	FND_MSG_PUB.Count_And_Get(p_count => x_msg_count
659      	   , p_data => x_msg_data);
660 END assign_pick_slip_number;
661 
662 
663 -- Bug# 4258360
664 -- Pick_Release API is overloaded for R12 changes related to the Planned Crossdocking project.
665 PROCEDURE Pick_Release
666   (
667    p_api_version		IN  	NUMBER
668    ,p_init_msg_list	        IN  	VARCHAR2
669    ,p_commit		        IN	VARCHAR2
670    ,x_return_status             OUT 	NOCOPY VARCHAR2
671    ,x_msg_count                 OUT 	NOCOPY NUMBER
672    ,x_msg_data                  OUT 	NOCOPY VARCHAR2
673    ,p_mo_line_tbl		IN  	INV_Move_Order_PUB.TROLIN_TBL_TYPE
674    ,p_auto_pick_confirm	        IN  	NUMBER
675    ,p_grouping_rule_id	        IN  	NUMBER
676    ,p_allow_partial_pick	IN	VARCHAR2
677    ,x_pick_release_status	OUT	NOCOPY INV_Release_Status_Tbl_Type
678    ,p_plan_tasks                IN      BOOLEAN
679    ,p_skip_cartonization        IN      BOOLEAN := FALSE
680    ,p_mo_transact_date          IN      DATE
681    )
682   IS
683    l_wsh_release_table          WSH_PR_CRITERIA.relRecTabTyp;
684    l_trolin_delivery_ids        WSH_UTIL_CORE.Id_Tab_Type;
685    l_del_detail_id              WSH_PICK_LIST.DelDetTabTyp;
686 
687 BEGIN
688    INV_Pick_Release_Pub.Pick_Release
689      (
690       p_api_version             => p_api_version
691       ,p_init_msg_list	        => p_init_msg_list
692       ,p_commit		        => p_commit
693       ,x_return_status          => x_return_status
694       ,x_msg_count              => x_msg_count
695       ,x_msg_data               => x_msg_data
696       ,p_mo_line_tbl		=> p_mo_line_tbl
697       ,p_auto_pick_confirm	=> p_auto_pick_confirm
698       ,p_grouping_rule_id	=> p_grouping_rule_id
699       ,p_allow_partial_pick	=> p_allow_partial_pick
700       ,x_pick_release_status	=> x_pick_release_status
701       ,p_plan_tasks             => p_plan_tasks
702       ,p_skip_cartonization     => p_skip_cartonization
703       ,p_wsh_release_table      => l_wsh_release_table
704       ,p_trolin_delivery_ids    => l_trolin_delivery_ids
705       ,p_del_detail_id          => l_del_detail_id
706       ,p_mo_transact_date       => p_mo_transact_date
707       ,p_dynamic_replenishment  => NULL  --Added R12.1 Replenishment Proj 6710368
708       );
709 END Pick_Release;
710 
711 
712 -- Bug# 4258360
713 -- Pick_Release API is overloaded for R12 changes related to the Planned Crossdocking project.
714 -- Three new IN OUT parameters are added.
715 PROCEDURE Pick_Release
716   (
717    p_api_version		IN  	NUMBER
718    ,p_init_msg_list	        IN  	VARCHAR2
719    ,p_commit		        IN	VARCHAR2
720    ,x_return_status             OUT 	NOCOPY VARCHAR2
721    ,x_msg_count                 OUT 	NOCOPY NUMBER
722    ,x_msg_data                  OUT 	NOCOPY VARCHAR2
723    ,p_mo_line_tbl		IN  	INV_Move_Order_PUB.TROLIN_TBL_TYPE
724    ,p_auto_pick_confirm	        IN  	NUMBER
725    ,p_grouping_rule_id	        IN  	NUMBER
726    ,p_allow_partial_pick	IN	VARCHAR2
727    ,x_pick_release_status	OUT	NOCOPY INV_Release_Status_Tbl_Type
728    ,p_plan_tasks                IN      BOOLEAN
729    ,p_skip_cartonization        IN      BOOLEAN
730    ,p_wsh_release_table         IN OUT  NOCOPY WSH_PR_CRITERIA.relRecTabTyp
731    ,p_trolin_delivery_ids       IN OUT  NOCOPY WSH_UTIL_CORE.Id_Tab_Type
732    ,p_del_detail_id             IN OUT  NOCOPY WSH_PICK_LIST.DelDetTabTyp
733    ,p_mo_transact_date          IN      DATE
734    ,p_dynamic_replenishment     IN      VARCHAR2  --Added R12.1 Replenishment Proj 6710368
735    ) IS
736       l_api_version		CONSTANT NUMBER := 1.0;
737       l_api_name		CONSTANT VARCHAR2(30) := 'Pick_Release';
738 
739       l_mo_line_count		NUMBER;
740 					-- The number of move order lines to
741                                 	-- be pick released.
742       l_line_index		NUMBER;
743 					-- The index of the line in the table
744 					-- being processed
745       l_mo_line		        INV_Move_Order_PUB.TROLIN_REC_TYPE;
746 					-- Temporary record to hold information
747 					-- on the record being processed.
748       l_organization_id	        NUMBER;
749 					-- The organization ID to use (based
750 					-- on the move order lines passed in).
751       l_print_mode		VARCHAR2(1);
752 					-- The pick slip printing mode to use
753 					-- (I = immediate, E = deferred)
754       l_mo_type			NUMBER;	-- The type of the move order (should
755 					-- be Pick Wave - 3)
756       l_mo_number		VARCHAR2(30);
757 					-- The move order number
758       l_grouping_rule_id	NUMBER;	-- The grouping rule ID to use (which
759 					-- may come from the parameter passed
760 					-- in or the default in the header).
761       l_get_header_rule	        NUMBER;	-- 1 (yes) if the grouping rule ID was
762 					-- not passed in and the headers have
763 					-- different grouping rules, or 2 (no)
764 					-- otherwise.
765       l_grouping_rules_differ	NUMBER;	-- Flag which tells whether the move
766 					-- order lines have differing grouping
767 					-- rule IDS in their headers.
768       l_auto_pick_confirm	NUMBER;	-- Whether or not to call the pick
769 					-- confirm process automatically.
770 					-- This may come from the parameter
771 					-- passed in or the org-level
772 					-- parameter.
773       l_api_return_status	VARCHAR2(1);
774 					-- The return status of APIs called
775 					-- within the Pick Release API.
776       l_processed_row_count	NUMBER := 0;
777 					-- The number of rows which have been
778 					-- processed.
779       l_detail_rec_count         NUMBER := 0;
780       l_reservation_exists NUMBER := 0; --BUG13604664
781 
782    l_mo_line_tbl	        INV_Move_Order_Pub.Trolin_Tbl_Type := p_mo_line_tbl;
783    l_shipping_attr              WSH_INTERFACE.ChangedAttributeTabType;
784    l_smc_backorder_det_tbl      WSH_INTERFACE.ChangedAttributeTabType;
785    l_shipset_smc_backorder_rec  WSH_INTEGRATION.BackorderRecType;
786    l_action_flag VARCHAR2(1);
787    l_quantity NUMBER;
788    -- HW INVCONV Added Qty2 variables
789    l_quantity2 NUMBER;
790    l_transaction_quantity2 NUMBER;
791    l_transaction_quantity NUMBER;
792    l_delivery_detail_id NUMBER;
793    l_source_header_id NUMBER;
794    l_source_line_id NUMBER;
795    l_released_status VARCHAR2(1);
796    l_line_status Number;
797    -- used for processing ship sets
798    l_cur_ship_set_id NUMBER := NULL;
799    l_set_index NUMBER;
800    l_start_index NUMBER;
801    l_set_process NUMBER;
802    l_start_process NUMBER;
803    -- used for processing ship model complete
804    l_model_reloop BOOLEAN := FALSE;
805    l_cur_ship_model_id NUMBER := NULL;
806    l_cur_txn_source_line_id NUMBER;
807    l_cur_txn_source_qty NUMBER;
808    -- HW INVCONV -Added Qty2
809    l_cur_txn_source_qty2 NUMBER;
810    l_cur_txn_source_req_qty NUMBER;
811    l_txn_source_line_uom VARCHAR2(3);
812    l_new_model_quantity NUMBER;
813    l_set_txn_source_line_id NUMBER := NULL;
814    l_set_txn_source_req_qty NUMBER;
815    l_set_txn_source_uom VARCHAR2(3);
816    l_set_new_req_qty NUMBER;
817    l_new_line_quantity NUMBER;
818    l_tree_id NUMBER;
819    l_revision_control_code NUMBER;
820    l_lot_control_code NUMBER;
821    l_revision_controlled BOOLEAN;
822    l_lot_controlled BOOLEAN;
823    l_req_msg  VARCHAR2(255);
824    g_pjm_unit_eff_enabled VARCHAR2(1) :=NULL;
825    l_demand_source_type      NUMBER;
826    l_mso_header_id     NUMBER;
827    l_oe_header_id      NUMBER;
828    l_reservable_type NUMBER := NULL;
829 
830    l_last_rec NUMBER;
831    l_item_index NUMBER;
832    l_qtree_line_index NUMBER;
833    l_wms_installed BOOLEAN;
834    l_multiple_headers BOOLEAN := FALSE;
835    l_first_header_id NUMBER := NULL;
836    l_quantity_delivered NUMBER;
837    -- HW INVCONV -Added Qty2
838    l_quantity2_delivered NUMBER;
839    l_backup_id NUMBER;
840    l_current_header_id NUMBER := NULL;
841    l_return_value BOOLEAN := TRUE;
842    l_do_cartonization number := NVL(FND_PROFILE.VALUE('WMS_ASSIGN_TASK_TYPE'),1); --added for Bug3237702
843 
844 
845 TYPE quantity_tree_tbl_type is TABLE OF NUMBER
846         INDEX BY BINARY_INTEGER;
847 
848 
849    --there will be one record in this table for every item in the MO batch.
850    --if the item is unit effective,
851    --    first line rec will hold the txn_source_line_id of first MO line
852    --    for this item; last_line_rec will hold the txn_source_line_id of
853    --    the last MO line for this item in the batch;
854    --This table is indexed based on the item_id
855    TYPE qtree_item_rec_type IS RECORD (
856        tree_id        NUMBER
857       ,unit_effective VARCHAR2(1)
858       ,first_line_rec NUMBER
859       ,last_line_rec  NUMBER
860    );
861 
862    --if item is unit effective controlled, there will be one record
863    -- in this table for each separate sales order line in this batch;
864    --transaction type id and move order line id are needed to get the
865    --  information on demand to build the correct quantity tree;
866    --next_line_rec contains the txn_source_line_id of the next MO line
867    --  for this item;
868    --This table is indexed by txn_source_line_id
869    TYPE qtree_line_rec_type IS RECORD (
870        tree_id             NUMBER
871       ,move_order_line_id  NUMBER
872       ,transaction_type_id NUMBER
873       ,next_line_rec       NUMBER
874    );
875 
876    TYPE qtree_item_tbl_type IS TABLE OF qtree_item_rec_type
877 	INDEX BY BINARY_INTEGER;
878 
879    TYPE qtree_line_tbl_type IS TABLE OF qtree_line_rec_type
880       INDEX BY BINARY_INTEGER;
881 
882    l_qtree_item_tbl qtree_item_tbl_type;
883    l_qtree_line_tbl qtree_line_tbl_type;
884 
885 
886    --This table is used to make sure that restore tree and backup tree
887    -- never get called more than once for a given tree within a shipset.
888    -- These two procedures can be a little slow, it's best to avoid calling
889    --  more than necessary. This table will be indexed by tree_id;  if
890    -- a record exists in this table for a given tree id, then the tree
891    -- is currently backed up and has not been restored.
892    -- This table is deleted at the beginning of each shipset/model.
893    l_qtree_backup_tbl  quantity_tree_tbl_type;
894 
895 
896    TYPE uom_tbl_type IS TABLE OF VARCHAR2(3)
897         INDEX BY BINARY_INTEGER;
898 
899    l_primary_uom_tbl uom_tbl_type;
900 
901    l_debug NUMBER;
902 
903    -- Bug# 4258360: Index pointer table so we can navigate through p_wsh_release_table
904    -- easily if needed based on the allocation mode for the pick release batch.
905    -- This should only be used for allocation mode = N (Prioritize Inventory)
906    TYPE wdd_index_tbl IS TABLE OF NUMBER INDEX BY BINARY_INTEGER;
907    l_wdd_index_tbl               wdd_index_tbl;
908 
909    -- Index used for adding crossdocked WDD lines into the input tables,
910    -- p_trolin_delivery_ids and p_del_detail_id for allocation mode of X (Prioritize Crossdock).
911    -- This is needed to enter the crossdocked WDD lines from p_wsh_release_table into the
912    -- delivery tables so a delivery can be created for them if needed.
913    -- This will also be used for other crossdock related changes.
914    -- l_xdock_next_index is needed when removing backordered WDD lines from the
915    -- delivery tables.
916    l_xdock_index                 PLS_INTEGER;
917    l_xdock_next_index            PLS_INTEGER;
918 
919    -- Table storing the delivery detail ID's for backordered lines.  These records
920    -- should be removed from the input tables, p_trolin_delivery_ids and p_del_detail_id
921    -- for allocation modes of I (Inventory Only) and X (Prioritize Crossdock).
922    -- This is so deliveries are not autocreated for them later on by Shipping.
923    -- UPDATE: This is not used anymore due to change in what Shipping passes for the
924    -- delivery tables.
925    TYPE backordered_wdd_tbl IS TABLE OF BOOLEAN INDEX BY BINARY_INTEGER;
926    l_backordered_wdd_tbl         backordered_wdd_tbl;
927 
928    -- Variables used to call the Shipping API to update a WDD line during partial or zero
929    -- allocation for allocation mode of N (Prioritize Inventory).  This will be used
930    -- primarily to update the released_status and to null out the move_order_line_id.
931    l_detail_info_tab             WSH_INTERFACE_EXT_GRP.delivery_details_Attr_tbl_Type;
932    l_in_rec                      WSH_INTERFACE_EXT_GRP.detailInRecType;
933    l_out_rec                     WSH_INTERFACE_EXT_GRP.detailOutRecType;
934 
935    -- Variables used to call the Shipping API to split a WDD line during partial
936    -- allocation for allocation mode of N (Prioritize Inventory).
937    l_detail_id_tab               WSH_UTIL_CORE.id_tab_type;
938    l_action_prms                 WSH_GLBL_VAR_STRCT_GRP.dd_action_parameters_rec_type;
939    l_action_out_rec              WSH_GLBL_VAR_STRCT_GRP.dd_action_out_rec_type;
940    l_split_wdd_rel_rec           WSH_PR_CRITERIA.relRecTyp;
941    l_split_delivery_detail_id    NUMBER;
942 
943    -- Variable storing the allocation method for the current picking batch
944    l_allocation_method           VARCHAR2(1);
945 
946    -- Variable used to store the lower tolerance for the current move order line
947    l_lower_tolerance		 NUMBER;
948 
949    -- Bug 4349602: save all MOL IDs in current batch
950    TYPE l_molid_tbltyp IS TABLE OF NUMBER INDEX BY BINARY_INTEGER;
951    l_mol_id_tbl                  l_molid_tbltyp;
952    l_mol_id_index                NUMBER;
953    l_atr_org            NUMBER; -- r12 replenishment project
954 
955     --Bug 6696594
956     l_transaction_id	INV_LABEL.transaction_id_rec_type;
957     l_counter		NUMBER := 1 ;
958     honor_case_pick_count NUMBER := 0;
959     honor_case_pick	VARCHAR2(1) := 'Y';
960     l_label_status VARCHAR2(500);
961     l_return_status VARCHAR2(1) := fnd_api.g_ret_sts_success;
962     v_transaction_id INV_LABEL.transaction_id_rec_type;
963     --Bug 6696594
964 
965 	--MUOM Fulfillment Project
966     l_fulfill_base varchar2(1):='P';
967     l_lower_tolerance2 NUMBER;
968 
969     -- Bug 9130704
970     -- Cursor to fetch temp IDs for case pick labels
971     CURSOR c_wpr_casepick_labels (p_mo_hdr_id NUMBER) IS
972     -- Non-bulk tasks
973     SELECT mmtt.transaction_temp_id
974       FROM mtl_material_transactions_temp   mmtt
975      WHERE mmtt.move_order_header_id = p_mo_hdr_id
976        AND mmtt.parent_line_id IS NULL
977        AND EXISTS
978          ( SELECT 'x'
979              FROM wms_user_task_type_attributes   wutta
980             WHERE wutta.organization_id = mmtt.organization_id
981               AND wutta.user_task_type_id = mmtt.standard_operation_id
982               AND wutta.honor_case_pick_flag = 'Y'
983          )
984     UNION ALL
985     -- Bulk pick parent tasks
986     SELECT mmtt.transaction_temp_id
987       FROM mtl_material_transactions_temp   mmtt
988      WHERE mmtt.transaction_temp_id IN
989          ( SELECT DISTINCT mmtt2.parent_line_id
990              FROM mtl_material_transactions_temp   mmtt2
991             WHERE mmtt2.move_order_header_id = p_mo_hdr_id
992               AND mmtt2.parent_line_id IS NOT NULL
993               AND mmtt2.transaction_temp_id <> mmtt2.parent_line_id
994          )
995        AND EXISTS
996          ( SELECT 'x'
997              FROM wms_user_task_type_attributes   wutta
998             WHERE wutta.organization_id = mmtt.organization_id
999               AND wutta.user_task_type_id = mmtt.standard_operation_id
1000               AND wutta.honor_case_pick_flag = 'Y'
1001          );
1002 
1003 
1004 BEGIN
1005    -- because the debug profile  rarely changes, only check it once per
1006    -- session, instead of once per batch
1007    IF is_debug IS NULL THEN
1008      l_debug := NVL(FND_PROFILE.VALUE('INV_DEBUG_TRACE'),0);
1009      if l_debug = 1 then
1010        is_debug := TRUE;
1011      else
1012        is_debug := FALSE;
1013      end if;
1014    END IF;
1015 
1016    -- Set savepoint for this API
1017    If is_debug then
1018     print_debug('Inside Pick_Release', 'INV_Pick_Release_Pub.Pick_Release');
1019     print_debug('p_dynamic_replenishment :'||p_dynamic_replenishment, 'INV_Pick_Release_Pub.Pick_Release');
1020    End If;
1021 
1022    l_return_value := inv_cache.set_pick_release(TRUE); --Added for bug3237702
1023    inv_log_util.g_maintain_log_profile := TRUE; -- Bug 5558315 - duplication so no dependency btw inv_cache and inv_log
1024 
1025    SAVEPOINT Pick_Release_PUB;
1026 
1027    -- Standard Call to check for call compatibility
1028    IF NOT fnd_api.Compatible_API_Call(l_api_version , p_api_version , l_api_name , G_PKG_NAME) THEN
1029      If is_debug then
1030       print_debug('Fnd_APi not compatible','INV_Pick_Release_Pub.Pick_Release');
1031      End If;
1032      RAISE fnd_api.g_exc_unexpected_error;
1033    END IF;
1034 
1035    -- Initialize message list if p_init_msg_list is set to true
1036    IF fnd_api.to_Boolean(p_init_msg_list) THEN
1037       fnd_msg_pub.initialize;
1038    END IF;
1039 
1040    -- Initialize API return status to success
1041    x_return_status := fnd_api.g_ret_sts_success;
1042 
1043 
1044    -- Validate parameters
1045 
1046    -- First determine whether the table of move order lines in p_mo_line_tbl has
1047    -- any records
1048    l_mo_line_count := p_mo_line_tbl.COUNT;
1049    IF l_mo_line_count = 0 THEN
1050      If is_debug then
1051        print_debug('No Lines to pick', 'INV_Pick_Release_Pub.Pick_Release');
1052      End If;
1053 
1054       ROLLBACK TO Pick_Release_PUB;
1055       FND_MESSAGE.SET_NAME('INV','INV_NO_LINES_TO_PICK');
1056       FND_MSG_PUB.Add;
1057       RAISE fnd_api.g_exc_unexpected_error;
1058    END IF;
1059 
1060    -- Set move order transaction date if passed in as not NULL
1061    IF p_mo_transact_date <> fnd_api.g_miss_date THEN
1062       inv_cache.mo_transaction_date := p_mo_transact_date;
1063    END IF;
1064 
1065    -- Validate that all move order lines are from the same org, that all lines
1066    -- have a status of pre-approved(7) or approved(3),and that all of the move
1067    -- order lines are of type Pick Wave (3)
1068    l_line_index := l_mo_line_tbl.FIRST;
1069    l_mol_id_index := 1;
1070    l_organization_id := l_mo_line_tbl(l_line_index).organization_id;
1071    LOOP
1072      l_mo_line := l_mo_line_tbl(l_line_index);
1073 
1074      --This clause checks to see if there are multiple headers in this
1075      -- table of move orders.  If there are, we need to sort these lines
1076      -- for cartonization  (see call to sort() below).
1077      if l_first_header_id IS NULL THEN
1078         l_first_header_id := l_mo_line.header_id;
1079      else
1080         IF l_first_header_id <> l_mo_line.header_id THEN
1081           l_multiple_headers := TRUE;
1082         END IF;
1083      end if;
1084 
1085      -- only process the valid move order, fix bug 1540709.
1086      IF (l_mo_line.return_status <> FND_API.G_RET_STS_UNEXP_ERROR and
1087          l_mo_line.return_status <> FND_API.G_RET_STS_ERROR) THEN
1088 
1089       -- Verify that the lines are all for the same organization
1090       IF l_mo_line.organization_id <> l_organization_id THEN
1091         If is_debug then
1092           print_debug('Error: Trying to pick for different org','INV_Pick_Release_Pub.Pick_Release');
1093         End If;
1094 
1095         ROLLBACK TO Pick_Release_PUB;
1096         FND_MESSAGE.SET_NAME('INV','INV_PICK_DIFFERENT_ORG');
1097         FND_MSG_PUB.Add;
1098         RAISE fnd_api.g_exc_unexpected_error;
1099       END IF;
1100 
1101       -- Verify that the line status is approved or pre-approved
1102       IF (l_mo_line.line_status <> 3 AND l_mo_line.line_status <> 7) THEN
1103         If is_debug then
1104           print_debug('Error: Invalid Move Order Line Status','INV_Pick_Release_Pub.Pick_Release');
1105         End If;
1106 
1107         ROLLBACK TO Pick_Release_PUB;
1108         FND_MESSAGE.SET_NAME('INV','INV_PICK_LINE_STATUS');
1109         FND_MSG_PUB.Add;
1110         RAISE fnd_api.g_exc_unexpected_error;
1111       END IF;
1112 
1113       IF l_mo_line.header_id <> l_current_header_id OR
1114          l_current_header_id IS NULL THEN
1115          l_return_value := INV_CACHE.set_mtrh_rec(l_mo_line.header_Id);
1116          If NOT l_return_value Then
1117           If is_debug then
1118              print_debug('Error setting cache for move order header ','INV_Pick_Release_Pub.Pick_Release');
1119           End If;
1120           RAISE fnd_api.g_exc_unexpected_error;
1121          End If;
1122          l_mo_type := INV_CACHE.mtrh_rec.move_order_type;
1123          l_mo_number := INV_CACHE.mtrh_rec.request_number;
1124          l_current_header_id := l_mo_line.header_id;
1125       END IF;
1126 
1127       IF l_mo_type <> 3 THEN
1128         If is_debug then
1129           print_debug('Error: Trying to release non pick wave move order','INV_Pick_Release_Pub.Pick_Release');
1130         End If;
1131 
1132         ROLLBACK TO Pick_Release_PUB;
1133         FND_MESSAGE.SET_NAME('INV','INV_NON_PICK_WAVE_MO');
1134         FND_MESSAGE.SET_TOKEN('MO_NUMBER',l_mo_number);
1135         FND_MSG_PUB.Add;
1136         RAISE fnd_api.g_exc_unexpected_error;
1137       END IF;
1138       l_mol_id_tbl(l_mol_id_index) := l_mo_line.line_id;
1139       l_mol_id_index := l_mol_id_index + 1;
1140     END IF;
1141 
1142     IF NOT l_qtree_item_tbl.exists(l_mo_line.inventory_item_id) THEN
1143       --determine if item is unit-effective or not, and create
1144       --record in item_tbl
1145 
1146       If is_debug then
1147         print_debug('Storing rec in qtree_item_tbl', 'PICKREL');
1148       End If;
1149       --Bug2242924 For ship model Backorder was not happening correctly so
1150       -- create_tree for every line
1151       -- Bug 2363739 - call unit_effective_item instead of enabled
1152       --old: select pjm_unit_eff.enabled into g_pjm_unit_eff_enabled from dual;
1153 
1154       l_qtree_item_tbl(l_mo_line.inventory_item_id).unit_effective :=
1155         pjm_unit_eff.unit_effective_item(
1156           x_item_id => l_mo_line.inventory_item_id
1157          ,x_organization_id => l_organization_id);
1158 
1159       --if item is unit effective control, we have to build one tree for
1160       -- every sales order line.  Create record in line_tbl
1161       If l_qtree_item_tbl(l_mo_line.inventory_item_id).unit_effective =
1162          'Y' Then
1163 
1164         If is_debug then
1165           print_debug('Item is unit effective', 'PICKREL');
1166         End If;
1167         l_qtree_line_tbl(l_mo_line.txn_source_line_id).next_line_rec := 0;
1168         l_qtree_line_tbl(l_mo_line.txn_source_line_id).move_order_line_id :=
1169                 l_mo_line.line_id;
1170         l_qtree_line_tbl(l_mo_line.txn_source_line_id).transaction_type_id :=
1171                 l_mo_line.transaction_type_id;
1172         l_qtree_item_tbl(l_mo_line.inventory_item_id).first_line_rec :=
1173           l_mo_line.txn_source_line_id;
1174         l_qtree_item_tbl(l_mo_line.inventory_item_id).last_line_rec :=
1175           l_mo_line.txn_source_line_id;
1176       End If;
1177 
1178     --item entry already exists, but the item is effective control;
1179     --so, we have to create another entry in line tbl if one does not
1180     -- already exist for this sales order line
1181     ELSIF l_qtree_item_tbl(l_mo_line.inventory_item_id).unit_effective = 'Y'
1182       AND NOT l_qtree_line_tbl.exists(l_mo_line.txn_source_line_id) THEN
1183 
1184       If is_debug then
1185         print_debug('Item is unit effective. Inserting new line rec','PICKREL');
1186       End If;
1187       --make the next record the last one for this item
1188       l_last_rec:=l_qtree_item_tbl(l_mo_line.inventory_item_id).last_line_rec;
1189       l_qtree_line_tbl(l_last_rec).next_line_rec :=
1190                 l_mo_line.txn_source_line_id;
1191       l_qtree_item_tbl(l_mo_line.inventory_item_id).last_line_rec :=
1192                 l_mo_line.txn_source_line_id;
1193 
1194       --initialize values in new line record
1195       l_qtree_line_tbl(l_mo_line.txn_source_line_id).next_line_rec := 0;
1196       l_qtree_line_tbl(l_mo_line.txn_source_line_id).move_order_line_id :=
1197                 l_mo_line.line_id;
1198       l_qtree_line_tbl(l_mo_line.txn_source_line_id).transaction_type_id :=
1199                 l_mo_line.transaction_type_id;
1200 
1201     --IF item is not unit controlled and already exists in item_tbl,
1202     -- or if item is unit eff controlled and line already exists in line tbl,
1203     -- no need to do anything
1204     ELSE
1205       If is_debug then
1206         print_debug('Item/line recs already exist in table','PICKREL');
1207       End If;
1208     END IF;
1209 
1210     EXIT WHEN l_line_index = p_mo_line_tbl.LAST;
1211     l_line_index := p_mo_line_tbl.NEXT(l_line_index);
1212   END LOOP;
1213 
1214   l_item_index := l_qtree_item_tbl.FIRST;
1215   If is_debug then
1216     print_debug('Begin item loop.  First item id:' || l_item_index,
1217         'PICKREL');
1218   End If;
1219 
1220   LOOP
1221     EXIT WHEN l_item_index = 0;
1222     If is_debug then
1223       print_debug('Build quantity tree for item id:' || l_item_index,'PICKREL');
1224     End If;
1225 
1226     BEGIN
1227         SELECT revision_qty_control_code, lot_control_code,
1228                primary_uom_code, NVL(reservable_type,1)
1229           INTO l_revision_control_code, l_lot_control_code,
1230                l_primary_uom_tbl(l_item_index),
1231                l_reservable_type
1232           FROM mtl_system_items
1233          WHERE organization_id = l_organization_id
1234            AND inventory_item_id = l_item_index;
1235     EXCEPTION
1236        WHEN no_data_found THEN
1237            ROLLBACK TO Pick_Release_PUB;
1238            If is_debug then
1239               print_debug('No Item Info found','Inv_Pick_Release_Pub.Pick_Release');
1240            End If;
1241            RAISE fnd_api.g_exc_unexpected_error;
1242     END;
1243 
1244     IF l_revision_control_code = 1 THEN
1245        l_revision_controlled := FALSE;
1246     ELSE
1247        l_revision_controlled := TRUE;
1248     END IF;
1249 
1250     IF l_lot_control_code = 1 THEN
1251       l_lot_controlled := FALSE;
1252     ELSE
1253       l_lot_controlled := TRUE;
1254     END IF;
1255 
1256     -- if not unit effective, build qty tree for item
1257     IF l_qtree_item_tbl(l_item_index).unit_effective = 'N' AND l_reservable_type = 1 THEN
1258          -- Because of the quantity tree rearchitechture, we
1259          -- can pass dummy values for demand source info.
1260          -- Bug 1890424 - Pass sysdate to create_tree so
1261          -- expired lots don't appear as available
1262 
1263           inv_quantity_tree_pvt.create_tree
1264           (
1265             p_api_version_number        => 1.0
1266            ,p_init_msg_lst              => fnd_api.g_false
1267            ,x_return_status             => l_api_return_status
1268            ,x_msg_count                 => x_msg_count
1269            ,x_msg_data                  => x_msg_data
1270            ,p_organization_id           => l_organization_id
1271            ,p_inventory_item_id         => l_item_index
1272            ,p_tree_mode                 => inv_quantity_tree_pvt.g_transaction_mode
1273            ,p_is_revision_control       => l_revision_controlled
1274            ,p_is_lot_control            => l_lot_controlled
1275            ,p_is_serial_control         => FALSE
1276            ,p_asset_sub_only            => FALSE
1277            ,p_include_suggestion        => FALSE
1278            ,p_demand_source_type_id     => -99
1279            ,p_demand_source_header_id   => -99
1280            ,p_demand_source_line_id     => -99
1281            ,p_demand_source_delivery    => NULL
1282            ,p_demand_source_name        => NULL
1283            ,p_lot_expiration_date       => SYSDATE
1284            ,x_tree_id                   => l_tree_id
1285            ,p_exclusive              => inv_quantity_tree_pvt.g_exclusive
1286            ,p_pick_release           => inv_quantity_tree_pvt.g_pick_release_yes
1287          );
1288 
1289          If is_debug then
1290             print_debug('Tree id from Normal Create tree'||l_tree_id,'Inv_Pick_Release_PVT.Process_Line');
1291          End If;
1292 
1293          l_qtree_item_tbl(l_item_index).tree_id := l_tree_id;
1294 
1295          IF l_api_return_status = fnd_api.g_ret_sts_error THEN
1296            RAISE fnd_api.g_exc_error ;
1297          ELSIF l_api_return_status = fnd_api.g_ret_sts_unexp_error THEN
1298            RAISE fnd_api.g_exc_unexpected_error;
1299          END IF;
1300 
1301     --Bug 2500570.If unable to get delivery detail we should not
1302     --error for batch.
1303     ELSIF l_qtree_item_tbl(l_item_index).unit_effective = 'Y' AND
1304           l_reservable_type = 1 THEN
1305       --loop through all lines
1306       l_qtree_line_index := l_qtree_item_tbl(l_item_index).first_line_rec;
1307       Loop
1308         EXIT WHEN l_qtree_line_index = 0;
1309         --get demand information
1310         BEGIN
1311          SELECT SOURCE_HEADER_ID
1312            INTO l_OE_HEADER_ID
1313            FROM wsh_delivery_details
1314           WHERE move_order_line_id =
1315                 l_qtree_line_tbl(l_qtree_line_index).move_order_line_id
1316             AND   move_order_line_id is not NULL
1317             AND released_status = 'S';
1318         EXCEPTION
1319           WHEN others THEN
1320             l_OE_HEADER_ID :=-9999;
1321             If is_debug then
1322               print_debug('No data found-Delivery Info',
1323                     'Inv_Pick_Release_PUB.Pick_release');
1324             End If;
1325             --ROLLBACK TO Pick_Release_PUB;
1326             --FND_MESSAGE.SET_NAME('INV','INV_DELIV_INFO_MISSING');
1327             -- FND_MSG_PUB.Add;
1328             -- RAISE fnd_api.g_exc_unexpected_error;
1329         END;
1330 
1331         l_return_value := INV_CACHE.set_mso_rec(l_oe_header_id);
1332         IF NOT l_return_value THEN
1333            l_mso_header_id :=-9999;
1334            If is_debug then
1335               print_debug('No Mtl_Sales_Order ID found for oe header','Inv_Pick_Release_PUB.Process_Line');
1336            End If;
1337         ELSE
1338            l_mso_header_id := INV_CACHE.mso_rec.sales_order_id;
1339         END IF;
1340 
1341         BEGIN
1342           select t.transaction_source_type_id
1343             into l_demand_source_type
1344             from mtl_transaction_types t, mtl_txn_source_types st
1345            where t.transaction_type_id =
1346                   l_qtree_line_tbl(l_qtree_line_index).transaction_type_id
1347              and t.transaction_source_type_id = st.transaction_source_type_id;
1348         exception
1349           when others then
1350             l_demand_source_type :=-9999;
1351             If is_debug then
1352               print_debug('No data found-Transaction types','Inv_Pick_Release_PVT.Process_Line');
1353             End If;
1354         END;
1355 
1356         inv_quantity_tree_pvt.create_tree
1357          (
1358             p_api_version_number        => 1.0
1359            ,p_init_msg_lst              => fnd_api.g_false
1360            ,x_return_status             => l_api_return_status
1361            ,x_msg_count                 => x_msg_count
1362            ,x_msg_data                  => x_msg_data
1363            ,p_organization_id           => l_organization_id
1364            ,p_inventory_item_id         => l_item_index
1365            ,p_tree_mode                 => inv_quantity_tree_pvt.g_reservation_mode
1366            ,p_is_revision_control       => l_revision_controlled
1367            ,p_is_lot_control            => l_lot_controlled
1368            ,p_is_serial_control         => FALSE
1369            ,p_asset_sub_only            => FALSE
1370            ,p_include_suggestion        => FALSE
1371            ,p_demand_source_type_id     => l_demand_source_type
1372            ,p_demand_source_header_id   => l_mso_header_id
1373            ,p_demand_source_line_id     => l_qtree_line_index
1374            ,p_demand_source_delivery    => NULL
1375            ,p_demand_source_name        => NULL
1376            ,p_lot_expiration_date       => SYSDATE
1377            ,x_tree_id                   => l_tree_id
1378            ,p_exclusive                 => inv_quantity_tree_pvt.g_exclusive
1379            ,p_pick_release          => inv_quantity_tree_pvt.g_pick_release_yes
1380          );
1381          If is_debug then
1382            print_debug('Tree id from PJM Create tree'||l_tree_id,'Inv_Pick_Release_PVT.Process_Line');
1383          End If;
1384 
1385          l_qtree_line_tbl(l_qtree_line_index).tree_id := l_tree_id;
1386 
1387          IF l_api_return_status = fnd_api.g_ret_sts_error THEN
1388            If is_debug then
1389              print_debug('Error from Create tree','Inv_pick_release_pub.Pick_release');
1390            End If;
1391            RAISE fnd_api.g_exc_error ;
1392          ELSIF l_api_return_status = fnd_api.g_ret_sts_unexp_error THEN
1393            If is_debug then
1394              print_debug('Unexpected error from Create tree','Inv_pick_release_pub.Pick_release');
1395            End If;
1396            RAISE fnd_api.g_exc_unexpected_error;
1397          END IF;
1398 
1399          l_qtree_line_index :=
1400              l_qtree_line_tbl(l_qtree_line_index).next_line_rec;
1401        End Loop; --End of loop through order lines
1402 
1403      END IF; -- unit effective
1404 
1405      EXIT WHEN l_item_index = l_qtree_item_tbl.LAST;
1406      l_item_index := l_qtree_item_tbl.NEXT(l_item_index);
1407    END LOOP;
1408 
1409    -- now sort the move order line by the header_id
1410    --BENCHMARK - check cache
1411    --l_wms_installed := inv_install.adv_inv_installed(
1412    --            l_mo_line_tbl(l_line_index).organization_id);
1413    l_return_value := INV_CACHE.set_wms_installed(l_organization_id);
1414    If NOT l_return_value Then
1415       If is_debug then
1416           print_debug('Error setting cache for wms installed','INV_Pick_Release_Pub.Pick_Release');
1417       End If;
1418       RAISE fnd_api.g_exc_unexpected_error;
1419    End If;
1420    l_wms_installed := INV_CACHE.wms_installed;
1421    --sort only necessary if wms installed and multiple headers in the
1422    --    line_tbl
1423    IF l_wms_installed and l_multiple_headers THEN
1424       sort(l_mo_line_tbl, l_mo_line_tbl.FIRST, l_mo_line_tbl.LAST);
1425    END IF;
1426 
1427    -- Determine whether or not to automatically pick confirm
1428    IF p_auto_pick_confirm IS NOT NULL THEN
1429       IF (p_auto_pick_confirm <> 1 AND p_auto_pick_confirm <> 2) THEN
1430         If is_debug then
1431          print_debug('Error: Invalid auto_pick_confirm flag','INV_Pick_Release_Pub.Pick_Release');
1432         End If;
1433         ROLLBACK TO Pick_Release_PUB;
1434         FND_MESSAGE.SET_NAME('INV','INV_AUTO_PICK_CONFIRM_PARAM');
1435         FND_MSG_PUB.Add;
1436         RAISE fnd_api.g_exc_unexpected_error;
1437       ELSE
1438         l_auto_pick_confirm := p_auto_pick_confirm;
1439       END IF;
1440    ELSE
1441       -- Retrieve the org-level parameter for auto-pick confirm
1442       l_return_value := INV_CACHE.set_org_rec(l_organization_id);
1443       If NOT l_return_value Then
1444           If is_debug then
1445              print_debug('Error setting cache for organization',
1446                       'INV_Pick_Release_Pub.Pick_Release');
1447           End If;
1448 	  RAISE fnd_api.g_exc_unexpected_error;
1449       End If;
1450       l_auto_pick_confirm:= INV_CACHE.org_rec.mo_pick_confirm_required;
1451    END IF;
1452 
1453    -- Determine what printing mode to use when pick releasing lines.
1454    IF g_organization_id IS NOT NULL AND
1455       g_organization_id = l_organization_id AND
1456       g_print_mode IS NOT NULL THEN
1457 
1458      l_print_mode := g_print_mode;
1459    ELSE
1460 
1461     BEGIN
1462       SELECT print_pick_slip_mode, pick_grouping_rule_id
1463       INTO l_print_mode, g_org_grouping_rule_id
1464       FROM WSH_SHIPPING_PARAMETERS
1465       WHERE organization_id = l_organization_id;
1466     EXCEPTION
1467       WHEN no_data_found THEN
1468         If is_debug then
1469           print_debug('Error: print_pick_slip_mode not defined','INV_Pick_Release_Pub.Pick_Release');
1470         End If;
1471         ROLLBACK TO Pick_Release_PUB;
1472         FND_MESSAGE.SET_NAME('INV','INV_WSH_ORG_NOT_FOUND');
1473         FND_MSG_PUB.Add;
1474         RAISE fnd_api.g_exc_unexpected_error;
1475     END;
1476 
1477      g_organization_id := l_organization_id;
1478      g_print_mode := l_print_mode;
1479    END IF;
1480 
1481    -- Validate parameter for allowing partial pick release
1482    IF p_allow_partial_pick <> fnd_api.g_true AND
1483       p_allow_partial_pick <> fnd_api.g_false THEN
1484 
1485       If is_debug then
1486         print_debug('Error: invalid partial pick parameter','INV_Pick_Release_Pub.Pick_Release');
1487       End If;
1488       ROLLBACK TO Pick_Release_PUB;
1489       FND_MESSAGE.SET_NAME('INV','INV_INVALID_PARTIAL_PICK_PARAM');
1490       FND_MSG_PUB.Add;
1491       RAISE fnd_api.g_exc_unexpected_error;
1492    END IF;
1493 
1494    If is_debug then
1495      print_debug('p_allow_partial_pick is ' || p_allow_partial_pick,'Inv_Pick_Release_Pub.Pick_Release');
1496    End If;
1497 
1498    -- The Move Order Lines may need to have their grouping rule ID defaulted
1499    -- from the header.  This is only necessary if the Grouping Rule ID was not
1500    -- passed in as a parameter.
1501    IF p_grouping_rule_id IS NOT NULL AND p_grouping_rule_id <> fnd_api.G_MISS_NUM THEN
1502       l_grouping_rule_id := p_grouping_rule_id;
1503       l_get_header_rule := 2;
1504    ELSE
1505       l_get_header_rule := 1;
1506    END IF;
1507 
1508    -- Bug# 4258360: Query for and cache the picking batch record.
1509    -- Even if multiple move order headers are created for this batch (not likely),
1510    -- they should all refer to the same picking batch record.  A value for the move
1511    -- order header record should be cached by now in INV_CACHE.  'Batch' refers to
1512    -- the set of MOL's passed into the pick release API and not the entire set of pick
1513    -- release lines.
1514    -- {{
1515    -- Pick Release a batch such that you have orders from multiple
1516    -- organizations. This will cause multiple MOH to be created.
1517    -- If successfully pick released, then no bug.
1518    -- }}
1519    IF (NOT INV_CACHE.set_wpb_rec
1520        (p_batch_id       => NULL,
1521         p_request_number => INV_CACHE.mtrh_rec.request_number)) THEN
1522       IF (is_debug) THEN
1523          print_debug('Error setting cache for WSH picking batch record','INV_Pick_Release_Pub.Pick_Release');
1524       END IF;
1525       RAISE fnd_api.g_exc_unexpected_error;
1526    END IF;
1527    -- Set the allocation method variable
1528    l_allocation_method := NVL(INV_CACHE.wpb_rec.allocation_method, g_inventory_only);
1529 
1530    -- Bug# 4258360: Validate that p_trolin_delivery_ids and p_del_detail_id tables have the
1531    -- same number of entries.  There should be a one to one relationship between the tables
1532    -- and the indices used.  If NULL tables are passed, the counts should still match (0 = 0).
1533    -- NULL empty tables should be passed by Shipping for this.  These tables are used to store
1534    -- crossdocked WDD lines so deliveries can be created for them.
1535    IF (p_del_detail_id.COUNT <> p_trolin_delivery_ids.COUNT) THEN
1536       IF (is_debug) THEN
1537          print_debug('Mismatch in size of input tables from Shipping for delivery creation','INV_Pick_Release_Pub.Pick_Release');
1538       END IF;
1539       RAISE fnd_api.g_exc_unexpected_error;
1540    END IF;
1541 
1542    -- Bug# 4258360: Loop through p_wsh_release_table to build the index pointer table to it.
1543    -- Do this only if p_wsh_release_table has entries in it.  Crossdocking will be called after
1544    -- Inventory allocation has completed.  Since it makes use of the release table, we need to keep
1545    -- that updated and in sync.  We also want to update any backordered lines in the release table
1546    -- so Shipping can know which lines were backordered and not auto-create deliveries for them.
1547    -- UPDATE: Do not need to insert lines into the delivery tables for Prioritize Crossdock.
1548    -- Since Shipping is not populating the delivery tables inputted, they will just be used to store
1549    -- the crossdocked WDD lines.  The crossdock pegging API will now insert the crossdocked WDD lines
1550    -- into these delivery tables.
1551    -- {{
1552    -- Run PR in Prioritize Inventory mode. Ensure that some rows get
1553    -- allocated from INV and some get x-docked. The ones that got
1554    -- allocated from INV should not get x-docked.
1555    -- }}
1556    -- {{
1557    -- Run PR in Prioritize x-dock mode. Ensure that no deliveries are
1558    -- created prior to running PR. Also ensure some WDDs get x-docked
1559    -- and some get allocated from INV. All these WDDs should have deliveries
1560    -- created at the end of PR run.
1561    -- }}
1562    IF (p_wsh_release_table.COUNT > 0) THEN
1563       l_line_index := p_wsh_release_table.FIRST;
1564       l_wdd_index_tbl.DELETE;
1565       IF (is_debug) THEN
1566 	 print_debug('Build the WDD index pointer table (Prioritize Inventory)',
1567 		     'Inv_Pick_Release_Pub.Pick_Release');
1568       END IF;
1569       LOOP
1570 	 -- Store this WDD record into the WDD index pointer table
1571 	 l_wdd_index_tbl(p_wsh_release_table(l_line_index).delivery_detail_id) := l_line_index;
1572 
1573 	 EXIT WHEN l_line_index = p_wsh_release_table.LAST;
1574 	 l_line_index := p_wsh_release_table.NEXT(l_line_index);
1575       END LOOP;
1576    END IF;
1577 
1578      if l_wms_installed then -- 14781148
1579 	IF (is_debug) THEN
1580 	print_debug('Before calling the update_wave_lines_tbl ','Inv_Pick_Release_Pub.Pick_Release');
1581 	END IF;
1582 
1583 	wms_wave_planning_pvt.update_wave_lines_tbl( p_mo_line_table => l_mo_line_tbl
1584 	                               		,x_return_status => l_return_status);
1585 
1586 	IF (l_return_status <> fnd_api.g_ret_sts_success) THEN
1587 		IF (l_debug = 1) THEN
1588 		print_debug('After calling the update_wave_lines_tbl which has returned error - Still Continue with rest of Pick Release','Inv_Pick_Release_Pub.Pick_Release');
1589 		END IF;
1590 	END IF;
1591 
1592 	IF (is_debug) THEN
1593 	print_debug('After calling the update_wave_lines_tbl ','Inv_Pick_Release_Pub.Pick_Release');
1594 	END IF;
1595      end if; -- 14781148
1596 
1597 
1598    -- Validation and initialization complete.  Begin pick release processing row-by-row.
1599    l_line_index := l_mo_line_tbl.FIRST;
1600    l_organization_id := l_mo_line.organization_id;
1601    LOOP
1602     l_mo_line := l_mo_line_tbl(l_line_index);
1603       -- only process the valid move order, fix bug 1540709.
1604     IF (l_mo_line.return_status <> FND_API.G_RET_STS_UNEXP_ERROR and
1605           l_mo_line.return_status <> FND_API.G_RET_STS_ERROR) THEN
1606       -- First retrieve the new Grouping Rule ID if necessary.
1607       IF l_get_header_rule = 1 THEN
1608 	l_return_value := INV_CACHE.set_mtrh_rec(l_mo_line.header_id);
1609 	If NOT l_return_value Then
1610           If is_debug then
1611              print_debug('Error setting cache for move order header ',
1612                       'INV_Pick_Release_Pub.Pick_Release');
1613           End If;
1614 	  RAISE fnd_api.g_exc_unexpected_error;
1615 	End If;
1616 	l_grouping_rule_id := INV_CACHE.mtrh_rec.grouping_rule_id;
1617 
1618 	-- If the header did not have a grouping rule ID, retrieve it from
1619 	-- the organization-level default.
1620 	IF l_grouping_rule_id IS NULL THEN
1621 	  If g_organization_id IS NOT NULL And
1622              g_organization_id = l_organization_id And
1623 	     g_org_grouping_rule_id IS NOT NULL Then
1624 
1625 	    l_grouping_rule_id := g_org_grouping_rule_id;
1626 
1627 	  Else
1628 	    BEGIN
1629 	      SELECT pick_grouping_rule_id
1630 	      INTO l_grouping_rule_id
1631 	      FROM wsh_shipping_parameters
1632 	      WHERE organization_id = l_organization_id;
1633       	    EXCEPTION
1634 	      WHEN no_data_found THEN
1635 	        If is_debug then
1636 		  print_debug('Error finding org grouping rules',
1637 			 'INV_Pick_Release_Pub.Pick_Release');
1638 		End If;
1639 	        ROLLBACK TO Pick_Release_PUB;
1640       	        FND_MESSAGE.SET_NAME('INV','INV-NO ORG INFORMATION');
1641 	        FND_MSG_PUB.Add;
1642 	        RAISE fnd_api.g_exc_unexpected_error;
1643 	    END;
1644 
1645 	    If g_organization_id IS NULL Or
1646  	       g_organization_id <> l_organization_id Then
1647 	      g_organization_id := l_organization_id;
1648 	      -- null out other org based global variables
1649 	      g_print_mode := NULL;
1650 	    End If;
1651 
1652  	    g_org_grouping_rule_id := l_grouping_rule_id;
1653 	  End If;
1654 
1655 	END IF; -- get header rule
1656       END IF; -- return status
1657 
1658 
1659       IF l_mo_line.ship_set_id IS NOT NULL AND
1660 	  (l_cur_ship_set_id IS NULL OR
1661 	   l_cur_ship_set_id <> l_mo_line.ship_set_id) THEN
1662 
1663          SAVEPOINT SHIPSET;
1664 	 l_cur_ship_set_id := l_mo_line.ship_set_id;
1665 	 l_start_index := l_line_index;
1666          l_start_process := l_processed_row_count;
1667          l_qtree_backup_tbl.DELETE;
1668          If is_debug then
1669 	   print_debug('Start Shipset :' || l_cur_ship_set_id,
1670 	              'Inv_Pick_Release_Pub.Pick_Release');
1671 	 End If;
1672       ELSIF l_cur_ship_set_id IS NOT NULL AND
1673 	    l_mo_line.ship_set_id IS NULL THEN
1674         If is_debug then
1675 	  print_debug('End of Shipset :' || l_cur_ship_set_id,
1676 	              'Inv_Pick_Release_Pub.Pick_Release');
1677 	End If;
1678 	 l_cur_ship_set_id := NULL;
1679          l_qtree_backup_tbl.DELETE;
1680       END IF;
1681       --2509322
1682       IF  l_cur_ship_model_id IS NOT NULL AND
1683           l_mo_line.ship_model_id IS NULL OR
1684           l_mo_line.ship_model_id <>l_cur_ship_model_id then
1685            Backorder_SMC_DETAILS(l_api_return_status ,
1686                                 x_msg_data ,
1687                                 x_msg_count ) ;
1688          IF l_api_return_status = fnd_api.g_ret_sts_error THEN
1689            RAISE fnd_api.g_exc_error ;
1690          ELSIF l_api_return_status = fnd_api.g_ret_sts_unexp_error THEN
1691            RAISE fnd_api.g_exc_unexpected_error;
1692          END IF;
1693       END IF;
1694 
1695       IF l_mo_line.ship_model_id IS NOT NULL AND
1696 	  (l_cur_ship_model_id IS NULL OR
1697 	   l_cur_ship_model_id <> l_mo_line.ship_model_id) THEN
1698 
1699          SAVEPOINT SHIPMODEL;
1700 	 l_cur_ship_model_id := l_mo_line.ship_model_id;
1701 	 l_start_index := l_line_index;
1702          l_start_process := l_processed_row_count;
1703          l_qtree_backup_tbl.DELETE;
1704          If is_debug then
1705 	   print_debug('Start Ship Model :' || l_cur_ship_model_id,
1706 	              'Inv_Pick_Release_Pub.Pick_Release');
1707          End If;
1708       ELSIF l_cur_ship_model_id IS NOT NULL AND
1709 	    l_mo_line.ship_model_id IS NULL THEN
1710          If is_debug then
1711 	   print_debug('End of Ship Model :' || l_cur_ship_model_id,
1712 	              'Inv_Pick_Release_Pub.Pick_Release');
1713          End If;
1714 	 l_cur_ship_model_id := NULL;
1715          l_qtree_backup_tbl.DELETE;
1716       END IF;
1717 
1718       IF (l_mo_line.ship_set_id IS NOT NULL OR
1719 	  l_mo_line.ship_model_id IS NOT NULL)     THEN
1720 
1721         --find tree id.  If item is unit effective, get tree id from
1722         -- qtree_line_tbl.  Else, get it from qtree_item_tbl.
1723         If l_qtree_item_tbl(l_mo_line.inventory_item_id).unit_effective='Y'
1724          Then
1725           l_tree_id := l_qtree_line_tbl(l_mo_line.txn_source_line_id).tree_id;
1726         Else
1727           l_tree_id := l_qtree_item_tbl(l_mo_line.inventory_item_id).tree_id;
1728         End If;
1729 
1730         --only backup the tree if it is not already backed up
1731         If Not l_qtree_backup_tbl.Exists(l_tree_id) Then
1732           If is_debug then
1733             print_debug('Backing up qty tree: ' || l_tree_id,
1734                         'Inv_Pick_Release_Pub.Pick_Release');
1735           End If;
1736           --Bug 2814919
1737           if l_tree_id is not null then
1738             inv_quantity_tree_pvt.backup_tree(
1739               x_return_status   => l_api_return_status
1740              ,p_tree_id         => l_tree_id
1741 	     ,x_backup_id	=> l_backup_id
1742 	    );
1743 
1744            IF l_api_return_status = fnd_api.g_ret_sts_error THEN
1745              RAISE fnd_api.g_exc_error ;
1746            ELSIF l_api_return_status = fnd_api.g_ret_sts_unexp_error THEN
1747              RAISE fnd_api.g_exc_unexpected_error;
1748            END IF;
1749 	  End If;
1750 
1751           --Bug 2814919
1752 	  if l_tree_id is not null then
1753             l_qtree_backup_tbl(l_tree_id) := l_backup_id;
1754 	  End if;
1755 
1756         End If;
1757 
1758       END IF; -- shipset/ship model NOT NULL
1759 
1760       -- Need to keep track of the quantity allocated so far for this
1761       --  sales order - there can be multiple move orders per
1762       -- sales order line, and when dealing with ship model complete,
1763       -- the quantity requested and quantity allocated for the
1764       -- sales order line is important
1765       IF l_cur_txn_source_line_id IS NULL OR
1766          l_mo_line.txn_source_line_id <> l_cur_txn_source_line_id THEN
1767 
1768          l_cur_txn_source_line_id := l_mo_line.txn_source_line_id;
1769          l_cur_txn_source_qty := 0;
1770          -- HW INVCONV Added Qty2
1771          l_cur_txn_source_qty2 := 0;
1772          If is_debug then
1773             print_debug('Set Current Txn Src Line:' || l_cur_txn_source_line_id,'Inv_Pick_Release_Pub.Pick_Release');
1774          End If;
1775       END IF;
1776 
1777       g_pick_expired_lots := FALSE;
1778       g_pick_expired_lots := USER_PKG_LOT.use_expired_lots (
1779                              p_organization_id            => l_mo_line.organization_id
1780                            , p_inventory_item_id          => l_mo_line.inventory_item_id
1781                            , p_demand_source_type_id      => l_mo_line.transaction_source_type_id
1782                            , p_demand_source_line_id      => l_mo_line.txn_source_line_id
1783                              );
1784 
1785       -- Call the Pick Release Process_Line API on the current Move Order Line
1786       If is_debug then
1787         print_debug('calling INV_Pick_Release_PVT.process_line',
1788         'Inv_Pick_Release_Pub.Pick_Release');
1789       End If;
1790 
1791       INV_Pick_Release_PVT.Process_Line(
1792        p_api_version	=> 1.0
1793       ,p_init_msg_list	=> fnd_api.g_false
1794       ,p_commit		=> fnd_api.g_false
1795       ,x_return_status     => l_api_return_status
1796          ,x_msg_count         => x_msg_count
1797          ,x_msg_data          => x_msg_data
1798          ,p_mo_line_rec       => l_mo_line
1799       ,p_grouping_rule_id	=> l_grouping_rule_id
1800       ,p_allow_partial_pick => p_allow_partial_pick
1801       ,p_print_mode        => l_print_mode
1802       ,x_detail_rec_count	=> l_detail_rec_count
1803            ,p_plan_tasks        => p_plan_tasks
1804       );
1805 
1806       If is_debug then
1807         print_debug('l_return_status from process_line is '|| l_api_return_status, 'Inv_Pick_Release_Pub.Pick_Release');
1808       End If;
1809 
1810       IF l_api_return_status <> fnd_api.g_ret_sts_success THEN
1811          -- Return error if Process_Line returns error and
1812          -- allow_partial_pick is false, since we can't pick full quantity
1813          IF p_allow_partial_pick = fnd_api.g_false THEN
1814            x_pick_release_status.delete;
1815            ROLLBACK TO Pick_Release_PUB;
1816                 FND_MESSAGE.SET_NAME('INV','INV_COULD_NOT_PICK_FULL');
1817            FND_MSG_PUB.Add;
1818            RAISE fnd_api.g_exc_unexpected_error;
1819          END IF;
1820       END IF;
1821 
1822       l_quantity := l_mo_line.quantity;
1823       -- HW INVCONV Added Qty2
1824       l_quantity2 := l_mo_line.secondary_quantity;
1825       l_line_status := l_mo_line.line_status;
1826       l_quantity_delivered := l_mo_line.quantity_delivered;
1827       l_quantity2_delivered := l_mo_line.secondary_quantity_delivered;
1828 
1829       -- For non reservable items this status is set to 5 in
1830       -- process_line API and the below processing should not be done
1831 
1832       IF l_line_status <> 5 THEN
1833 	 --BENCHMARK - can we use quantity detailed, or perhaps
1834 	 --quantity detailed - quantity delivered
1835 
1836 	 --select nvl(sum(transaction_quantity),0)
1837 	 --into l_transaction_quantity
1838 	 --from mtl_material_transactions_Temp
1839 	 --where move_order_line_id = l_mo_line.line_id;
1840 
1841 	 l_transaction_quantity := nvl(l_mo_line.quantity_detailed,0) -
1842 	                           nvl(l_mo_line.quantity_delivered,0);
1843 	 l_cur_txn_source_qty := nvl(l_cur_txn_source_qty,0) + nvl(l_transaction_quantity,0);
1844 
1845 	 -- HW INVCONV Added Qty2
1846 	 l_transaction_quantity2 := nvl(l_mo_line.secondary_quantity_detailed,0) -
1847 	                            nvl(l_mo_line.secondary_quantity_delivered,0);
1848 	 l_cur_txn_source_qty2 := nvl(l_cur_txn_source_qty2,0) + nvl(l_transaction_quantity2,0);
1849 
1850         IF (l_mo_line.required_quantity IS NOT NULL) THEN
1851             l_quantity :=l_mo_line.required_quantity;
1852         END IF;
1853 
1854         If is_debug then
1855             print_debug('l_quantity '|| l_quantity, 'Inv_Pick_Release_Pub.Pick_Release');
1856             print_debug('l_line_status '|| l_line_status, 'Inv_Pick_Release_Pub.Pick_Release');
1857             print_debug('l_quantity_delivered '|| l_quantity_delivered, 'Inv_Pick_Release_Pub.Pick_Release');
1858             print_debug('l_transaction_quantity '|| l_transaction_quantity, 'Inv_Pick_Release_Pub.Pick_Release');
1859             print_debug('l_cur_txn_source_qty '|| l_cur_txn_source_qty, 'Inv_Pick_Release_Pub.Pick_Release');
1860            print_debug('l_quantity2_delivered '|| l_quantity2_delivered, 'Inv_Pick_Release_Pub.Pick_Release');
1861             print_debug('l_transaction_quantity2 '|| l_transaction_quantity2, 'Inv_Pick_Release_Pub.Pick_Release');
1862             print_debug('l_cur_txn_source_qty2 '|| l_cur_txn_source_qty2, 'Inv_Pick_Release_Pub.Pick_Release');
1863 	    print_debug('l_cur_ship_set_id '|| l_cur_ship_set_id, 'Inv_Pick_Release_Pub.Pick_Release');
1864             print_debug('p_dynamic_replenishment :'||p_dynamic_replenishment,'INV_Pick_Release_Pub.Pick_Release');
1865         end if;
1866 
1867 	 -- If the total allocated quantity is less than the requested
1868 	 -- quantity, call shipping to backorder the missing quantity.
1869 	 -- Update the move order line to change the requested quantity
1870 	 -- to be equal to the allocated quantity
1871 
1872          -- Get the tolerance set while allocating the line
1873          -- If quantity is within tolerance then do not backorder shipset
1874          --
1875          -- l_lower_tolerance := l_quantity * inv_pick_release_pvt.g_min_tolerance;
1876          -- Bug 5188796: g_min_tolerance is a qty, not a %, so use as is
1877          l_lower_tolerance := inv_pick_release_pvt.g_min_tolerance;
1878 	 l_lower_tolerance2 := inv_pick_release_pvt.g_min_tolerance2;
1879 
1880 		 --MUOM Fulfillment Project
1881 			inv_utilities.get_inv_fulfillment_base(
1882 			p_source_line_id		=> l_mo_line.txn_source_line_id,
1883 			p_demand_source_type_id	=> l_mo_line.transaction_source_type_id,
1884 			p_org_id				=> l_mo_line.organization_id,
1885 			x_fulfillment_base		=> l_fulfill_base
1886 			);
1887    --
1888     If is_debug then
1889       print_debug('l_lower_tolerance '|| l_lower_tolerance, 'Inv_Pick_Release_Pub.Pick_Release');
1890       print_debug('l_lower_tolerance2 '|| l_lower_tolerance2, 'Inv_Pick_Release_Pub.Pick_Release');
1891       print_debug('l_fulfill_base '|| l_fulfill_base, 'Inv_Pick_Release_Pub.Pick_Release');
1892    end if ;
1893  --
1894 	 -- Bug #2748751
1895 	 -- If move order is partially transacted and the allocations are split
1896 	 -- again, the allocated quantity will be lesser than move order quantity
1897 	 -- In that case, we need to compare the allocated quantity against the
1898 	 -- difference of move order requested quantity and delivered quantity
1899 	 --MUOM Fulfillemnt Project
1900 	 IF (((l_transaction_quantity < (l_quantity - NVL(l_quantity_delivered,0) - l_lower_tolerance)) and l_fulfill_base<>'S')
1901 			or ((l_transaction_quantity2 < (l_quantity2 - NVL(l_quantity2_delivered,0) - l_lower_tolerance2)) and l_fulfill_base='S')) THEN
1902 
1903 	    -- For shipsets, if any of the lines fail to allocate completely,
1904 	    -- rollback all allocations and then back order all of the
1905 	    -- move order lines for that ship set.
1906             If is_debug then
1907               print_debug('l_cur_ship_set_id:'||l_cur_ship_set_id,'Inv_Pick_Release_Pub.Pick_Release');
1908               print_debug('l_cur_ship_model_id:'||l_cur_ship_model_id  ,'Inv_Pick_Release_Pub.Pick_Release');
1909               print_debug('g_pick_release_caller :'||g_pick_release_caller,'Inv_Pick_Release_Pub.Pick_Release');
1910             end if;
1911 	    IF ( l_cur_ship_set_id IS NOT NULL AND NVL(g_pick_release_caller,'###') <> 'WMS-PICK-EXCEPTION') THEN --9556463
1912 
1913 	       -- Bug 2461353, 2411016
1914 	       -- Call Shipping and let them know for a ship set we were not able
1915 	       -- to detail complete so back ordering started.
1916 
1917 	       BEGIN
1918 		  If is_debug then
1919 		     print_debug('Update shipping that ship set detailing failed',
1920 				 'Inv_Pick_Release_Pub.Pick_Release');
1921 		  End If;
1922 
1923 		  l_shipset_smc_backorder_rec.move_order_line_id:=l_mo_line.line_id;
1924 		  l_shipset_smc_backorder_rec.ship_set_id :=l_cur_ship_set_id;
1925 
1926 
1927 		  wsh_integration.ins_backorder_ss_smc_rec
1928 		    (p_api_version_number => 1.0,
1929 		     p_source_code        => 'INV',
1930 		     p_init_msg_list      => fnd_api.g_false,
1931 		     p_backorder_rec      => l_shipset_smc_backorder_rec,
1932 		     x_return_status      => l_api_return_status,
1933 		     x_msg_count          => x_msg_count,
1934 		     x_msg_data           => x_msg_data);
1935 
1936 		  IF l_api_return_status <> fnd_api.g_ret_sts_success THEN
1937 		     If is_debug then
1938 			print_debug('Error occured while updating shipping for ' ||
1939 				    'failed ship set','Inv_Pick_Release_Pub.Pick_Release');
1940 			print_debug('l_return_status' || l_api_return_status,
1941 				    'Inv_Pick_Release_Pub.Pick_Release');
1942 		     End If;
1943 		  END IF;
1944 
1945 	       EXCEPTION
1946 		  WHEN OTHERS THEN
1947 		     If is_debug then
1948 			print_debug('When other exception: ' || Sqlerrm,
1949 				    'Inv_Pick_Release_Pub.Pick_Release');
1950 			print_debug('l_return_status' || l_api_return_status,
1951 			'Inv_Pick_Release_Pub.Pick_Release');
1952 		     End If;
1953 		     NULL;
1954 		     --no need to error out for reporting purpose.
1955 	       END;
1956 
1957 	       If is_debug then
1958 		  print_debug('Rollback for shipset :' || l_cur_ship_set_id,
1959 			      'Inv_Pick_Release_Pub.Pick_Release');
1960 	       End If;
1961 
1962 	       ROLLBACK to SHIPSET;
1963 	       l_set_index := l_start_index;
1964 	       l_set_process := l_start_process;
1965 
1966 	       --loop through all move order lines for this ship set
1967 	       LOOP
1968 		  l_mo_line := l_mo_line_tbl(l_set_index);
1969 
1970 		  --find tree id.  If item is unit effective, get tree id from
1971 		  -- qtree_line_tbl.  Else, get it from qtree_item_tbl.
1972 		  IF l_qtree_item_tbl(l_mo_line.inventory_item_id).unit_effective='Y'
1973 		    THEN
1974 		     l_tree_id :=
1975 		       l_qtree_line_tbl(l_mo_line.txn_source_line_id).tree_id;
1976 		   ELSE
1977 		     l_tree_id :=
1978 		       l_qtree_item_tbl(l_mo_line.inventory_item_id).tree_id;
1979 		  END IF;
1980 
1981 		  -- only restore tree if it is currently in backup table.
1982 		  -- Tree would not be in backup table if current move order line
1983 		  -- was not allocated or if the tree had already been restored
1984 		  -- for a previous move order line.
1985 		  IF l_qtree_backup_tbl.EXISTS(l_tree_id) THEN
1986 
1987 		     If is_debug then
1988 			print_debug('Restoring Quantity Tree: ' || l_tree_id,
1989 				    'Inv_Pick_Release_Pub.Pick_Release');
1990 		     End If;
1991 
1992 		     inv_quantity_tree_pvt.restore_tree
1993 		       (x_return_status  => l_api_return_status
1994 			,p_tree_id       => l_tree_id
1995 			,p_backup_id     => l_qtree_backup_tbl(l_tree_id)
1996 			);
1997 
1998 		     if( l_api_return_status = FND_API.G_RET_STS_ERROR ) then
1999 			If is_debug then
2000 			   print_debug('Error in Restore_Tree',
2001 				       'Inv_Pick_Release_Pub.Pick_Release');
2002 			End If;
2003 			raise FND_API.G_EXC_ERROR;
2004 		      elsif l_api_return_status=FND_API.G_RET_STS_UNEXP_ERROR then
2005 			If is_debug then
2006 			   print_debug('Unexpected error in Restore_tree',
2007 				       'Inv_Pick_Release_Pub.Pick_Release');
2008 			End If;
2009 			raise FND_API.G_EXC_UNEXPECTED_ERROR;
2010 		     end if;
2011 
2012 		     --delete entry, so we don't restore tree more than once
2013 		     l_qtree_backup_tbl.DELETE(l_tree_id);
2014 
2015 		  END IF;
2016 
2017 		  If is_debug then
2018 		     print_debug('Backorder mo line:' || l_mo_line.line_id,
2019 				 'Inv_Pick_Release_Pub.Pick_Release');
2020 		  End If;
2021 
2022 		  l_return_value := INV_CACHE.set_wdd_rec(l_mo_line.line_id);
2023 		  If NOT l_return_value Then
2024 		     If is_debug then
2025 			print_debug('Error setting cache for delivery line',
2026 				    'INV_Pick_Release_Pub.Pick_Release');
2027 		     End If;
2028 		     RAISE fnd_api.g_exc_unexpected_error;
2029 		  End If;
2030 		  l_delivery_detail_id := INV_CACHE.wdd_rec.delivery_detail_id;
2031 		  l_source_header_id := INV_CACHE.wdd_rec.source_header_id;
2032 		  l_source_line_id := INV_CACHE.wdd_rec.source_line_id;
2033 		  l_released_status := INV_CACHE.wdd_rec.released_status;
2034 
2035 
2036 		  --Call Update_Shipping_Attributes to backorder detail line
2037 		  l_shipping_attr(1).source_header_id := l_source_header_id;
2038 		  l_shipping_attr(1).source_line_id := l_source_line_id;
2039 		  l_shipping_attr(1).ship_from_org_id := l_mo_line.organization_id;
2040 		  l_shipping_attr(1).released_status := l_released_status;
2041 		  l_shipping_attr(1).delivery_detail_id := l_delivery_detail_id;
2042 		  l_shipping_attr(1).action_flag := 'B';
2043 		  l_shipping_attr(1).cycle_count_quantity := l_mo_line.quantity;
2044 		  -- HW INVCONV Added Qty2
2045 		  l_shipping_attr(1).cycle_count_quantity2 := l_mo_line.secondary_quantity;
2046 		  l_shipping_attr(1).subinventory := l_mo_line.from_subinventory_code;
2047 		  l_shipping_attr(1).locator_id := l_mo_line.from_locator_id;
2048 
2049 
2050 		  WSH_INTERFACE.Update_Shipping_Attributes
2051 		    (p_source_code               => 'INV',
2052 		     p_changed_attributes        => l_shipping_attr,
2053 		     x_return_status             => l_api_return_status
2054 		     );
2055 		  if( l_api_return_status = FND_API.G_RET_STS_ERROR ) then
2056 		     If is_debug then
2057 			print_debug('return error from update shipping attributes',
2058 				    'Inv_Pick_Release_Pub.Pick_Release');
2059 		     End If;
2060 		     raise FND_API.G_EXC_ERROR;
2061 		   elsif l_api_return_status = FND_API.G_RET_STS_UNEXP_ERROR then
2062 		     If is_debug then
2063 			print_debug('return error from update shipping attributes',
2064 				    'Inv_Pick_Release_Pub.Pick_Release');
2065 		     End If;
2066 		     raise FND_API.G_EXC_UNEXPECTED_ERROR;
2067 		  end if;
2068 
2069 		  --close the move order line
2070 		  -- HW INVCONV Update Qty2
2071 		  update mtl_txn_request_lines
2072 		    set  quantity = 0
2073 		    ,quantity_detailed = 0
2074 		    ,secondary_quantity = decode(secondary_quantity,fnd_api.g_miss_num, NULL, 0)
2075 		    ,secondary_quantity_detailed = decode(secondary_quantity_detailed,fnd_api.g_miss_num, NULL, 0)
2076 		    ,line_status = 5
2077           ,status_date =sysdate                      --BUG 7560455
2078 		    where line_id = l_mo_line.line_id;
2079 
2080 		  -- Exit if there are no more move order lines to detail
2081 		  --  or when the next move order is not for the same ship set.
2082 		  -- Exit before updating the pick_release_status tbl
2083 		  -- for the last line.  The table gets updated for the last
2084 		  -- line later.
2085 		  -- l_set_index should always be equal to the last line
2086 		  --  in the current ship set, so that the logic at the
2087 		  --  end of the outer loop works correctly.
2088 		  EXIT WHEN l_mo_line_tbl.LAST = l_set_index;
2089 		  l_set_index := l_mo_line_tbl.NEXT(l_set_index);
2090 		  if nvl(l_mo_line_tbl(l_set_index).ship_set_id,-1)
2091 		    <> l_cur_ship_set_id then
2092 		     l_set_index := l_mo_line_tbl.PRIOR(l_set_index);
2093 		     EXIT;
2094 		  end if;
2095 
2096 		  --If next line is for same ship set, update output table
2097 		  l_set_process := l_set_process + 1;
2098 		  x_pick_release_status(l_set_process).mo_line_id :=
2099 		    l_mo_line.line_id;
2100 		  x_pick_release_status(l_set_process).return_status :=
2101 		    l_api_return_status;
2102 		  x_pick_release_status(l_set_process).detail_rec_count := 0;
2103 		  If is_debug then
2104 		     print_debug('x_pick_release_status ' || l_set_process ||
2105 				 ' mo_line_id = ' || l_mo_line.line_id,
2106 				 'Pick_release_Pub');
2107 		     print_debug('x_pick_release_status ' || l_set_process ||
2108 				 ' return_status = '|| l_api_return_status,
2109 				 'Pick_release_Pub');
2110 		     print_debug('x_pick_release_status ' || l_set_process ||
2111 				 ' detail_rec_count = 0', 'Pick_Release_Pub');
2112 		  End If;
2113 	       END LOOP;
2114 
2115 	       -- at the end of this loop, l_mo_line and l_set_index
2116 	       --  point to the last line for this ship set.  l_set_process
2117 	       --  is the index of the last entry in the pick release status
2118 	       --  table.  This allows all of the logic near the end of the
2119 	       --  loop to work correctly.
2120 	       l_line_index := l_set_index;
2121 	       l_cur_ship_set_id := NULL;
2122 	       l_processed_row_count := l_set_process;
2123 	       l_detail_rec_count := 0;
2124 	       l_qtree_backup_tbl.DELETE;
2125 	       If is_debug then
2126 		  print_debug('Finished backordering all lines in shipset',
2127 	              'Inv_Pick_Release_Pub.Pick_Release');
2128 	       End If;
2129 
2130 	       --For Ship Models, if a move order line does not fully
2131 	       -- allocate, we have to determine the new model quantity.  Then,
2132 	       -- once we know the new model quantity, we have to change the
2133 	       -- quantity on each move order line to reflect the new model
2134 	       -- quantity.  Backorders have to created for the lines which
2135 	       -- have their quantity reduced.
2136 	     ELSIF (l_cur_ship_model_id IS NOT NULL AND NVL(g_pick_release_caller,'###') <> 'WMS-PICK-EXCEPTION') THEN --9556463
2137 	       -- Bug 2461353, 2411016
2138 	       --Call Shipping and let them know for a ship model we were not
2139 	       --able to allocate completely
2140 	       BEGIN
2141 		  If is_debug then
2142 		     print_debug('Update shipping that ship model detailing partial',
2143 				 'Inv_Pick_Release_Pub.Pick_Release');
2144 		  End If;
2145 
2146 		  l_shipset_smc_backorder_rec.move_order_line_id:=l_mo_line.line_id;
2147 		  l_shipset_smc_backorder_rec.ship_model_id :=l_cur_ship_model_id;
2148 
2149 		  wsh_integration.ins_backorder_ss_smc_rec
2150 		    (p_api_version_number => 1.0,
2151 		     p_source_code        => 'INV',
2152 		     p_init_msg_list      => fnd_api.g_false,
2153 		     p_backorder_rec      => l_shipset_smc_backorder_rec,
2154 		     x_return_status      => l_api_return_status,
2155 		     x_msg_count          => x_msg_count,
2156 		     x_msg_data           => x_msg_data);
2157 
2158 		  IF l_api_return_status <> fnd_api.g_ret_sts_success THEN
2159 		     If is_debug then
2160 			print_debug('Error occured while updating shipping for ' ||
2161 				    'failed ship set',
2162 				    'Inv_Pick_Release_Pub.Pick_Release');
2163 			print_debug('l_return_status'||l_api_return_status,
2164 				    'Inv_Pick_Release_Pub.Pick_Release');
2165 		     End If;
2166 		  END IF;
2167 	       EXCEPTION
2168 		  WHEN OTHERS THEN
2169 		     If is_debug then
2170 			print_debug('When other exception',
2171 				    'Inv_Pick_Release_Pub.Pick_Release');
2172 		     End If;
2173 		     NULL;
2174 		     --no need to error out for reporting purpose.
2175 	       END;
2176 
2177 	       If is_debug then
2178 		  print_debug('Rolling back for ship model :' ||l_cur_ship_model_id,
2179 			      'Inv_Pick_Release_Pub.Pick_Release');
2180 	       End If;
2181 
2182 	       ROLLBACK to SHIPMODEL;
2183 	       l_set_index := l_start_index;
2184 	       l_set_process := l_start_process;
2185 
2186 	       If is_debug then
2187 		  print_debug('OE Line: ' || l_cur_txn_source_line_id,
2188 			      'Inv_Pick_Release_Pub.Pick_Release');
2189 	       End If;
2190 
2191 	       -- Get the sales order line quantity.  We need the order
2192 	       -- line quantity to determine the new model quantity. We
2193 	       -- can't just use the move order line quantity, b/c there
2194 	       -- could be multiple move orders per sales order line.
2195  	       BEGIN
2196 		  SELECT ordered_quantity, order_quantity_uom
2197 		    INTO l_cur_txn_source_req_qty, l_txn_source_line_uom
2198 		    FROM OE_ORDER_LINES_ALL
2199 		    WHERE line_id = l_cur_txn_source_line_id;
2200 	       EXCEPTION
2201 		  WHEN NO_DATA_FOUND then
2202 		     If is_debug then
2203 			print_debug('No Order Line Quantity found',
2204 				    'Inv_Pick_Release_Pub.Pick_Release');
2205 		     End If;
2206 		     ROLLBACK TO Pick_Release_PUB;
2207 		     FND_MESSAGE.SET_NAME('INV','INV_DELIV_INFO_MISSING');
2208 		     FND_MSG_PUB.Add;
2209 		     RAISE fnd_api.g_exc_unexpected_error;
2210 	       END;
2211 
2212 	       -- convert to primary UOM
2213 	       IF l_txn_source_line_uom <>
2214 		 l_primary_uom_tbl(l_mo_line.inventory_item_id) THEN
2215 
2216 		  l_cur_txn_source_req_qty :=
2217 		    inv_convert.inv_um_convert(
2218 					       l_mo_line.inventory_item_id
2219 					       ,NULL
2220 					       ,l_cur_txn_source_req_qty
2221 					       ,l_txn_source_line_uom
2222 					       ,l_primary_uom_tbl(l_mo_line.inventory_item_id)
2223 					       ,NULL
2224 					       ,NULL);
2225 	       END IF;
2226 	       -- find new model quantity.
2227 	       -- new model qty = floor((allocated for this sales order /
2228 	       --		       requested for this sales order) *
2229 	       --		       original model quantity)
2230 	       --  We take the floor because we can only ship whole numbers
2231 	       --  of the top model
2232 	       l_new_model_quantity := floor(l_cur_txn_source_qty * l_mo_line.model_quantity /
2233 					     l_cur_txn_source_req_qty);
2234 	       --l_new_model_quantity :=
2235 	       --floor(l_cur_txn_source_qty * l_mo_line.model_quantity/
2236 	       --l_mo_line.quantity);
2237 
2238 	       --We keep model quantity and quantity in PUOM so should not
2239 	       --find it from order lines.
2240 	       If is_debug then
2241 		  print_debug('New model qty ' || l_new_model_quantity,
2242 			      'Inv_Pick_Release_Pub.Pick_Release');
2243 	       End If;
2244 
2245 	       --loop through all move order lines for this ship model
2246 	       LOOP
2247 		  l_mo_line := l_mo_line_tbl(l_set_index);
2248 		  If is_debug then
2249 		     print_debug('SHIPMODEL-Current mo line:'||l_mo_line.line_id,
2250 				 'Inv_Pick_Release_Pub.Pick_Release');
2251 		  End If;
2252 
2253 		  --find tree id.  If item is unit effective, get tree id from
2254 		  -- qtree_line_tbl.  Else, get it from qtree_item_tbl.
2255 		  IF l_qtree_item_tbl(l_mo_line.inventory_item_id).unit_effective='Y'
2256 		    THEN
2257 		     l_tree_id :=
2258 		       l_qtree_line_tbl(l_mo_line.txn_source_line_id).tree_id;
2259 		   ELSE
2260 		     l_tree_id :=
2261 		       l_qtree_item_tbl(l_mo_line.inventory_item_id).tree_id;
2262 		  END IF;
2263 
2264 		  -- only restore tree if it is currently in backup table.
2265 		  -- Tree would not be in backup table if current move order line
2266 		  -- was not allocated or if the tree had already been restored
2267 		  -- for a previous move order line.
2268 		  IF l_qtree_backup_tbl.EXISTS(l_tree_id) THEN
2269 
2270 		     If is_debug then
2271 			print_debug('Restoring Quantity Tree: ' || l_tree_id,
2272 				    'Inv_Pick_Release_Pub.Pick_Release');
2273 		     End If;
2274 		     inv_quantity_tree_pvt.restore_tree
2275 		       (x_return_status  => l_api_return_status
2276 			,p_tree_id       => l_tree_id
2277 			,p_backup_id     => l_qtree_backup_tbl(l_tree_id)
2278 			);
2279 		     if( l_api_return_status = FND_API.G_RET_STS_ERROR ) then
2280 			If is_debug then
2281 			   print_debug('Error in Restore_Tree',
2282 				       'Inv_Pick_Release_Pub.Pick_Release');
2283 			End If;
2284 			raise FND_API.G_EXC_ERROR;
2285 		      elsif l_api_return_status=FND_API.G_RET_STS_UNEXP_ERROR then
2286 			If is_debug then
2287 			   print_debug('Unexpected error in Restore_tree',
2288 				       'Inv_Pick_Release_Pub.Pick_Release');
2289 			End If;
2290 			raise FND_API.G_EXC_UNEXPECTED_ERROR;
2291 		     end if;
2292 
2293 		     --delete entry, so we don't restore tree more than once
2294 		     l_qtree_backup_tbl.DELETE(l_tree_id);
2295 
2296 		  END IF;
2297 
2298 
2299 		  -- whenever line changes, find sales order quantity for
2300 		  -- this line
2301 		  IF l_set_txn_source_line_Id IS NULL OR
2302 		    l_set_txn_source_line_id <> l_mo_line.txn_source_line_id
2303 		    THEN
2304 		     l_set_txn_source_line_id := l_mo_line.txn_source_line_id;
2305 		     If is_debug then
2306 			print_debug('OE Line: ' || l_set_txn_source_line_id,
2307 				    'Inv_Pick_Release_Pub.Pick_Release');
2308 		     End If;
2309 
2310 		     -- if we already got the qty, don't get it again
2311 		     IF l_set_txn_source_line_id = l_cur_txn_source_line_id Then
2312 			l_set_txn_source_req_qty := l_cur_txn_source_req_qty;
2313 		      ELSE
2314  	                BEGIN
2315 			   -- Bug 3340502, fetching order_quantity_uom in variable
2316 			   -- l_txn_source_line_uom instead of l_set_txn_source_uom
2317 			   SELECT ordered_quantity, order_quantity_uom
2318 			     INTO l_set_txn_source_req_qty, l_txn_source_line_uom
2319 			     FROM OE_ORDER_LINES_ALL
2320 			     WHERE line_id = l_set_txn_source_line_id;
2321 			EXCEPTION
2322 			   WHEN NO_DATA_FOUND then
2323 			      If is_debug then
2324 				 print_debug('No Order Line Quantity found',
2325 					     'Inv_Pick_Release_Pub.Pick_Release');
2326 			      End If;
2327 			      ROLLBACK TO Pick_Release_PUB;
2328 			      FND_MESSAGE.SET_NAME('INV','INV_DELIV_INFO_MISSING');
2329 			      FND_MSG_PUB.Add;
2330 			      RAISE fnd_api.g_exc_unexpected_error;
2331 			END;
2332 
2333 			--convert to primary quantity
2334 			if l_txn_source_line_uom <>
2335 			  l_primary_uom_tbl(l_mo_line.inventory_item_id) then
2336 
2337 			   l_cur_txn_source_req_qty :=
2338 			     inv_convert.inv_um_convert(
2339 							l_mo_line.inventory_item_id
2340 							,NULL
2341 							,l_cur_txn_source_req_qty
2342 							,l_txn_source_line_uom
2343 							,l_primary_uom_tbl(l_mo_line.inventory_item_id)
2344 							,NULL
2345 							,NULL);
2346 			end if;
2347 		     END IF;
2348 
2349 		     -- based on new model quantity, find new move order
2350 		     -- line quantity
2351 		     -- l_set_new_req_qty :=  (l_mo_line.quantity *
2352 		     --		          l_new_model_quantity
2353 		     --			   / l_mo_line.model_quantity);
2354 
2355 		     l_set_new_req_qty := l_set_txn_source_req_qty *
2356 		       l_new_model_quantity /
2357 		       l_mo_line.model_quantity;
2358 
2359 		     If is_debug then
2360 			print_debug('New req qty: ' || l_set_new_req_qty,
2361 				    'Inv_Pick_Release_Pub.Pick_Release');
2362 		     End If;
2363 		  END IF;
2364 
2365 		  -- set new move order line quantity
2366 		  IF l_set_new_req_qty >= l_mo_line.quantity THEN
2367 		     l_new_line_quantity := l_mo_line.quantity;
2368 		   ELSE
2369 		     -- if new line quantity < previous line qty,
2370 		     -- backorder
2371 		     l_new_line_quantity := l_set_new_req_qty;
2372 
2373 		     If is_debug then
2374 			print_debug('New line qty: ' || l_new_line_quantity,
2375 				    'Inv_Pick_Release_Pub.Pick_Release');
2376 		     End If;
2377 
2378 		     l_return_value := INV_CACHE.set_wdd_rec(l_mo_line.line_id);
2379 		     If NOT l_return_value Then
2380 			If is_debug then
2381 			   print_debug('Error setting cache for delivery line',
2382 				       'INV_Pick_Release_Pub.Pick_Release');
2383 			End If;
2384 			RAISE fnd_api.g_exc_unexpected_error;
2385 		     End If;
2386 		     l_delivery_detail_id := INV_CACHE.wdd_rec.delivery_detail_id;
2387 		     l_source_header_id := INV_CACHE.wdd_rec.source_header_id;
2388 		     l_source_line_id := INV_CACHE.wdd_rec.source_line_id;
2389 		     l_released_status := INV_CACHE.wdd_rec.released_status;
2390 
2391 		     --Call Update_Shipping_Attributes to backorder detail line
2392 		     l_shipping_attr(1).source_header_id := l_source_header_id;
2393 		     l_shipping_attr(1).source_line_id := l_source_line_id;
2394 		     l_shipping_attr(1).ship_from_org_id := l_mo_line.organization_id;
2395 		     l_shipping_attr(1).released_status := l_released_status;
2396 		     l_shipping_attr(1).delivery_detail_id := l_delivery_detail_id;
2397 		     l_shipping_attr(1).action_flag := 'B';
2398 		     l_shipping_attr(1).cycle_count_quantity := l_mo_line.quantity - l_new_line_quantity;
2399 		     l_shipping_attr(1).subinventory := l_mo_line.from_subinventory_code;
2400 		     l_shipping_attr(1).locator_id := l_mo_line.from_locator_id;
2401 		     l_smc_backorder_det_tbl(1) :=l_shipping_attr(1);
2402 		     -- 2509322: Earlier whenever a component in a model is short we
2403 		     -- backorder all
2404 		     -- components to the difference of new model quantity and original
2405 		     -- and repick release all.But if many components are short then
2406 		     -- we end up splitting many delivery details.
2407 		     -- Now avoided multiple splits by storing back order details
2408 		     -- and do only once.
2409 
2410 		     Store_smc_bo_details(x_return_status    => l_api_return_status,
2411 					  back_order_det_tbl =>l_smc_backorder_det_tbl);
2412 		     if( l_api_return_status = FND_API.G_RET_STS_ERROR ) then
2413 			If is_debug then
2414 			   print_debug(' return error E from Store_smc_bo_details',
2415 				       'Inv_Pick_Release_Pub.Pick_Release');
2416 			End If;
2417 			l_smc_backorder_det_tbl.DELETE;
2418 			raise FND_API.G_EXC_ERROR;
2419 		      elsif l_api_return_status = FND_API.G_RET_STS_UNEXP_ERROR then
2420 			If is_debug then
2421 			   print_debug(' return error U from Store_smc_bo_details',
2422 				       'Inv_Pick_Release_Pub.Pick_Release');
2423 			End If;
2424 			l_smc_backorder_det_tbl.DELETE;
2425 			raise FND_API.G_EXC_UNEXPECTED_ERROR;
2426 		     end if;
2427 
2428 		     l_smc_backorder_det_tbl.DELETE;
2429 
2430 
2431 		     --WSH_INTERFACE.Update_Shipping_Attributes
2432 		     --(p_source_code               => 'INV',
2433 		     --p_changed_attributes        => l_shipping_attr,
2434 		     --x_return_status             => l_api_return_status
2435 		     --);
2436 
2437 		  END IF;
2438 
2439 		  l_set_new_req_qty := l_set_new_req_qty - l_new_line_quantity;
2440 
2441 		  -- Update mo line with new quantity and model quantity;
2442 		  --If mo line quantity is 0, close the move order line
2443 		  IF l_new_line_quantity = 0 THEN
2444 		     update mtl_txn_request_lines
2445 		       set  quantity = 0
2446 		       ,quantity_detailed = 0
2447 		       ,line_status = 5
2448              ,status_date =sysdate                    --BUG 7560455
2449 		       ,model_quantity = l_new_model_quantity
2450 		       where line_id = l_mo_line.line_id;
2451 		     l_mo_line_tbl(l_set_index).quantity_detailed := 0;
2452 		     l_mo_line_tbl(l_set_index).line_status := 5;
2453 		   ELSE
2454 		     update mtl_txn_request_lines
2455 		       set  quantity = l_new_line_quantity
2456 		       ,quantity_detailed = NULL
2457 		       ,model_quantity = l_new_model_quantity
2458 		       where line_id = l_mo_line.line_id;
2459 		     l_mo_line_tbl(l_set_index).quantity_detailed := NULL;
2460 		  END IF;
2461 		  l_mo_line_tbl(l_set_index).quantity := l_new_line_quantity;
2462 
2463 		  -- Bug# 3085075. Commented out the next line so that model qty does not
2464 		  -- become fractional.
2465 		  --l_mo_line_tbl(l_set_index).model_quantity := l_new_model_quantity;
2466 
2467 		  If is_debug then
2468 		     print_debug('Finished Updating Mo Line',
2469 				 'Inv_Pick_Release_Pub.Pick_Release');
2470 		  End If;
2471 
2472 		  -- Exit if there are no more move order lines to detail
2473 		  --  or when the next move order is not for the same ship model.
2474 		  -- Exit before updating the pick_release_status tbl
2475 		  -- for the last line.  The table gets updated for the last
2476 		  -- line later.
2477 		  -- l_set_index should always be equal to the last line
2478 		  --  in the current ship set, so that the logic at the
2479 		  --  end of the outer loop works correctly.
2480 		  EXIT WHEN l_mo_line_tbl.LAST = l_set_index;
2481 		  l_set_index := l_mo_line_tbl.NEXT(l_set_index);
2482 		  if nvl(l_mo_line_tbl(l_set_index).ship_model_id,-99)
2483 		    <> l_cur_ship_model_id then
2484 		     l_set_index := l_mo_line_tbl.PRIOR(l_set_index);
2485 		     EXIT;
2486 		  end if;
2487 
2488 		  -- Only update status table if model_quantity = 0;
2489 		  -- If model quantity <> 0, then we loop through all these
2490 		  -- records again, re-detailing them for the new line quantities.
2491 		  -- The status table will get populated at that point.
2492 		  -- But, if model_quantity = 0, then we don't look at these
2493 		  -- mo lines again, since the quantity for all the lines = 0.
2494 		  -- We have to update the status now.
2495 		  if l_new_model_quantity = 0 then
2496 
2497 		     --If next line is for same ship set, update output table
2498 		     l_set_process := l_set_process + 1;
2499 		     x_pick_release_status(l_set_process).mo_line_id := l_mo_line.line_id;
2500 		     x_pick_release_status(l_set_process).return_status := l_api_return_status;
2501 		     x_pick_release_status(l_set_process).detail_rec_count := 0;
2502 		     If is_debug then
2503 			print_debug('x_pick_release_status ' || l_set_process ||
2504 				    ' mo_line_id = ' || l_mo_line.line_id,
2505 				    'Pick_release_Pub');
2506 			print_debug('x_pick_release_status ' || l_set_process ||
2507 				    ' return_status = '|| l_api_return_status,
2508 				    'Pick_release_Pub');
2509 			print_debug('x_pick_release_status ' || l_set_process ||
2510 				    ' detail_rec_count = 0', 'Pick_Release_Pub');
2511 		     End If;
2512 		  end if;
2513 	       END LOOP;
2514 
2515 	       --reset global values, since we are relooping
2516 	       --Bug 2706558 - reset cur_txn_source_qty and cur_txn_source_line_id
2517 	       l_cur_ship_model_id := NULL;
2518 	       l_qtree_backup_tbl.DELETE;
2519 	       l_cur_txn_source_qty := 0;
2520 	       -- HW INVCONV Added Qty2
2521 	       l_cur_txn_source_qty2 :=0;
2522 	       l_cur_txn_source_line_id := NULL;
2523 
2524 	       -- If new model quantity = 0, then we backordered all of the
2525 	       -- lines.  No need to try to redetail.  Set line index
2526 	       -- to point at the last mo line we backordered.
2527 	       IF l_new_model_quantity = 0 THEN
2528 		  l_line_index := l_set_index;
2529 		  l_processed_row_count := l_set_process;
2530 		  l_detail_rec_count := 0;
2531 
2532 		  If is_debug then
2533 		     print_debug('Backordered all lines with this Ship Model Id',
2534 				 'Inv_Pick_Release_Pub.Pick_Release');
2535 		  End If;
2536 		  Backorder_SMC_DETAILS(l_api_return_status ,
2537 					x_msg_data ,
2538 					x_msg_count
2539 					);
2540 		  if( l_api_return_status = FND_API.G_RET_STS_ERROR ) then
2541 		     If is_debug then
2542 			print_debug('return error E from Backorder_SMC_DETAILS',
2543 				    'Inv_Pick_Release_Pub.Pick_Release');
2544 		     End If;
2545 		     raise FND_API.G_EXC_ERROR;
2546 		   elsif l_api_return_status = FND_API.G_RET_STS_UNEXP_ERROR then
2547 		     If is_debug then
2548 			print_debug('return error U from Backorder_SMC_DETAILS',
2549 				    'Inv_Pick_Release_Pub.Pick_Release');
2550 		     End If;
2551 		     raise FND_API.G_EXC_UNEXPECTED_ERROR;
2552 		  end if;
2553 
2554 		ELSE
2555 
2556 		  -- If new model quantity <> 0, then we want to loop
2557 		  -- through these lines again.  Set line index to
2558 		  -- point to the  first record with this ship
2559 		  -- model id. Also we need to turn on the reloop flag so that
2560 		  -- the line index is not incremented later.
2561 		  l_line_index := l_start_index;
2562 		  l_processed_row_count := l_start_process;
2563 		  l_model_reloop := TRUE;
2564 	       END IF;
2565 
2566 	     ELSE
2567 	       -- Move order line is not fully allocated and it is not part of a
2568 	       -- shipset or ship model
2569 
2570 
2571 	        -- 8519286
2572                 /*  l_return_value := INV_CACHE.set_wdd_rec(l_mo_line.line_id); */
2573       	        l_return_value := FALSE;
2574 
2575 		  BEGIN
2576 		     SELECT *
2577 		     INTO INV_CACHE.wdd_rec
2578 		     FROM WSH_DELIVERY_DETAILS
2579 		     WHERE move_order_line_id = l_mo_line.line_id
2580 		     AND NVL(released_status, 'Z') NOT IN ('Y','C');
2581 		     l_return_value := TRUE;
2582 		      EXCEPTION
2583 		     WHEN NO_DATA_FOUND THEN
2584                      l_return_value := FALSE;
2585                      WHEN OTHERS THEN
2586                      l_return_value := FALSE;
2587 		  END;
2588                  -- End of 8519286
2589 
2590 
2591 	       -- Retrieve the WDD record corresponding to the current MOL
2592 	       l_return_value := INV_CACHE.set_wdd_rec(l_mo_line.line_id);
2593 	       IF (NOT l_return_value) THEN
2594 		  IF (is_debug) THEN
2595 		     print_debug('Error setting cache for delivery line',
2596 				 'INV_Pick_Release_Pub.Pick_Release');
2597 		  END IF;
2598 		  RAISE fnd_api.g_exc_unexpected_error;
2599 	       END IF;
2600 	       l_delivery_detail_id := INV_CACHE.wdd_rec.delivery_detail_id;
2601 	       l_source_header_id := INV_CACHE.wdd_rec.source_header_id;
2602 	       l_source_line_id := INV_CACHE.wdd_rec.source_line_id;
2603 	       l_released_status := INV_CACHE.wdd_rec.released_status;
2604 
2605 	       -- Bug# 4258360: If allocation mode = N (Prioritize Inventory), instead of simply
2606 	       -- backordering the unallocated quantity on the WDD record, we need to perform
2607 	       -- new logic to support crossdocking.  The WDD record needs to be split or updated
2608 	       -- properly so we can still try to allocate material through crossdocking later.
2609 	       -- {{
2610 	       -- Run PR in Prioritize INV mode and ensure that one WDD
2611 	       -- does not get allocated at all. That WDD should get
2612 	       -- x-docked and later deliveries created for same.
2613 	       -- }}
2614 	       -- {{
2615 	       -- Run PR in Prioritize INV mode and ensure that one WDD
2616 	       -- gets partially allocated. That WDD should get split and
2617 	       -- x-docked and later deliveries created for the new WDD.
2618 	       -- Also ensure that the original WDD has the correct qty.
2619 	       -- }}
2620 	       IF (l_allocation_method = g_prioritize_inventory) AND (p_wsh_release_table.COUNT > 0) THEN
2621 		  IF (l_transaction_quantity = 0) THEN
2622 
2623 
2624 		     -- Move order line is not allocated at all.
2625 		     -- Do not backorder the current WDD line yet since crossdocking can still
2626 		     -- potentially allocate material for this.  Update the WDD record to null
2627 		     -- out the move_order_line_id column and reset the released_status to the
2628 		     -- original value from the corresponding record in p_wsh_release_table.
2629 
2630 
2631 		     -- R12.1 replenishment Project 6681109/6710368
2632 		     -- changes based ON p_dynamic_replenishment
2633 		     IF (is_debug) THEN
2634 			print_debug('p_dynamic_replenishment :'||p_dynamic_replenishment,
2635 				    'INV_Pick_Release_Pub.Pick_Release');
2636 		     END IF;
2637 
2638 
2639 		     l_detail_info_tab(1).delivery_detail_id := l_delivery_detail_id;
2640 		     l_detail_info_tab(1).released_status :=
2641 		       p_wsh_release_table(l_wdd_index_tbl(l_delivery_detail_id)).released_status;
2642 
2643 		     IF NVL(p_dynamic_replenishment,'N') = 'Y' THEN
2644 
2645 			IF (is_debug) THEN
2646 			   print_debug('Mark WDD repl_status as RR','INV_Pick_Release_Pub.Pick_Release');
2647 			END IF;
2648 			--if qty is available somewhere in the org, we will try to replenish it first
2649 			-- mark the demand lines for replenishment requested status
2650 			l_detail_info_tab(1).replenishment_status := 'R';
2651 			l_in_rec.caller := 'WMS_REP';
2652 			l_in_rec.action_code := 'UPDATE';
2653 
2654 		      ELSE
2655 
2656 			-- When calling the Shipping package WSH_INTERFACE_EXT_GRP instead of
2657 			-- WSH_INTERFACE_GRP, we have to pass a G_MISS_NUM value instead of NULL
2658 			-- in order to properly NULL out the move_order_line_id value.
2659 
2660 			l_detail_info_tab(1).move_order_line_id := fnd_api.g_miss_num;
2661 
2662 			-- Caller needs to be WMS_XDOCK% in order for shipping to allow this action
2663 			l_in_rec.caller := 'WMS_XDOCK.INVPPICB';
2664 			l_in_rec.action_code := 'UPDATE';
2665 
2666 		     END IF;
2667 
2668 		     WSH_INTERFACE_EXT_GRP.Create_Update_Delivery_Detail
2669 		       (p_api_version_number  => 1.0,
2670 			p_init_msg_list       => fnd_api.g_false,
2671 			p_commit              => fnd_api.g_false,
2672 			x_return_status       => l_api_return_status,
2673 			x_msg_count           => x_msg_count,
2674 			x_msg_data            => x_msg_data,
2675 			p_detail_info_tab     => l_detail_info_tab,
2676 			p_in_rec              => l_in_rec,
2677 			x_out_rec             => l_out_rec
2678 			);
2679 
2680 		     IF (l_api_return_status = FND_API.G_RET_STS_ERROR) THEN
2681 			IF (is_debug) THEN
2682 			   print_debug('Error returned from Create_Update_Delivery_Detail API',
2683 				       'Inv_Pick_Release_Pub.Pick_Release');
2684 			END IF;
2685 			RAISE FND_API.G_EXC_ERROR;
2686 		      ELSIF (l_api_return_status = FND_API.G_RET_STS_UNEXP_ERROR) THEN
2687 			IF (is_debug) THEN
2688 			   print_debug('Unexpected errror from Create_Update_Delivery_Detail API',
2689 				       'Inv_Pick_Release_Pub.Pick_Release');
2690 			END IF;
2691 			RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
2692 		     END IF;
2693 
2694 		   ELSE -- means (l_transaction_quantity <> 0)
2695 		     -- Move order line is partially allocated
2696 		     -- Split the WDD line with the partial quantity allocated.  The new WDD
2697 		     -- line with the unallocated quantity will retain the original released_status
2698 		     -- on the original WDD record in p_wsh_release_table
2699 		     l_detail_id_tab(1) := l_delivery_detail_id;
2700 		     -- Caller needs to be WMS_XDOCK% in order for shipping to allow this action
2701 		     l_action_prms.caller := 'WMS_XDOCK.INVPPICB';
2702 		     l_action_prms.action_code := 'SPLIT-LINE';
2703 		     l_action_prms.split_quantity :=
2704 		       (l_quantity - NVL(l_quantity_delivered,0)) - l_transaction_quantity;
2705 		     l_action_prms.split_quantity2 :=
2706 		       (l_quantity2 - NVL(l_quantity2_delivered,0)) - l_transaction_quantity2;
2707 
2708 		     WSH_INTERFACE_GRP.Delivery_Detail_Action
2709 		       (p_api_version_number  => 1.0,
2710 			p_init_msg_list       => fnd_api.g_false,
2711 			p_commit              => fnd_api.g_false,
2712 			x_return_status       => l_api_return_status,
2713 			x_msg_count           => x_msg_count,
2714 			x_msg_data            => x_msg_data,
2715 			p_detail_id_tab       => l_detail_id_tab,
2716 			p_action_prms         => l_action_prms,
2717 			x_action_out_rec      => l_action_out_rec
2718 			);
2719 
2720 		     IF (l_api_return_status = FND_API.G_RET_STS_ERROR) THEN
2721 			IF (is_debug) THEN
2722 			   print_debug('Error returned from Split Delivery_Detail_Action API',
2723 				       'Inv_Pick_Release_Pub.Pick_Release');
2724 			END IF;
2725 			RAISE FND_API.G_EXC_ERROR;
2726 		      ELSIF (l_api_return_status = FND_API.G_RET_STS_UNEXP_ERROR) THEN
2727 			IF (is_debug) THEN
2728 			   print_debug('Unexpected errror from Split Delivery_Detail_Action API',
2729 				       'Inv_Pick_Release_Pub.Pick_Release');
2730 			END IF;
2731 			RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
2732 		     END IF;
2733 
2734 		     l_xdock_index := l_action_out_rec.result_id_tab.FIRST;
2735 		     l_split_delivery_detail_id := l_action_out_rec.result_id_tab(l_xdock_index);
2736 
2737 		     -- Update the split WDD line for the unallocated quantity to null out the
2738 		     -- move_order_line_id column and reset the released_status to the original
2739 		     -- value in the corresponding WDD record (original one) in p_wsh_release_table
2740 		     l_detail_info_tab(1).delivery_detail_id := l_split_delivery_detail_id;
2741 		     l_detail_info_tab(1).released_status :=
2742 		       p_wsh_release_table(l_wdd_index_tbl(l_delivery_detail_id)).released_status;
2743 		     -- When calling the Shipping package WSH_INTERFACE_EXT_GRP instead of
2744 		     -- WSH_INTERFACE_GRP, we have to pass a G_MISS_NUM value instead of NULL
2745 		     -- in order to properly NULL out the move_order_line_id value.
2746 		     --l_detail_info_tab(1).move_order_line_id := NULL;
2747 		     l_detail_info_tab(1).move_order_line_id := fnd_api.g_miss_num;
2748 
2749 
2750 		     IF NVL(p_dynamic_replenishment,'N') = 'Y' THEN
2751 			IF (is_debug) THEN
2752 			   print_debug(' Mark repl_status of WDD as RR','INV_Pick_Release_Pub.Pick_Release');
2753 			END IF;
2754 			-- mark the new split demand lines for replenishment requested status
2755 			l_detail_info_tab(1).replenishment_status := 'R';
2756 			l_in_rec.caller := 'WMS_REP';
2757 		      ELSE
2758 			-- Caller needs to be WMS_XDOCK% in order for shipping to allow this action
2759 			l_in_rec.caller := 'WMS_XDOCK.INVPPICB';
2760 		     END IF;
2761 
2762 
2763 		     l_in_rec.action_code := 'UPDATE';
2764 
2765 		     WSH_INTERFACE_EXT_GRP.Create_Update_Delivery_Detail
2766 		       (p_api_version_number  => 1.0,
2767 			p_init_msg_list       => fnd_api.g_false,
2768 			p_commit              => fnd_api.g_false,
2769 			x_return_status       => l_api_return_status,
2770 			x_msg_count           => x_msg_count,
2771 			x_msg_data            => x_msg_data,
2772 			p_detail_info_tab     => l_detail_info_tab,
2773 			p_in_rec              => l_in_rec,
2774 			x_out_rec             => l_out_rec
2775 			);
2776 
2777 		     IF (l_api_return_status = FND_API.G_RET_STS_ERROR) THEN
2778 			IF (is_debug) THEN
2779 			   print_debug('Error returned from Create_Update_Delivery_Detail API',
2780 				       'Inv_Pick_Release_Pub.Pick_Release');
2781 			END IF;
2782 			RAISE FND_API.G_EXC_ERROR;
2783 		      ELSIF (l_api_return_status = FND_API.G_RET_STS_UNEXP_ERROR) THEN
2784 			IF (is_debug) THEN
2785 			   print_debug('Unexpected errror from Create_Update_Delivery_Detail API',
2786 				       'Inv_Pick_Release_Pub.Pick_Release');
2787 			END IF;
2788 			RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
2789 		     END IF;
2790 
2791 		     -- Insert the split WDD line into p_wsh_release_table.
2792 		     -- The split WDD release record should be the same as the original one with
2793 		     -- only the following fields modified: delivery_detail_id, move_order_line_id
2794 		     -- replenishment_status, and requested_quantity fields
2795 		     l_split_wdd_rel_rec := p_wsh_release_table(l_wdd_index_tbl(l_delivery_detail_id));
2796 		     l_split_wdd_rel_rec.delivery_detail_id := l_split_delivery_detail_id;
2797 		     l_split_wdd_rel_rec.move_order_line_id := NULL;
2798 		     l_split_wdd_rel_rec.requested_quantity :=
2799 		       (l_quantity - NVL(l_quantity_delivered,0)) - l_transaction_quantity;
2800 		     l_split_wdd_rel_rec.requested_quantity2 :=
2801 		       (l_quantity2 - NVL(l_quantity2_delivered,0)) - l_transaction_quantity2;
2802 
2803 
2804 		     l_xdock_index := p_wsh_release_table.LAST + 1;
2805 		     p_wsh_release_table(l_xdock_index) := l_split_wdd_rel_rec;
2806 
2807 		     -- Insert a new record into p_trolin_delivery_ids and p_del_detail_id
2808 		     -- for the split WDD line created.
2809 		     -- UPDATE: Do not need to do this anymore.  The delivery tables passed in by
2810 		     -- Shipping are used for storing crossdocked WDD lines.  If this split line
2811 		     -- is later allocated from Crossdocking, the crossdock API will insert them
2812 		     -- into the delivery tables.
2813 		     /*l_xdock_index := NVL(p_del_detail_id.LAST, 0) + 1;
2814 		     p_del_detail_id(l_xdock_index) := l_split_wdd_rel_rec.delivery_detail_id;
2815 		     p_trolin_delivery_ids(l_xdock_index) := l_split_wdd_rel_rec.delivery_id;*/
2816 
2817 		     -- Update the original WDD line in p_wsh_release_table with
2818 		     -- released_status = 'S' and the corresponding allocated quantity
2819 		     l_xdock_index := l_wdd_index_tbl(l_delivery_detail_id);
2820 		     p_wsh_release_table(l_xdock_index).released_status := 'S';
2821 		     p_wsh_release_table(l_xdock_index).requested_quantity := l_transaction_quantity;
2822 		     p_wsh_release_table(l_xdock_index).requested_quantity2 := l_transaction_quantity2;
2823 
2824 		  END IF; -- for  IF (l_transaction_quantity = 0) THEN
2825 		ELSE
2826 		  -- Original code which is used for allocation mode = I (Inventory Only)
2827 		  -- and X (Prioritize Crossdock).
2828 		  -- NOTE: I believe cycle_count_quantity should technically be:
2829 		  -- (l_quantity - NVL(l_quantity_delivered,0)) - l_transaction_quantity
2830 		  -- Same thing goes for cycle_count_quantity2.  Since the transaction quantity
2831 		  -- variable already takes the quantity delivered into account, the requested
2832 		  -- quantity on the MOL (l_quantity) should do the same.  Not making the changes
2833 		  -- yet but leaving the comments here for the future.  -etam
2834 		  l_shipping_attr(1).source_header_id := l_source_header_id;
2835 		  l_shipping_attr(1).source_line_id := l_source_line_id;
2836 
2837 		  l_shipping_attr(1).ship_from_org_id := l_mo_line.organization_id;
2838 		  l_shipping_attr(1).released_status := l_released_status;
2839 		  l_shipping_attr(1).delivery_detail_id := l_delivery_detail_id;
2840 
2841 			select count(1) INTO l_reservation_exists
2842               from mtl_reservations mr
2843              WHERE MR.DEMAND_SOURCE_LINE_ID = l_source_line_id
2844                and MR.DEMAND_SOURCE_HEADER_ID =
2845                    inv_salesorder.get_salesorder_for_oeheader(l_source_header_id)
2846                and MR.demand_source_type_id = decode(INV_CACHE.wdd_rec.source_document_type_id, 10, 8, 2)
2847                and MR.SUBINVENTORY_CODE IS NOT NULL  --locator is not needed
2848 	           and (nvl(mr.staged_flag,'N') = 'N' and nvl(mr.detailed_quantity,0) = 0);
2849 
2850 			IF is_debug THEN
2851 			print_debug('The value of l_reservation_exists is - ' ||l_reservation_exists,'Inv_Pick_Release_Pub.Pick_Release');
2852 		    END IF;
2853 
2854 		  --Note: Inside the API Update_Shipping_Attributes, wdd is split and qty are backordered
2855 		  --in case action_flag is 'B'.  Backorder qty is passed
2856 		  --from INV as cycle_count_quantity below and requested qty is obtained from WDD table by
2857 		  --shipping. Now in case of 'R', shipping team will make change
2858 		  -- to mark those lines as Replenishment Requested instead of backordering them
2859 
2860 
2861 		  IF (l_reservation_exists = 0  and NVL(p_dynamic_replenishment,'N') = 'Y')  THEN --BUG13604664
2862 		     IF is_debug THEN
2863 			print_debug('Marking line status as RR',
2864 				    'Inv_Pick_Release_Pub.Pick_Release');
2865 		     END IF;
2866 		     l_shipping_attr(1).action_flag := 'R';
2867 		   ELSE
2868 		     l_shipping_attr(1).action_flag := 'B';
2869 		  END IF;
2870 
2871 		  --l_shipping_attr(1).cycle_count_quantity := (l_quantity - l_transaction_quantity);
2872 		  -- HW INVCONV - Added Qty2
2873 		  --l_shipping_attr(1).cycle_count_quantity2 := (l_quantity2 - l_transaction_quantity2);
2874 
2875 		   -- End of 8519286
2876                   l_shipping_attr(1).cycle_count_quantity := (l_quantity - NVL(l_quantity_delivered,0) - l_transaction_quantity);
2877                   l_shipping_attr(1).cycle_count_quantity2 := (l_quantity2 - NVL(l_quantity2_delivered,0) - l_transaction_quantity2);
2878                   -- End of 8519286
2879 
2880 		  --MUOM Fulfillment Project
2881           IF ( l_fulfill_base ='S') THEN
2882              l_shipping_attr(1).cycle_count_quantity := inv_convert.inv_um_convert(
2883                                       item_id                      => l_mo_line.inventory_item_id
2884                                     , PRECISION                    => NULL
2885                                     , from_quantity                => l_shipping_attr(1).cycle_count_quantity2
2886                                     , from_unit                    => l_mo_line.secondary_uom
2887                                     , to_unit                      => l_primary_uom_tbl(l_mo_line.inventory_item_id)
2888                                     , from_name                    => NULL
2889                                     , to_name                      => NULL
2890                                  );
2891           END IF;
2892 
2893 
2894 		  l_shipping_attr(1).subinventory := l_mo_line.from_subinventory_code;
2895 		  l_shipping_attr(1).locator_id := l_mo_line.from_locator_id;
2896 
2897 		  WSH_INTERFACE.Update_Shipping_Attributes
2898 		    (p_source_code               => 'INV',
2899 		     p_changed_attributes        => l_shipping_attr,
2900 		     x_return_status             => l_api_return_status
2901 		     );
2902 		  IF (l_api_return_status = FND_API.G_RET_STS_ERROR) THEN
2903 		     IF is_debug THEN
2904 			print_debug('return error from update shipping attributes',
2905 				    'Inv_Pick_Release_Pub.Pick_Release');
2906 		     END IF;
2907 		     RAISE FND_API.G_EXC_ERROR;
2908 		   ELSIF (l_api_return_status = FND_API.G_RET_STS_UNEXP_ERROR) THEN
2909 		     IF is_debug THEN
2910 			print_debug('return error from update shipping attributes',
2911 				    'Inv_Pick_Release_Pub.Pick_Release');
2912 		     END IF;
2913 		     RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
2914 		  END IF;
2915 	       END IF; -- for  IF (l_allocation_method = g_prioritize_inventory) AND (p_wsh...
2916 
2917 	       -- HW INVCONV Added secondary_quantity
2918 	       -- Update the current move order line depending on how much quantity
2919 	       -- was successfully allocated from inventory.
2920 	       IF (l_transaction_quantity = 0) THEN
2921 		  -- Close the move order line created since no quantity was allocated
2922 		  UPDATE mtl_txn_request_lines
2923 		    SET line_status = 5,
2924           status_date =sysdate,                --BUG 7560455
2925 		    quantity = l_transaction_quantity,
2926 		    secondary_quantity = DECODE(secondary_quantity, fnd_api.g_miss_num, NULL,
2927 						l_transaction_quantity2)
2928 		    WHERE line_id = l_mo_line.line_id;
2929 
2930 		  -- Bug# 4258360: For allocation modes of I (Inventory Only) or
2931 		  -- X (Prioritize Crossdock), allocation (both from inventory and crossdock)
2932 		  -- has completed.  We need to remove the backordered lines from
2933 		  -- p_trolin_delivery_ids and p_del_detail_id tables so deliveries are not
2934 		  -- autocreated for them later on by Shipping.  Store the lines which did
2935 		  -- not get any material allocated at all in PLSQL table l_backordered_wdd_tbl.
2936 		  IF (l_allocation_method IN (g_inventory_only, g_prioritize_crossdock)) AND
2937                      (p_wsh_release_table.COUNT > 0) THEN
2938 		     -- UPDATE: Do not need to do this anymore.  The delivery tables inputted from
2939 		     -- Shipping are used only to store crossdocked WDD lines.  They will be
2940 		     -- empty initially.  Instead, set the released_status for the line to be 'B'
2941 		     -- in the inputted release table.
2942 		     --l_backordered_wdd_tbl(l_delivery_detail_id) := TRUE;
2943 		     p_wsh_release_table(l_wdd_index_tbl(l_delivery_detail_id)).released_status := 'B';
2944 		  END IF;
2945 		ELSE
2946         --Bug 9199956 The primary quantity in mtrl should match the quantity in primary uom. Since for Pick Wave move orders
2947         --The uom is always primary uom setting it to quantity value.
2948 		  -- Update the move order line to the partial quantity that was allocated
2949 		  UPDATE mtl_txn_request_lines
2950 		    SET quantity = l_transaction_quantity,
2951 		    secondary_quantity = DECODE(secondary_quantity, fnd_api.g_miss_num, NULL,
2952 						l_transaction_quantity2)
2953                    ,primary_quantity=l_transaction_quantity
2954 		    WHERE line_id = l_mo_line.line_id;
2955 	       END IF;
2956 
2957 	    END IF;  --cur ship set id
2958 	  ELSIF (((l_transaction_quantity = (l_quantity - NVL(l_quantity_delivered,0)))  AND l_fulfill_base<>'S') OR
2959 	    ((l_transaction_quantity2 = (l_quantity2 - NVL(l_quantity2_delivered,0)))  AND l_fulfill_base = 'S'))THEN
2960 	    -- Bug# 4258360: If allocation mode = N (Prioritize Inventory), we need to update
2961 	    -- the corresponding WDD record in p_wsh_release_table to a released_status of 'S'.
2962 	    -- This is so the crossdock API (which will be called later on) knows the WDD record has
2963 	    -- been fully allocated already.  This is added for the R12 Planned Crossdocking project.
2964 	    -- {{
2965 	    -- Run PR in prioritize INV mode and ensure entire WDD
2966 	    -- gets allocated. That WDD should not be re-allocated for
2967 	    -- x-docking.
2968 	    -- }}
2969 	    IF (l_allocation_method = g_prioritize_inventory) THEN
2970 	       -- Retrieve the WDD record associated with the current MOL
2971 	       IF (NOT INV_CACHE.set_wdd_rec(l_mo_line.line_id)) THEN
2972 		  IF (is_debug) THEN
2973 		     print_debug('Error setting cache for WDD delivery line',
2974 				 'INV_Pick_Release_Pub.Pick_Release');
2975 		  END IF;
2976 		  RAISE fnd_api.g_exc_unexpected_error;
2977 	       END IF;
2978 	       l_delivery_detail_id := INV_CACHE.wdd_rec.delivery_detail_id;
2979 
2980 	       -- Update WDD record in release table with a released status of 'S'
2981                IF (p_wsh_release_table.COUNT > 0) THEN
2982 	          p_wsh_release_table(l_wdd_index_tbl(l_delivery_detail_id)).released_status := 'S';
2983                END IF;
2984 	    END IF;
2985 
2986 	 END IF; -- transaction quantity < quantity
2987       END IF;  --line status = 5
2988 
2989       -- If there is no need to reloop for processsing partial quantities
2990       -- FOR ship models
2991       IF (l_model_reloop <> TRUE) THEN
2992 	 -- Populate return status structure with the processing status of
2993 	 -- this row
2994 	 l_processed_row_count := l_processed_row_count + 1;
2995 	 x_pick_release_status(l_processed_row_count).mo_line_id := l_mo_line.line_id;
2996 	 x_pick_release_status(l_processed_row_count).return_status := l_api_return_status;
2997 	 x_pick_release_status(l_processed_row_count).detail_rec_count := l_detail_rec_count;
2998 	 If is_debug then
2999 	    print_debug('x_pick_release_status ' || l_processed_row_count ||
3000 			'   mo_line_id = ' ||
3001 			x_pick_release_status(l_processed_row_count).mo_line_id,
3002 			'Pick_release_Pub');
3003 	    print_debug('x_pick_release_status ' || l_processed_row_count ||
3004 			' return_status = ' ||
3005 			x_pick_release_status(l_processed_row_count).return_status,
3006 			'Pick_release_Pub');
3007 	    print_debug('x_pick_release_status ' || l_processed_row_count ||
3008 			' detail_rec_count = ' ||
3009 			x_pick_release_status(l_processed_row_count).detail_rec_count,
3010 			'Pick_Release_Pub');
3011 	    print_Debug('detail record count is ' ||
3012 			x_pick_release_status(l_processed_row_count).detail_rec_count,
3013 			'Inv_Pick_Release_Pub.Pick_Release');
3014 	 End If;
3015       END IF;
3016       l_detail_rec_count := 0;
3017       --Update the Pick Release API's return status to an error if the line could
3018       -- not be processed.  Note that processing of other lines will continue.
3019       IF l_api_return_status = fnd_api.g_ret_sts_unexp_error OR
3020 	l_api_return_status = fnd_api.g_ret_sts_error THEN
3021 	 x_return_status := fnd_api.g_ret_sts_error;
3022       END IF;
3023     END IF; -- mo line return status <> ERROR
3024 
3025     -- Bug 2776309
3026     -- If model reloop is required then do not exit.
3027     -- Exit in the case where the new model quantity = 0.
3028     EXIT WHEN l_line_index = l_mo_line_tbl.last AND (l_model_reloop <> TRUE);
3029 
3030     IF (l_model_reloop <> TRUE) THEN
3031        l_line_index := l_mo_line_tbl.NEXT(l_line_index);
3032      ELSE
3033        --Don't increment the line index and turn off the reloop variable
3034        l_model_reloop := FALSE;
3035     END IF;
3036    END LOOP;
3037 
3038    IF is_debug then
3039      print_debug('after calling inv_pick_release_pvt',
3040 	       'Inv_Pick_Release_Pub.Pick_Release');
3041    END IF;
3042 
3043     -- To ensure that lock_flag should not get updated to Y unnecessarily i.e., only change needed only when high volume related code executes
3044     -- WMS installed should be true
3045     -- Auto Pick Confirm should be no
3046     -- The profile value of WMS_ASSIGN_TASK_TYPE should be NULL or YES(default)
3047     -- Value of p_skip_cartonization passed as TRUE only when parallel pick release happens
3048     IF  l_wms_installed AND p_auto_pick_confirm = 2 AND l_do_cartonization = 1 AND p_skip_cartonization = TRUE THEN
3049       BEGIN
3050         IF is_debug THEN
3051           print_debug('Updating lock_flag of MMTT records','Inv_Pick_Release_Pub.Pick_Release');
3052         END IF;
3053         FORALL ii IN l_mol_id_tbl.FIRST..l_mol_id_tbl.LAST
3054           update mtl_material_transactions_temp
3055           set lock_flag = 'Y'
3056           where move_order_line_id =l_mol_id_tbl(ii);
3057       EXCEPTION
3058       WHEN OTHERS THEN
3059         IF is_debug THEN
3060           print_debug('Error in updating MMTT records lock_flag: ' || sqlerrm
3061                      ,'Inv_Pick_Release_Pub.Pick_Release');
3062         END IF;
3063         RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
3064       END;
3065     END IF;
3066 
3067    -- Bug 4349602: Deleting Move Order Lines which are not allocated
3068    BEGIN
3069       IF is_debug THEN
3070          print_debug('Deleting MOLs in status 5','Inv_Pick_Release_Pub.Pick_Release');
3071       END IF;
3072       FORALL ii IN l_mol_id_tbl.FIRST..l_mol_id_tbl.LAST
3073         DELETE FROM mtl_txn_request_lines  mtrl
3074          WHERE line_status = 5
3075            AND line_id = l_mol_id_tbl(ii)
3076            AND EXISTS
3077              ( SELECT 'x'
3078                  FROM mtl_system_items  msi
3079                 WHERE msi.organization_id = mtrl.organization_id
3080                   AND msi.inventory_item_id = mtrl.inventory_item_id
3081                   AND NVL(msi.reservable_type,1) = 1
3082              );
3083    EXCEPTION
3084      WHEN OTHERS THEN
3085        IF is_debug THEN
3086           print_debug('Error in Deleting Move Order Lines: ' || sqlerrm
3087                      ,'Inv_Pick_Release_Pub.Pick_Release');
3088        END IF;
3089        RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
3090    END;
3091 
3092    IF l_wms_installed THEN
3093       -- 09/14/2000 added call to cartonization api
3094       l_line_index := l_mo_line_tbl.FIRST;
3095       l_api_return_status := '';
3096       IF is_debug THEN
3097 	 print_Debug('l_mo_line_tbl.count is ' || l_mo_line_tbl.COUNT,
3098 		     'Inv_Pick_Release_pub.Pick_Release');
3099       END IF;
3100       -- Calling device integration api to set global var which will decide
3101       -- whether to process device request or not, if it is a WMS organization.
3102       IF wms_device_integration_pvt.wms_call_device_request IS NULL THEN
3103 	 -- Bug# 4491974
3104 	 -- Changed l_mo_line_tbl(1).organization_id to l_mo_line_tbl(l_line_index).organization_id
3105 	 -- since it is possible to have null value at 1 which will lead to ORA-1403 error.
3106 	 wms_device_integration_pvt.is_device_set_up(
3107 						     --l_mo_line_tbl(1).organization_id,
3108 						     l_mo_line_tbl(l_line_index).organization_id,
3109 						     11,
3110 						     l_api_return_status);
3111       END IF;
3112 
3113       IF (l_do_cartonization = 1 AND NOT p_skip_cartonization) THEN --Added for bug3237702
3114 	 LOOP
3115 	    If is_debug then
3116 	       print_debug('headeR_id for line index ' || l_line_index || ' is ' ||
3117 			   l_mo_line_tbl(l_line_index).header_id,
3118 			   'Inv_Pick_Release_Pub.Pick_Release');
3119 	    End If;
3120 
3121 	    IF l_line_index >= l_mo_line_tbl.COUNT THEN
3122 	       -- it's the last line in this group
3123 	       If is_debug then
3124 		  print_debug('calling cartonize api',
3125 			      'Inv_Pick_Release_Pub.Pick_Release');
3126 	       End If;
3127 
3128 	       WMS_CARTNZN_PUB.cartonize
3129 		 (
3130 		  p_api_version           => 1,
3131 		  p_init_msg_list         => fnd_api.g_false,
3132 		  p_commit                => fnd_api.g_false,
3133 		  p_validation_level      => fnd_api.g_valid_level_full,
3134 		  x_return_status         => l_api_return_status,
3135 		  x_msg_count             => x_msg_count,
3136 		  x_msg_data              => x_msg_data,
3137 		  p_out_bound             => 'Y',
3138 		  p_org_id                => l_mo_line_tbl(l_line_index).organization_id,
3139 		  p_move_order_header_id  => l_mo_line_tbl(l_line_index).header_id
3140 		  );
3141 
3142 	       IF l_api_return_status = fnd_api.g_ret_sts_unexp_error OR
3143 		 l_api_return_status = fnd_api.g_ret_sts_error THEN
3144 		  If is_debug then
3145 		     print_debug('error from cartonize api',
3146 				 'Inv_Pick_Release_Pub.Pick_Release');
3147 		     print_debug('error count ' || x_msg_count,
3148 				 'Inv_Pick_Release_Pub.Pick_Release');
3149 		     print_debug('error msg ' || x_msg_data,
3150 				 'Inv_Pick_Release_Pub.Pick_Release');
3151 		     x_return_status := fnd_api.g_ret_sts_error;
3152 		  End If;
3153 		ELSE  -- patchset J bulk picking
3154 		  IF (WMS_CONTROL.G_CURRENT_RELEASE_LEVEL >= INV_RELEASE.G_J_RELEASE_LEVEL) THEN
3155 		     IF (is_debug) THEN
3156 			print_debug('PATCHSET J -- BULK PICKING --- START',
3157 				    'Inv_Pick_Release_Pub.Pick_Release');
3158 		     END IF;
3159 		     assign_pick_slip_number
3160 		       (x_return_status	        => l_api_return_status,
3161 			x_msg_count       	=> x_msg_count,
3162 			x_msg_data        	=> x_msg_data,
3163 			p_move_order_header_id  => l_mo_line_tbl(l_line_index).header_id,
3164 			p_ps_mode               => l_print_mode,
3165 			p_grouping_rule_id	=> p_grouping_rule_id,
3166 			p_allow_partial_pick    => p_allow_partial_pick);
3167 
3168 		     IF l_api_return_status = fnd_api.g_ret_sts_unexp_error OR
3169 		       l_api_return_status = fnd_api.g_ret_sts_error THEN
3170 			print_debug('error from assign_pick_slip_number api',
3171 				    'Inv_Pick_Release_Pub.Pick_Release');
3172 			print_debug('error count ' || x_msg_count,
3173 				    'Inv_Pick_Release_Pub.Pick_Release');
3174 			print_debug('error msg ' || x_msg_data,
3175 				    'Inv_Pick_Release_Pub.Pick_Release');
3176 			x_return_status := fnd_api.g_ret_sts_error;
3177 		     END IF;
3178 		     IF (is_debug) THEN
3179 			print_debug('PATCHSET J -- BULK PICKING --- END',
3180 				    'Inv_Pick_Release_Pub.Pick_Release');
3181 		     END IF;
3182 		  END IF;
3183 	       END IF;
3184 	       EXIT;
3185 
3186 	     ELSIF l_mo_line_tbl(l_line_index).header_id =
3187                    l_mo_line_tbl(l_mo_line_tbl.NEXT(l_line_index)).header_id THEN
3188                  l_line_index := l_mo_line_tbl.NEXT(l_line_index);  --Changed bug4102518;
3189 	     ELSE
3190 	       -- call cartonize API
3191 	       If is_debug then
3192 		  print_debug('calling cartonize api',
3193 			      'Inv_Pick_Release_Pub.Pick_Release');
3194 	       End If;
3195 
3196 	       WMS_CARTNZN_PUB.cartonize
3197 		 (
3198 		  p_api_version           => 1,
3199 		  p_init_msg_list         => fnd_api.g_false,
3200 		  p_commit                => fnd_api.g_false,
3201 		  p_validation_level      => fnd_api.g_valid_level_full,
3202 		  x_return_status         => l_api_return_status,
3203 		  x_msg_count             => x_msg_count,
3204 		  x_msg_data              => x_msg_data,
3205 		  p_out_bound             => 'Y',
3206 		  p_org_id                => l_mo_line_tbl(l_line_index).organization_id,
3207 		  p_move_order_header_id  => l_mo_line_tbl(l_line_index).header_id
3208 		  );
3209 
3210 	       IF l_api_return_status = fnd_api.g_ret_sts_unexp_error OR
3211 		 l_api_return_status = fnd_api.g_ret_sts_error THEN
3212 		  If is_debug then
3213 		     print_debug('error from cartonize api',
3214 				 'Inv_Pick_Release_Pub.Pick_Release');
3215 		     print_debug('error count ' || x_msg_count,
3216 				 'Inv_Pick_Release_Pub.Pick_Release');
3217 		     print_debug('error msg ' || x_msg_data,
3218 				 'Inv_Pick_Release_Pub.Pick_Release');
3219 		  End If;
3220 		  x_return_status := fnd_api.g_ret_sts_error;
3221 		ELSE  -- patchset J bulk picking
3222 		  IF (WMS_CONTROL.G_CURRENT_RELEASE_LEVEL >= INV_RELEASE.G_J_RELEASE_LEVEL) THEN
3223 		     IF (is_debug) THEN
3224 			print_debug('PATCHSET J -- BULK PICKING --- START',
3225 				    'Inv_Pick_Release_Pub.Pick_Release');
3226 			print_debug('calling assign_pick_slip_number',
3227 				    'Inv_Pick_Release_Pub.Pick_Release');
3228 		     END IF;
3229 
3230 		     assign_pick_slip_number
3231 		       (x_return_status	        => l_api_return_status,
3232 			x_msg_count       	=> x_msg_count,
3233 			x_msg_data        	=> x_msg_data,
3234 			p_move_order_header_id  => l_mo_line_tbl(l_line_index).header_id,
3235 			p_ps_mode               => l_print_mode,
3236 			p_grouping_rule_id	=> p_grouping_rule_id,
3237 			p_allow_partial_pick    => p_allow_partial_pick);
3238 
3239 		     IF l_api_return_status = fnd_api.g_ret_sts_unexp_error OR
3240 		       l_api_return_status = fnd_api.g_ret_sts_error THEN
3241 			print_debug('error from assign_pick_slip_number api',
3242 				    'Inv_Pick_Release_Pub.Pick_Release');
3243 			print_debug('error count ' || x_msg_count,
3244 				    'Inv_Pick_Release_Pub.Pick_Release');
3245 			print_debug('error msg ' || x_msg_data,
3246 				    'Inv_Pick_Release_Pub.Pick_Release');
3247 			x_return_status := fnd_api.g_ret_sts_error;
3248 		     END IF;
3249 		     IF (is_debug) THEN
3250 			print_debug('PATCHSET J -- BULK PICKING --- END',
3251 				    'Inv_Pick_Release_Pub.Pick_Release');
3252 		     END IF;
3253 		  END IF;
3254 	       END IF;
3255 
3256 	       IF is_debug THEN
3257 		  print_debug('success from cartonize api',
3258 			      'Inv_Pick_Release_Pub.Pick_Release');
3259 	       END IF;
3260 	       l_line_index := l_line_index + 1;
3261 	    END IF;
3262 	    EXIT WHEN l_line_index > l_mo_line_tbl.LAST;
3263 	 END LOOP;
3264       END IF; -- Do cartonization?? --Added bug3237702
3265    END IF;  -- wms installed
3266 
3267    -- At this point, each Move Order Line has been processed.
3268    -- If automatic pick confirmation is chosen, call pick confirm now.
3269    IF l_auto_pick_confirm = 1 THEN
3270 	NULL;
3271    END IF;
3272 
3273   -- bug 9130704
3274   -- Do not execute the label printing related code
3275   -- unnecessarily when doing parallel pick release (p_skip_cartonization set to TRUE)
3276  -- Start Bug 6696594
3277 IF (l_wms_installed AND NOT p_skip_cartonization) THEN
3278 	BEGIN
3279 	-- bug 9130704
3280 
3281     	IF (l_debug = 1) THEN
3282       		print_debug('Move header id: ' || l_mo_line_tbl(l_mo_line_tbl.FIRST).header_id, 'Inv_Pick_Release_Pub.Pick_Release');
3283     	END IF;
3284 
3285     	OPEN c_wpr_casepick_labels(l_mo_line_tbl(l_mo_line_tbl.FIRST).header_id);
3286 
3287     	LOOP --{
3288         	FETCH c_wpr_casepick_labels BULK COLLECT
3289          	INTO v_transaction_id LIMIT 1000;
3290 
3291         	EXIT WHEN v_transaction_id.COUNT = 0;
3292 
3293         	IF (l_debug = 1) THEN
3294           		print_debug('Calling print_label with v_transaction_id.count : ' || v_transaction_id.COUNT, 'Inv_Pick_Release_Pub.Pick_Release');
3295         	END IF;
3296 
3297 		l_return_status := fnd_api.g_ret_sts_success;
3298 
3299         	inv_label.print_label (
3300 				x_return_status      => l_return_status
3301 				, x_msg_count          => x_msg_count
3302 				, x_msg_data           => x_msg_data
3303 				, x_label_status       => l_label_status
3304 				, p_api_version        => 1.0
3305 				, p_print_mode         => 1
3306 				, p_business_flow_code => 42  --Business Flow Pick Release
3307 				, p_transaction_id     => v_transaction_id);
3308 
3309 		IF ( l_return_status <> fnd_api.g_ret_sts_success ) THEN
3310 			IF (l_debug = 1) THEN
3311 				print_debug('failed to print labels', 'Inv_Pick_Release_Pub.Pick_Release');
3312 			END IF;
3313 			fnd_message.set_name('WMS','WMS_PRINT_LABEL_FAIL');
3314 			fnd_msg_pub.ADD;
3315 		END IF;
3316 
3317 
3318      	END LOOP; --}
3319 
3320      	IF c_wpr_casepick_labels%ISOPEN THEN
3321        	 CLOSE c_wpr_casepick_labels;
3322      	END IF;
3323 
3324 	EXCEPTION
3325 	WHEN OTHERS THEN
3326 		IF (l_debug = 1) THEN
3327 			print_debug('Exception occured while calling print_label', 'Inv_Pick_Release_Pub.Pick_Release');
3328 		END IF;
3329 		fnd_message.set_name('WMS', 'WMS_PRINT_LABEL_FAIL');
3330 		fnd_msg_pub.ADD;
3331 
3332 		IF c_wpr_casepick_labels%ISOPEN THEN
3333 	         CLOSE c_wpr_casepick_labels;
3334         	END IF;
3335 
3336 	END;
3337 END IF;
3338 --END Bug 6696594
3339 
3340 
3341    -- Call Device Integration API to send the details of this
3342    -- PickRelease Wave to devices, if it is a WMS organization.
3343    -- All the MoveOrderLines should have the same MO Header Id. So
3344    -- picking the FIRST line's Header Id
3345    -- Note: We don't check for the return condition of this API as
3346    -- we let the PickRelease process succeed whether DeviceIntegration
3347    -- succeeds or fails.
3348    --
3349    -- bug 9130704: WMS_DEVICE_INTEGRATION_PVT.device_request should not
3350    -- be called for parallel pick release
3351 
3352    IF (l_wms_installed AND NOT p_skip_cartonization) THEN
3353       WMS_DEVICE_INTEGRATION_PVT.device_request
3354 	(p_bus_event      => WMS_DEVICE_INTEGRATION_PVT.WMS_BE_PICK_RELEASE,
3355 	 p_call_ctx       => WMS_Device_integration_pvt.DEV_REQ_AUTO,
3356 	 p_task_trx_id    => l_mo_line_tbl(l_mo_line_tbl.FIRST).header_id,
3357     -- Bug 6401204 Passing the Organization id as WCS API isn't called correctly
3358     p_org_id         => l_mo_line_tbl(l_mo_line_tbl.FIRST).organization_id,
3359 	 x_request_msg    =>  l_req_msg,
3360 	 x_return_status  =>  l_api_return_status,
3361 	 x_msg_count      => x_msg_count,
3362 	 x_msg_data       => x_msg_data
3363 	 );
3364       IF is_debug THEN
3365 	 print_debug('Device_API: return stat:'||l_api_return_status,
3366 		     'PICKREL');
3367       END IF;
3368    END IF;
3369 
3370    -- Bug 2776309
3371    -- The below call should never backorder but if this
3372    -- happens then do not check l_cur_ship_model_id
3373    --IF l_cur_ship_model_id is not NULL then
3374    --2509322
3375    backorder_smc_details(l_api_return_status,
3376 			 x_msg_data,
3377 			 x_msg_count);
3378    IF l_api_return_status = fnd_api.g_ret_sts_error THEN
3379       RAISE fnd_api.g_exc_error;
3380     ELSIF l_api_return_status = fnd_api.g_ret_sts_unexp_error THEN
3381       RAISE fnd_api.g_exc_unexpected_error;
3382    END IF;
3383    -- END IF;
3384 
3385    --bug 2408329: Since Quantity trees are cached and not built in a pick release
3386    --session, available qty seen is wrong during a blanket pick release.
3387    --Now Clear_cache after pick release so as to ensure when new locks are
3388    --obtained, the tree is built with latest db state.
3389    inv_quantity_tree_grp.clear_quantity_cache;
3390 
3391    -- Bug# 4258360: For allocation modes of I (Inventory Only) or
3392    -- X (Prioritize Crossdock), allocation (both from inventory and crossdock)
3393    -- has completed.  We need to remove the backordered lines from
3394    -- p_trolin_delivery_ids and p_del_detail_id tables so deliveries are not
3395    -- autocreated for them later on by Shipping.
3396    -- UPDATE: Do not need to do this logic anymore.  Shipping does not populate the delivery
3397    -- tables inputted.  Those are only used to store crossdocked lines for creation of deliveries.
3398    -- {{
3399    -- Run PR in Inventory Only mode and ensure no delivery exists for WDD
3400    -- Also ensure that the WDD is not allocated. After PR completes
3401    -- WDD should be back ordered and no delivery should exist for it.
3402    -- }}
3403    -- {{
3404    -- Run PR in Prioritize Xdock mode and ensure no delivery exists for WDD
3405    -- Also ensure that the WDD is not allocated. After PR completes
3406    -- WDD should be back ordered and no delivery should exist for it.
3407    -- }}
3408    /*IF (l_allocation_method IN (g_inventory_only, g_prioritize_crossdock) AND
3409        p_del_detail_id.COUNT > 0) THEN
3410       IF (is_debug) THEN
3411 	 print_debug('Remove the backordered WDD lines from the inputted delivery tables: ' ||
3412 		     l_allocation_method, 'Inv_Pick_Release_Pub.Pick_Release');
3413       END IF;
3414       l_xdock_index := p_del_detail_id.FIRST;
3415       l_xdock_next_index := p_del_detail_id.FIRST;
3416       -- Loop through table p_del_detail_id.  If that WDD is backordered (value exists in
3417       -- l_backordered_wdd_tbl), then delete that entry from p_del_detail_id and the corresponding
3418       -- one in p_trolin_delivery_ids.
3419       LOOP
3420 	 l_xdock_index := l_xdock_next_index;
3421 	 l_xdock_next_index := p_del_detail_id.NEXT(l_xdock_next_index);
3422 	 -- Exit out of loop when l_xdock_index is null, meaning we have
3423 	 -- reached the last entry in the table.
3424 	 EXIT WHEN l_xdock_index IS NULL;
3425 
3426 	 IF (l_backordered_wdd_tbl.EXISTS(p_del_detail_id(l_xdock_index))) THEN
3427 	    p_del_detail_id.DELETE(l_xdock_index);
3428 	    p_trolin_delivery_ids.DELETE(l_xdock_index);
3429 	 END IF;
3430       END LOOP;
3431    END IF;*/
3432 
3433    -- Bug# 4258360: For allocation modes of N (Prioritize Inventory), call the
3434    -- Crossdock Pegging API here since inventory allocation has been completed
3435    IF (l_allocation_method = g_prioritize_inventory) THEN
3436       IF (is_debug) THEN
3437 	 print_debug('Call the Planned_Cross_Dock API (Prioritize Inventory)',
3438 		     'Inv_Pick_Release_Pub.Pick_Release');
3439       END IF;
3440       WMS_XDOCK_PEGGING_PUB.Planned_Cross_Dock
3441 	(p_api_version		=> 1.0,
3442 	 p_init_msg_list	=> fnd_api.g_false,
3443 	 p_commit		=> fnd_api.g_false,
3444 	 x_return_status        => l_api_return_status,
3445 	 x_msg_count            => x_msg_count,
3446 	 x_msg_data             => x_msg_data,
3447 	 p_batch_id             => INV_CACHE.wpb_rec.batch_id,
3448 	 p_wsh_release_table    => p_wsh_release_table,
3449 	 p_trolin_delivery_ids  => p_trolin_delivery_ids,
3450 	 p_del_detail_id        => p_del_detail_id);
3451 
3452       IF (l_api_return_status = FND_API.G_RET_STS_SUCCESS) THEN
3453 	 IF (is_debug) THEN
3454 	    print_debug('Success returned from Planned_Cross_Dock API',
3455 			'Inv_Pick_Release_Pub.Pick_Release');
3456 	 END IF;
3457        ELSIF (l_api_return_status = FND_API.G_RET_STS_ERROR) THEN
3458 	 IF (is_debug) THEN
3459 	    print_debug('Error returned from Planned_Cross_Dock API',
3460 			'Inv_Pick_Release_Pub.Pick_Release');
3461 	 END IF;
3462 	 RAISE FND_API.G_EXC_ERROR;
3463        ELSIF (l_api_return_status = FND_API.G_RET_STS_UNEXP_ERROR) THEN
3464 	 IF (is_debug) THEN
3465 	    print_debug('Unexpected error returned from Planned_Cross_Dock API',
3466 			'Inv_Pick_Release_Pub.Pick_Release');
3467 	 END IF;
3468 	 RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
3469       END IF;
3470    END IF;
3471 
3472    -- Standard call to commit
3473    IF p_commit = fnd_api.g_true THEN
3474       COMMIT;
3475    END IF;
3476 
3477    -- Standard call to get message count and if count is 1, get message info
3478    IF is_debug THEN
3479       print_Debug('x_return_status is ' || x_return_status,
3480 		  'Inv_Pick_Release_Pub.Pick_Release');
3481    END IF;
3482 
3483    inv_cache.mo_transaction_date := NULL;
3484    l_return_value := inv_cache.set_pick_release(FALSE); --Added bug3237702
3485    inv_log_util.g_maintain_log_profile := FALSE;
3486 
3487 EXCEPTION
3488    WHEN FND_API.G_EXC_ERROR THEN
3489       --
3490       x_return_status := FND_API.G_RET_STS_ERROR;
3491       l_return_value := inv_cache.set_pick_release(FALSE); --Added bug3237702
3492       inv_log_util.g_maintain_log_profile := TRUE;
3493       --
3494       FND_MSG_PUB.Count_And_Get(p_count => x_msg_count
3495 				, p_data => x_msg_data);
3496       --
3497    WHEN FND_API.G_EXC_UNEXPECTED_ERROR THEN
3498       --
3499       x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
3500       l_return_value := inv_cache.set_pick_release(FALSE); --Added bug3237702
3501       inv_log_util.g_maintain_log_profile := TRUE;
3502       --
3503       FND_MSG_PUB.Count_And_Get(p_count => x_msg_count
3504 				, p_data => x_msg_data);
3505       --
3506    WHEN OTHERS THEN
3507       IF is_debug THEN
3508          print_Debug('Other error: ' || sqlerrm,
3509                      'Inv_Pick_Release_Pub.Pick_Release');
3510       END IF;
3511 
3512       ROLLBACK TO Pick_Release_PUB;
3513       --
3514       l_return_value := inv_cache.set_pick_release(FALSE); --Added bug3237702
3515       inv_log_util.g_maintain_log_profile := TRUE;
3516       x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
3517       --
3518       IF FND_MSG_PUB.Check_Msg_Level(FND_MSG_PUB.G_MSG_LVL_UNEXP_ERROR) THEN
3519 	 FND_MSG_PUB.Add_Exc_Msg(G_PKG_NAME, l_api_name);
3520       END IF;
3521       --
3522       FND_MSG_PUB.Count_And_Get(p_count => x_msg_count
3523 				, p_data => x_msg_data);
3524 END Pick_Release;
3525 
3526 
3527 -- Start of Comments
3528 -- API name 	Reserve_Unconfirmed_Quantity
3529 -- Type		Public
3530 --
3531 -- Purpose
3532 --   Transfers a reservation on material which is missing or damaged to an
3533 -- 	    appropriate demand source.
3534 --
3535 -- Input Parameters
3536 --   p_missing_quantity
3537 --       The quantity to be transferred to a Cycle Count reservation, in the primary
3538 --	    UOM for the item.
3539 --	p_organization_id
3540 --	    The organization in which the reservation(s) should be created
3541 --	p_reservation_id
3542 --	    The reservation to transfer quantity from (not required if demand source
3543 --	    parameters are given).
3544 --	p_demand_source_type_id
3545 --	    The demand source type ID for the reservation to be transferred
3546 --   p_demand_source_header_id
3547 --	    The demand source header ID for the reservation to be transferred
3548 --	p_demand_source_line_id
3549 --	    The demand source line ID for the reservation to be transferred
3550 --	p_inventory_item_id
3551 --	    The item which is missing or damaged.
3552 --	p_subinventory_code
3553 --	    The subinventory in which the material is missing or damaged.
3554 --   p_locator_id
3555 --	    The locator in which the material is missing or damaged.
3556 --	p_revision
3557 --	    The revision of the item which is missing or damaged.
3558 --	p_lot_number
3559 --	    The lot number of the item which is missing or damaged.
3560 --
3561 -- Output Parameters
3562 --   x_return_status
3563 --       if the pick release process succeeds, the value is
3564 --			fnd_api.g_ret_sts_success;
3565 --       if there is an expected error, the value is
3566 --             fnd_api.g_ret_sts_error;
3567 --       if there is an unexpected error, the value is
3568 --             fnd_api.g_ret_sts_unexp_error;
3569 --   x_msg_count
3570 --       if there is one or more errors, the number of error messages
3571 --       	in the buffer
3572 --   x_msg_data
3573 --       if there is one and only one error, the error message
3574 --   (See fnd_api package for more details about the above output parameters)
3575 --
3576 
3577 -- HW INVCONV added p_missing_quantity2
3578 
3579 PROCEDURE Reserve_Unconfirmed_Quantity
3580   (
3581       p_api_version			IN  	NUMBER
3582       ,p_init_msg_list			IN  	VARCHAR2 DEFAULT fnd_api.g_false
3583       ,p_commit				IN	VARCHAR2 DEFAULT fnd_api.g_false
3584       ,x_return_status        		OUT 	NOCOPY VARCHAR2
3585       ,x_msg_count            		OUT 	NOCOPY NUMBER
3586       ,x_msg_data             		OUT 	NOCOPY VARCHAR2
3587       ,p_missing_quantity		IN	NUMBER
3588       ,p_missing_quantity2		IN	NUMBER DEFAULT fnd_api.g_miss_num
3589       ,p_reservation_id			IN	NUMBER DEFAULT fnd_api.g_miss_num
3590       ,p_demand_source_header_id	IN	NUMBER DEFAULT fnd_api.g_miss_num
3591       ,p_demand_source_line_id		IN	NUMBER DEFAULT fnd_api.g_miss_num
3592       ,p_organization_id		IN	NUMBER DEFAULT fnd_api.g_miss_num
3593       ,p_inventory_item_id		IN	NUMBER DEFAULT fnd_api.g_miss_num
3594       ,p_subinventory_code		IN	VARCHAR2 DEFAULT fnd_api.g_miss_char
3595       ,p_locator_id			IN	NUMBER DEFAULT fnd_api.g_miss_num
3596       ,p_revision			IN	VARCHAR2 DEFAULT fnd_api.g_miss_char
3597       ,p_lot_number			IN	VARCHAR2 DEFAULT fnd_api.g_miss_char
3598   ) IS
3599       l_api_version	CONSTANT NUMBER := 1.0;
3600       l_api_name	CONSTANT VARCHAR2(30) := 'Reserve_Unconfirmed_Quantity';
3601 
3602       l_reservation_id		NUMBER;	-- The reservation to transfer quantity from
3603 					-- If invoked at Pick Confirm, this will
3604 					-- typically be passed in as a parameter,
3605 					-- based on the reservation tied to the Move
3606 					-- Order Line Detail which is being Pick
3607 					-- Confirmed.  If invoked at Ship Confirm,
3608 					-- this will most likely be derived from the
3609 					-- demand and supply source parameters.
3610       l_reservation_rec		INV_Reservation_GLOBAL.MTL_RESERVATION_REC_TYPE;
3611 					-- Temporary reservation record for retrieving
3612 					-- the reservation to transfer.
3613       l_reservation_count	NUMBER;	-- The number of reservations which match the
3614 					-- demand/supply source parameters passed in.
3615       l_cc_reservation_rec	INV_Reservation_GLOBAL.MTL_RESERVATION_REC_TYPE;
3616 					-- Temporary reservation record for the amount
3617 					-- to be transferred to Cycle Count.
3618       l_reservations_tbl	INV_Reservation_GLOBAL.MTL_RESERVATION_TBL_TYPE;
3619 					-- The table of reservations for given
3620 					-- supply and demand source
3621       l_dummy_sn  		INV_Reservation_GLOBAL.SERIAL_NUMBER_TBL_TYPE;
3622       l_new_rsv_id		NUMBER;	-- The reservation ID that has been transferred
3623 					-- to or updated
3624       l_mso_header_id		NUMBER; -- The header ID for the record in
3625 					-- MTL_SALES_ORDERS that corresponds to the OE
3626 					-- header and line passed in.
3627       l_api_return_status	VARCHAR2(1);
3628 					-- The return status of APIs called
3629 					-- within this API.
3630       l_api_error_code		NUMBER; -- The error code of APIs called within
3631 					-- this API.
3632     l_debug number := NVL(FND_PROFILE.VALUE('INV_DEBUG_TRACE'),0);
3633 BEGIN
3634    -- Set savepoint for this API
3635    SAVEPOINT Reserve_Unconfirmed_Qty_PUB;
3636 
3637    -- Standard Call to check for call compatibility
3638    IF NOT fnd_api.Compatible_API_Call(l_api_version
3639 				      , p_api_version
3640 				      , l_api_name
3641 				      , G_PKG_NAME) THEN
3642       RAISE fnd_api.g_exc_unexpected_error;
3643    END IF;
3644 
3645    -- Initialize message list if p_init_msg_list is set to true
3646    IF fnd_api.to_Boolean(p_init_msg_list) THEN
3647       fnd_msg_pub.initialize;
3648    END IF;
3649 
3650    -- Initialize API return status to success
3651    x_return_status := fnd_api.g_ret_sts_success;
3652 
3653    -- Validate parameters
3654 
3655    -- First make sure that missing quantity is not <= 0
3656    IF p_missing_quantity <= 0 THEN
3657       FND_MESSAGE.SET_NAME('INV','INV_NO_QTY_TO_TRANSFER');
3658       FND_MSG_PUB.Add;
3659       RAISE fnd_api.g_exc_unexpected_error;
3660    END IF;
3661 
3662    -- Determine whether the reservation id was given, or if it must be derived
3663    -- based on the supply source parameters.
3664    IF p_reservation_id <> fnd_api.g_miss_num AND
3665       p_reservation_id IS NOT NULL THEN
3666      -- Initialize the reservation querying record with the reservation ID
3667      l_reservation_id := p_reservation_id;
3668      l_reservation_rec.reservation_id := l_reservation_id;
3669    ELSE
3670      -- Initialize the reservation record with the demand/supply source
3671      -- information.  At minimum, must have a demand source type, line and header,
3672      -- and an item and organization ID
3673      IF	p_inventory_item_id = fnd_api.g_miss_num OR
3674 	p_inventory_item_id IS NULL OR
3675 	p_organization_id = fnd_api.g_miss_num OR
3676 	p_organization_id IS NULL OR
3677 	p_demand_source_header_id = fnd_api.g_miss_num OR
3678 	p_demand_source_header_id IS NULL OR
3679 	p_demand_source_line_id = fnd_api.g_miss_num OR
3680 	p_demand_source_line_id IS NULL THEN
3681           FND_MESSAGE.SET_NAME('INV','INV_COULD_NOT_ID_RSV');
3682 	  FND_MSG_PUB.Add;
3683 	  RAISE fnd_api.g_exc_unexpected_error;
3684      END IF;
3685 
3686      -- First attempt to convert the demand source header id given
3687      -- (the OE header id) to the MTL_SALES_ORDERS id to be used.
3688      /*l_mso_header_id :=
3689 	inv_salesorder.get_salesorder_for_oeheader(p_demand_source_header_id);
3690      IF l_mso_header_id IS NULL THEN
3691 	FND_MESSAGE.SET_NAME('INV','INV_COULD_NOT_GET_MSO_HEADER');
3692 	FND_MSG_PUB.Add;
3693 	RAISE fnd_api.g_exc_unexpected_error;
3694      END IF;*/
3695 
3696      l_reservation_rec.inventory_item_id := p_inventory_item_id;
3697      l_reservation_rec.organization_id := p_organization_id;
3698      l_reservation_rec.demand_source_type_id :=
3699 			INV_Reservation_GLOBAL.g_source_type_oe;
3700      l_reservation_rec.demand_source_header_id := p_demand_source_header_id;
3701      l_reservation_rec.demand_source_line_id := p_demand_source_line_id;
3702      -- R12 Crossdock changes
3703      l_reservation_rec.demand_source_line_detail := NULL;
3704 
3705      IF p_subinventory_code <> fnd_api.g_miss_char THEN
3706 	l_reservation_rec.subinventory_code := p_subinventory_code;
3707      ELSE
3708 	l_reservation_rec.subinventory_code := NULL;
3709      END IF;
3710 
3711      IF p_locator_id <> fnd_api.g_miss_num THEN
3712 	l_reservation_rec.locator_id := p_locator_id;
3713      ELSE
3714 	l_reservation_rec.locator_id := NULL;
3715      END IF;
3716 
3717      IF p_revision <> fnd_api.g_miss_char THEN
3718 	l_reservation_rec.revision := p_revision;
3719      ELSE
3720 	l_reservation_rec.revision := NULL;
3721      END IF;
3722 
3723      IF p_lot_number <> fnd_api.g_miss_char THEN
3724 	l_reservation_rec.lot_number := p_lot_number;
3725      ELSE
3726 	l_reservation_rec.lot_number := NULL;
3727      END IF;
3728    END IF;
3729 
3730    -- Retrieve the reservation information
3731    INV_Reservation_PUB.Query_Reservation
3732    (
3733 	p_api_version_number		=> 1.0
3734 	, p_init_msg_lst		=> fnd_api.g_false
3735 	, x_return_status		=> l_api_return_status
3736 	, x_msg_count			=> x_msg_count
3737 	, x_msg_data			=> x_msg_data
3738 	, p_query_input			=> l_reservation_rec
3739 	, x_mtl_reservation_tbl		=> l_reservations_tbl
3740 	, x_mtl_reservation_tbl_count	=> l_reservation_count
3741 	, x_error_code			=> l_api_error_code
3742    );
3743    -- Return an error if the query reservations call failed
3744    IF l_api_return_status <> fnd_api.g_ret_sts_success THEN
3745       FND_MESSAGE.SET_NAME('INV','INV_QRY_RSV_FAILED');
3746       FND_MSG_PUB.Add;
3747       RAISE fnd_api.g_exc_unexpected_error;
3748    END IF;
3749 
3750    -- Only 1 reservation record should have been returned, since the parameters
3751    -- passed are supposed to uniquely identify a reservation record.
3752    IF l_reservation_count = 0 THEN
3753       FND_MESSAGE.SET_NAME('INV','INV_NO_RSVS_FOUND');
3754       FND_MSG_PUB.Add;
3755       RAISE fnd_api.g_exc_unexpected_error;
3756    END IF;
3757 
3758    IF l_reservation_count > 1 THEN
3759       FND_MESSAGE.SET_NAME('INV','INV_NON_UNIQUE_RSV');
3760       FND_MSG_PUB.Add;
3761       RAISE fnd_api.g_exc_unexpected_error;
3762    END IF;
3763 
3764    -- Determine whether the quantity to transfer is greater
3765    -- than the currently reserved quantity
3766    IF p_missing_quantity > l_reservations_tbl(1).primary_reservation_quantity THEN
3767       FND_MESSAGE.SET_NAME('INV','INV_INSUFF_QTY_RSV');
3768       FND_MSG_PUB.Add;
3769       RAISE fnd_api.g_exc_unexpected_error;
3770    END IF;
3771 
3772    -- Initialize the querying record with the reservation ID so that the update
3773    -- will be more efficient.
3774    l_reservation_rec.reservation_id := l_reservations_tbl(1).reservation_id;
3775 
3776    -- Validation complete - ready to transfer reservation to appropriate source
3777    l_cc_reservation_rec.primary_reservation_quantity := p_missing_quantity;
3778    l_cc_reservation_rec.primary_uom_code := l_reservations_tbl(1).primary_uom_code;
3779    l_cc_reservation_rec.detailed_quantity := 0;
3780    l_cc_reservation_rec.demand_source_type_id := 9;
3781 -- HW INVCONV
3782    l_cc_reservation_rec.secondary_reservation_quantity := p_missing_quantity2;
3783    l_cc_reservation_rec.secondary_uom_code := l_reservations_tbl(1).secondary_uom_code;
3784    l_cc_reservation_rec.secondary_detailed_quantity := 0;
3785 -- End of HW INVCONV
3786    l_cc_reservation_rec.demand_source_header_id := -1;
3787    l_cc_reservation_rec.demand_source_line_id := -1;
3788    -- R12 Crossdock changes
3789    l_cc_reservation_rec.demand_source_line_detail := -1;
3790 
3791    l_cc_reservation_rec.subinventory_code := p_subinventory_code;
3792 	 l_cc_reservation_rec.locator_id := p_locator_id;
3793    l_cc_reservation_rec.revision := p_revision;
3794    l_cc_reservation_rec.lot_number := p_lot_number;
3795 
3796    -- Make the call to the Transfer Reservation API
3797    INV_Reservation_PUB.Transfer_Reservation
3798    (
3799 	p_api_version_number          => 1.0
3800 	, p_init_msg_lst              => fnd_api.g_true
3801 	, x_return_status             => l_api_return_status
3802 	, x_msg_count                 => x_msg_count
3803 	, x_msg_data                  => x_msg_data
3804 	, p_original_rsv_rec          => l_reservation_rec
3805 	, p_to_rsv_rec                => l_cc_reservation_rec
3806 	, p_original_serial_number    => l_dummy_sn
3807 	, p_to_serial_number          => l_dummy_sn
3808 	, p_validation_flag           => fnd_api.g_true
3809 	, x_to_reservation_id         => l_new_rsv_id
3810    );
3811    -- Return an error if the transfer reservations call failed
3812    IF l_api_return_status <> fnd_api.g_ret_sts_success THEN
3813       FND_MESSAGE.SET_NAME('INV','INV_TRANSFER_RSV_FAILED');
3814       FND_MSG_PUB.Add;
3815       RAISE fnd_api.g_exc_unexpected_error;
3816    END IF;
3817 
3818    -- Commit if necessary
3819    IF x_return_status <> fnd_api.g_ret_sts_success THEN
3820      ROLLBACK TO Reserve_Unconfirmed_Qty_PUB;
3821    ELSE
3822      -- Standard call to commit
3823      IF p_commit = fnd_api.g_true THEN
3824        COMMIT;
3825      END IF;
3826    END IF;
3827 
3828 EXCEPTION
3829      WHEN FND_API.G_EXC_ERROR THEN
3830      	--
3831      	x_return_status := FND_API.G_RET_STS_ERROR;
3832      	--
3833      	FND_MSG_PUB.Count_And_Get(p_count => x_msg_count
3834      	   , p_data => x_msg_data);
3835      	--
3836      WHEN FND_API.G_EXC_UNEXPECTED_ERROR THEN
3837      	--
3838      	x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
3839      	--
3840      	FND_MSG_PUB.Count_And_Get(p_count => x_msg_count
3841      	   , p_data => x_msg_data);
3842      	--
3843      WHEN OTHERS THEN
3844 	ROLLBACK TO Reserve_Unconfirmed_Qty_PUB;
3845      	--
3846      	x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
3847      	--
3848      	IF FND_MSG_PUB.Check_Msg_Level(FND_MSG_PUB.G_MSG_LVL_UNEXP_ERROR) THEN
3849      	   FND_MSG_PUB.Add_Exc_Msg(G_PKG_NAME, l_api_name);
3850      	END IF;
3851      	--
3852      	FND_MSG_PUB.Count_And_Get(p_count => x_msg_count
3853      	   , p_data => x_msg_data);
3854 END Reserve_Unconfirmed_Quantity;
3855 
3856 
3857 PROCEDURE call_cartonization (
3858          p_api_version              IN   NUMBER
3859          , p_init_msg_list          IN   VARCHAR2
3860          , p_commit                 IN   VARCHAR2
3861          , p_validation_level       IN   NUMBER
3862          , x_return_status          OUT NOCOPY VARCHAR2
3863          , x_msg_count              OUT NOCOPY NUMBER
3864          , x_msg_data               OUT NOCOPY VARCHAR2
3865          , p_out_bound              IN   VARCHAR2
3866          , p_org_id                 IN   NUMBER
3867          , p_move_order_header_id   IN   NUMBER
3868          , p_grouping_rule_id       IN   NUMBER
3869          , p_allow_partial_pick     IN   VARCHAR2
3870 ) IS
3871 
3872 l_print_mode     VARCHAR(1);
3873 l_debug          NUMBER;
3874 l_api_return_status    VARCHAR2(1);
3875 l_do_cartonization number := NVL(FND_PROFILE.VALUE('WMS_ASSIGN_TASK_TYPE'),1);
3876 
3877 BEGIN
3878    -- Set savepoint for this API
3879    SAVEPOINT PR_Call_cartonization;
3880 
3881    -- because the debug profile  rarely changes, only check it once per
3882    -- session, instead of once per batch
3883    IF is_debug IS NULL THEN
3884      l_debug := NVL(FND_PROFILE.VALUE('INV_DEBUG_TRACE'),0);
3885      if l_debug = 1 then
3886        is_debug := TRUE;
3887      else
3888        is_debug := FALSE;
3889      end if;
3890    END IF;
3891 
3892    IF l_do_cartonization = 1 THEN
3893    -- Determine what printing mode to use when pick releasing lines.
3894    IF g_organization_id IS NOT NULL AND
3895       g_organization_id = p_org_id AND
3896       g_print_mode IS NOT NULL THEN
3897 
3898      l_print_mode := g_print_mode;
3899    ELSE
3900 
3901     BEGIN
3902       SELECT print_pick_slip_mode, pick_grouping_rule_id
3903       INTO l_print_mode, g_org_grouping_rule_id
3904       FROM WSH_SHIPPING_PARAMETERS
3905       WHERE organization_id = p_org_id;
3906     EXCEPTION
3907       WHEN no_data_found THEN
3908         If is_debug then
3909           print_debug('Error: print_pick_slip_mode not defined',
3910                      'INV_Pick_Release_Pub.Pick_Release');
3911         End If;
3912         --ROLLBACK TO Pick_Release_PUB;
3913         FND_MESSAGE.SET_NAME('INV','INV_WSH_ORG_NOT_FOUND');
3914         FND_MSG_PUB.Add;
3915         RAISE fnd_api.g_exc_unexpected_error;
3916     END;
3917 
3918      g_organization_id := p_org_id;
3919      g_print_mode := l_print_mode;
3920    END IF;
3921 
3922    -- call cartonize API
3923    If is_debug then
3924       print_debug('calling cartonize api',
3925                    'Inv_Pick_Release_Pub.Pick_Release');
3926    End If;
3927 
3928    IF p_move_order_header_id <> -1 and  p_move_order_header_id <> 0 and p_move_order_header_id IS NOT NULL THEN
3929 	update mtl_material_transactions_temp
3930         set lock_flag = NULL
3931         where move_order_header_id  = p_move_order_header_id
3932         and organization_id = p_org_id
3933         and lock_flag is not null;
3934    END IF;
3935 
3936    WMS_CARTNZN_PUB.cartonize
3937         (
3938          p_api_version           => 1,
3939          p_init_msg_list         => fnd_api.g_false,
3940          p_commit                => fnd_api.g_false,
3941          p_validation_level      => fnd_api.g_valid_level_full,
3942          x_return_status         => l_api_return_status,
3943          x_msg_count             => x_msg_count,
3944          x_msg_data              => x_msg_data,
3945          p_out_bound             => 'Y',
3946          p_org_id          => p_org_id,
3947          p_move_order_header_id  => p_move_order_header_id
3948    );
3949    IF l_api_return_status = fnd_api.g_ret_sts_unexp_error OR
3950        l_api_return_status = fnd_api.g_ret_sts_error THEN
3951       If is_debug then
3952          print_debug('error from cartonize api',
3953                   'Inv_Pick_Release_Pub.Call_Cartonization');
3954          print_debug('error count ' || x_msg_count,
3955                   'Inv_Pick_Release_Pub.Call_Cartonization');
3956          print_debug('error msg ' || x_msg_data,
3957                   'Inv_Pick_Release_Pub.Call_Cartonization');
3958       End If;
3959       x_return_status := fnd_api.g_ret_sts_error;
3960    ELSE
3961       IF (is_debug) THEN print_debug('PATCHSET J -- BULK PICKING --- START',
3962                                 'Inv_Pick_Release_Pub.Call_Cartonization');
3963                     print_debug('calling assign_pick_slip_number',
3964                                 'Inv_Pick_Release_Pub.Call_Cartonization');
3965       END IF;
3966       assign_pick_slip_number(
3967                 x_return_status         => l_api_return_status,
3968                 x_msg_count             => x_msg_count,
3969                 x_msg_data              => x_msg_data,
3970                 p_move_order_header_id  => p_move_order_header_id,
3971                 p_ps_mode            => l_print_mode,
3972                 p_grouping_rule_id  => p_grouping_rule_id,
3973                 p_allow_partial_pick => p_allow_partial_pick);
3974       IF l_api_return_status = fnd_api.g_ret_sts_unexp_error OR
3975                 l_api_return_status = fnd_api.g_ret_sts_error THEN
3976                 print_debug('error from assign_pick_slip_number api',
3977                             'Inv_Pick_Release_Pub.Call_Cartonization');
3978                 print_debug('error count ' || x_msg_count,
3979                             'Inv_Pick_Release_Pub.Call_Cartonization');
3980                 print_debug('error msg ' || x_msg_data,
3981                             'Inv_Pick_Release_Pub.Call_Cartonization');
3982                 x_return_status := fnd_api.g_ret_sts_error;
3983       END IF;
3984    END IF;
3985 
3986    If is_debug then
3987      print_debug('success from cartonize api',
3988                'Inv_Pick_Release_Pub.Call_Cartonization');
3989    End If;
3990    END IF; --l_do_Cartonization=1
3991 EXCEPTION
3992      WHEN FND_API.G_EXC_ERROR THEN
3993         --
3994         x_return_status := FND_API.G_RET_STS_ERROR;
3995         --
3996         FND_MSG_PUB.Count_And_Get(p_count => x_msg_count
3997            , p_data => x_msg_data);
3998         --
3999      WHEN FND_API.G_EXC_UNEXPECTED_ERROR THEN
4000         --
4001         x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
4002         --
4003         FND_MSG_PUB.Count_And_Get(p_count => x_msg_count
4004            , p_data => x_msg_data);
4005         --
4006      WHEN OTHERS THEN
4007         ROLLBACK TO PR_Call_cartonization;
4008         --
4009         x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
4010         --
4011         IF FND_MSG_PUB.Check_Msg_Level(FND_MSG_PUB.G_MSG_LVL_UNEXP_ERROR) THEN
4012            FND_MSG_PUB.Add_Exc_Msg(G_PKG_NAME, 'Call_Cartonization');
4013         END IF;
4014         --
4015         FND_MSG_PUB.Count_And_Get(p_count => x_msg_count
4016            , p_data => x_msg_data);
4017 END call_cartonization;
4018 
4019 /* Bug 7504490* - Added the procedure Reserve_Unconfqty_lpn. This procedure transfers the reservation
4020    of the remaining quantity (task qty-picked qty) to cycle count reservation and ensures that the
4021    lpn_id is stamped on the reservation if the task was for an allocated lpn. This is similar to the
4022    Reserve_unconfirmed_quantity API except for passing the lpn_id to the reservation record. */
4023 
4024 PROCEDURE Reserve_Unconfqty_lpn
4025   (
4026        p_api_version			IN  	NUMBER
4027       ,p_init_msg_list			IN  	VARCHAR2 DEFAULT fnd_api.g_false
4028       ,p_commit				IN	VARCHAR2 DEFAULT fnd_api.g_false
4029       ,x_return_status        		OUT 	NOCOPY VARCHAR2
4030       ,x_msg_count            		OUT 	NOCOPY NUMBER
4031       ,x_msg_data             		OUT 	NOCOPY VARCHAR2
4032       ,x_new_rsv_id                     OUT     NOCOPY NUMBER -- bug8301348
4033       ,p_missing_quantity		IN	NUMBER
4034       ,p_secondary_missing_quantity     IN      NUMBER DEFAULT NULL  /*9251210*/
4035       ,p_reservation_id			IN	NUMBER DEFAULT fnd_api.g_miss_num
4036       ,p_demand_source_header_id	IN	NUMBER DEFAULT fnd_api.g_miss_num
4037       ,p_demand_source_line_id		IN	NUMBER DEFAULT fnd_api.g_miss_num
4038       ,p_organization_id		IN	NUMBER DEFAULT fnd_api.g_miss_num
4039       ,p_inventory_item_id		IN	NUMBER DEFAULT fnd_api.g_miss_num
4040       ,p_subinventory_code		IN	VARCHAR2 DEFAULT fnd_api.g_miss_char
4041       ,p_locator_id			IN	NUMBER DEFAULT fnd_api.g_miss_num
4042       ,p_revision			IN	VARCHAR2 DEFAULT fnd_api.g_miss_char
4043       ,p_lot_number			IN	VARCHAR2 DEFAULT fnd_api.g_miss_char
4044       ,p_lpn_id                         IN	NUMBER DEFAULT fnd_api.g_miss_num
4045   ) IS
4046       l_api_version	CONSTANT NUMBER := 1.0;
4047       l_api_name	CONSTANT VARCHAR2(30) := 'Reserve_Unconfirmed_Quantity';
4048 
4049       l_reservation_id		NUMBER;	-- The reservation to transfer quantity from
4050 					-- If invoked at Pick Confirm, this will
4051 					-- typically be passed in as a parameter,
4052 					-- based on the reservation tied to the Move
4053 					-- Order Line Detail which is being Pick
4054 					-- Confirmed.  If invoked at Ship Confirm,
4055 					-- this will most likely be derived from the
4056 					-- demand and supply source parameters.
4057       l_reservation_rec		INV_Reservation_GLOBAL.MTL_RESERVATION_REC_TYPE;
4058 					-- Temporary reservation record for retrieving
4059 					-- the reservation to transfer.
4060       l_reservation_count	NUMBER;	-- The number of reservations which match the
4061 					-- demand/supply source parameters passed in.
4062       l_cc_reservation_rec	INV_Reservation_GLOBAL.MTL_RESERVATION_REC_TYPE;
4063 					-- Temporary reservation record for the amount
4064 					-- to be transferred to Cycle Count.
4065       l_reservations_tbl	INV_Reservation_GLOBAL.MTL_RESERVATION_TBL_TYPE;
4066 					-- The table of reservations for given
4067 					-- supply and demand source
4068       l_dummy_sn  		INV_Reservation_GLOBAL.SERIAL_NUMBER_TBL_TYPE;
4069       l_new_rsv_id		NUMBER;	-- The reservation ID that has been transferred
4070 					-- to or updated
4071       l_mso_header_id		NUMBER; -- The header ID for the record in
4072 					-- MTL_SALES_ORDERS that corresponds to the OE
4073 					-- header and line passed in.
4074       l_api_return_status	VARCHAR2(1);
4075 					-- The return status of APIs called
4076 					-- within this API.
4077       l_api_error_code		NUMBER; -- The error code of APIs called within
4078 					-- this API.
4079     l_debug number := NVL(FND_PROFILE.VALUE('INV_DEBUG_TRACE'),0);
4080 BEGIN
4081    -- Set savepoint for this API
4082    SAVEPOINT Reserve_Unconfirmed_Qty_PUB;
4083 
4084    -- Standard Call to check for call compatibility
4085    IF NOT fnd_api.Compatible_API_Call(l_api_version
4086 				      , p_api_version
4087 				      , l_api_name
4088 				      , G_PKG_NAME) THEN
4089       RAISE fnd_api.g_exc_unexpected_error;
4090    END IF;
4091 
4092    -- Initialize message list if p_init_msg_list is set to true
4093    IF fnd_api.to_Boolean(p_init_msg_list) THEN
4094       fnd_msg_pub.initialize;
4095    END IF;
4096 
4097    -- Initialize API return status to success
4098    x_return_status := fnd_api.g_ret_sts_success;
4099 
4100    -- Validate parameters
4101 
4102    -- First make sure that missing quantity is not <= 0
4103    IF p_missing_quantity <= 0 THEN
4104       FND_MESSAGE.SET_NAME('INV','INV_NO_QTY_TO_TRANSFER');
4105       FND_MSG_PUB.Add;
4106       RAISE fnd_api.g_exc_unexpected_error;
4107    END IF;
4108 
4109    -- Determine whether the reservation id was given, or if it must be derived
4110    -- based on the supply source parameters.
4111    IF p_reservation_id <> fnd_api.g_miss_num AND
4112       p_reservation_id IS NOT NULL THEN
4113      -- Initialize the reservation querying record with the reservation ID
4114      l_reservation_id := p_reservation_id;
4115      l_reservation_rec.reservation_id := l_reservation_id;
4116    ELSE
4117      -- Initialize the reservation record with the demand/supply source
4118      -- information.  At minimum, must have a demand source type, line and header,
4119      -- and an item and organization ID
4120      IF	p_inventory_item_id = fnd_api.g_miss_num OR
4121 	p_inventory_item_id IS NULL OR
4122 	p_organization_id = fnd_api.g_miss_num OR
4123 	p_organization_id IS NULL OR
4124 	p_demand_source_header_id = fnd_api.g_miss_num OR
4125 	p_demand_source_header_id IS NULL OR
4126 	p_demand_source_line_id = fnd_api.g_miss_num OR
4127 	p_demand_source_line_id IS NULL THEN
4128           FND_MESSAGE.SET_NAME('INV','INV_COULD_NOT_ID_RSV');
4129 	  FND_MSG_PUB.Add;
4130 	  RAISE fnd_api.g_exc_unexpected_error;
4131      END IF;
4132 
4133      -- First attempt to convert the demand source header id given
4134      -- (the OE header id) to the MTL_SALES_ORDERS id to be used.
4135      /*l_mso_header_id :=
4136 	inv_salesorder.get_salesorder_for_oeheader(p_demand_source_header_id);
4137      IF l_mso_header_id IS NULL THEN
4138 	FND_MESSAGE.SET_NAME('INV','INV_COULD_NOT_GET_MSO_HEADER');
4139 	FND_MSG_PUB.Add;
4140 	RAISE fnd_api.g_exc_unexpected_error;
4141      END IF;*/
4142 
4143      l_reservation_rec.inventory_item_id := p_inventory_item_id;
4144      l_reservation_rec.organization_id := p_organization_id;
4145      l_reservation_rec.demand_source_type_id :=
4146 			INV_Reservation_GLOBAL.g_source_type_oe;
4147      l_reservation_rec.demand_source_header_id := p_demand_source_header_id;
4148      l_reservation_rec.demand_source_line_id := p_demand_source_line_id;
4149 
4150      IF p_subinventory_code <> fnd_api.g_miss_char THEN
4151 	l_reservation_rec.subinventory_code := p_subinventory_code;
4152      ELSE
4153 	l_reservation_rec.subinventory_code := NULL;
4154      END IF;
4155 
4156      IF p_locator_id <> fnd_api.g_miss_num THEN
4157 	l_reservation_rec.locator_id := p_locator_id;
4158      ELSE
4159 	l_reservation_rec.locator_id := NULL;
4160      END IF;
4161 
4162      IF p_revision <> fnd_api.g_miss_char THEN
4163 	l_reservation_rec.revision := p_revision;
4164      ELSE
4165 	l_reservation_rec.revision := NULL;
4166      END IF;
4167 
4168      IF p_lot_number <> fnd_api.g_miss_char THEN
4169 	l_reservation_rec.lot_number := p_lot_number;
4170      ELSE
4171 	l_reservation_rec.lot_number := NULL;
4172      END IF;
4173 
4174      /* Bug 7504490 - Checking for the allocated_lpn_id passed */
4175      IF p_lpn_id <> fnd_api.g_miss_char THEN
4176 	l_reservation_rec.lpn_id := p_lpn_id;
4177      ELSE
4178 	l_reservation_rec.lpn_id := NULL;
4179      END IF;
4180    END IF;
4181 
4182    -- Retrieve the reservation information
4183    INV_Reservation_PUB.Query_Reservation
4184    (
4185 	p_api_version_number		=> 1.0
4186 	, p_init_msg_lst		=> fnd_api.g_false
4187 	, x_return_status		=> l_api_return_status
4188 	, x_msg_count			=> x_msg_count
4189 	, x_msg_data			=> x_msg_data
4190 	, p_query_input			=> l_reservation_rec
4191 	, x_mtl_reservation_tbl		=> l_reservations_tbl
4192 	, x_mtl_reservation_tbl_count	=> l_reservation_count
4193 	, x_error_code			=> l_api_error_code
4194    );
4195    -- Return an error if the query reservations call failed
4196    IF l_api_return_status <> fnd_api.g_ret_sts_success THEN
4197       FND_MESSAGE.SET_NAME('INV','INV_QRY_RSV_FAILED');
4198       FND_MSG_PUB.Add;
4199       RAISE fnd_api.g_exc_unexpected_error;
4200    END IF;
4201 
4202    -- Only 1 reservation record should have been returned, since the parameters
4203    -- passed are supposed to uniquely identify a reservation record.
4204    IF l_reservation_count = 0 THEN
4205       FND_MESSAGE.SET_NAME('INV','INV_NO_RSVS_FOUND');
4206       FND_MSG_PUB.Add;
4207       RAISE fnd_api.g_exc_unexpected_error;
4208    END IF;
4209 
4210    IF l_reservation_count > 1 THEN
4211       FND_MESSAGE.SET_NAME('INV','INV_NON_UNIQUE_RSV');
4212       FND_MSG_PUB.Add;
4213       RAISE fnd_api.g_exc_unexpected_error;
4214    END IF;
4215 
4216    -- Determine whether the quantity to transfer is greater
4217    -- than the currently reserved quantity
4218    IF p_missing_quantity > l_reservations_tbl(1).primary_reservation_quantity THEN
4219       FND_MESSAGE.SET_NAME('INV','INV_INSUFF_QTY_RSV');
4220       FND_MSG_PUB.Add;
4221       RAISE fnd_api.g_exc_unexpected_error;
4222    END IF;
4223 
4224    -- Initialize the querying record with the reservation ID so that the update
4225    -- will be more efficient.
4226    l_reservation_rec.reservation_id := l_reservations_tbl(1).reservation_id;
4227 
4228    -- Validation complete - ready to transfer reservation to appropriate source
4229    l_cc_reservation_rec.primary_reservation_quantity := p_missing_quantity;
4230    l_cc_reservation_rec.primary_uom_code := l_reservations_tbl(1).primary_uom_code;
4231    l_cc_reservation_rec.secondary_reservation_quantity := p_secondary_missing_quantity ; --9251213
4232    l_cc_reservation_rec.detailed_quantity := 0;
4233    l_cc_reservation_rec.secondary_detailed_quantity := 0; --9251213
4234    l_cc_reservation_rec.demand_source_type_id := 9;
4235    l_cc_reservation_rec.demand_source_header_id := -1;
4236    l_cc_reservation_rec.demand_source_line_id := -1;
4237    l_cc_reservation_rec.subinventory_code := p_subinventory_code;
4238    l_cc_reservation_rec.locator_id := p_locator_id;
4239    l_cc_reservation_rec.revision := p_revision;
4240    l_cc_reservation_rec.lot_number := p_lot_number;
4241    /* Bug 7504490 - passing the lpn_id to the CC reservation record. */
4242    l_cc_reservation_rec.lpn_id := p_lpn_id;
4243 
4244    -- Make the call to the Transfer Reservation API
4245    INV_Reservation_PUB.Transfer_Reservation
4246    (
4247 	p_api_version_number          => 1.0
4248 	, p_init_msg_lst              => fnd_api.g_true
4249 	, x_return_status             => l_api_return_status
4250 	, x_msg_count                 => x_msg_count
4251 	, x_msg_data                  => x_msg_data
4252 	, p_original_rsv_rec          => l_reservation_rec
4253 	, p_to_rsv_rec                => l_cc_reservation_rec
4254 	, p_original_serial_number    => l_dummy_sn
4255 	, p_to_serial_number          => l_dummy_sn
4256 	, p_validation_flag           => fnd_api.g_true
4257 	, x_to_reservation_id         => l_new_rsv_id
4258    );
4259    -- Return an error if the transfer reservations call failed
4260    IF l_api_return_status <> fnd_api.g_ret_sts_success THEN
4261       FND_MESSAGE.SET_NAME('INV','INV_TRANSFER_RSV_FAILED');
4262       FND_MSG_PUB.Add;
4263       RAISE fnd_api.g_exc_unexpected_error;
4264    END IF;
4265    x_new_rsv_id := l_new_rsv_id ; --Bug#8301348
4266    -- Commit if necessary
4267    IF x_return_status <> fnd_api.g_ret_sts_success THEN
4268      ROLLBACK TO Reserve_Unconfirmed_Qty_PUB;
4269    ELSE
4270      -- Standard call to commit
4271      IF p_commit = fnd_api.g_true THEN
4272        COMMIT;
4273      END IF;
4274    END IF;
4275 
4276 EXCEPTION
4277      WHEN FND_API.G_EXC_ERROR THEN
4278      	--
4279      	x_return_status := FND_API.G_RET_STS_ERROR;
4280      	--
4281      	FND_MSG_PUB.Count_And_Get(p_count => x_msg_count
4282      	   , p_data => x_msg_data);
4283      	--
4284      WHEN FND_API.G_EXC_UNEXPECTED_ERROR THEN
4285      	--
4286      	x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
4287      	--
4288      	FND_MSG_PUB.Count_And_Get(p_count => x_msg_count
4289      	   , p_data => x_msg_data);
4290      	--
4291      WHEN OTHERS THEN
4292 	ROLLBACK TO Reserve_Unconfirmed_Qty_PUB;
4293      	--
4294      	x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
4295      	--
4296      	IF FND_MSG_PUB.Check_Msg_Level(FND_MSG_PUB.G_MSG_LVL_UNEXP_ERROR) THEN
4297      	   FND_MSG_PUB.Add_Exc_Msg(G_PKG_NAME, l_api_name);
4298      	END IF;
4299      	--
4300      	FND_MSG_PUB.Count_And_Get(p_count => x_msg_count
4301      	   , p_data => x_msg_data);
4302 END Reserve_Unconfqty_lpn;
4303 
4304 
4305 END INV_Pick_Release_PUB;