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