[Home] [Help]
PACKAGE BODY: APPS.WMS_CONTAINER_PVT
Source
1 PACKAGE BODY WMS_CONTAINER_PVT AS
2 /* $Header: WMSVCNTB.pls 120.55.12010000.6 2008/12/19 20:59:09 mchemban ship $ */
3
4 -- Global constant holding the package name
5 g_pkg_name CONSTANT VARCHAR2(30) := 'WMS_CONTAINER_PVT';
6 g_pkg_version CONSTANT VARCHAR2(100) := '$Header: WMSVCNTB.pls 120.55.12010000.6 2008/12/19 20:59:09 mchemban ship $';
7
8 -- Various debug levels
9 G_ERROR CONSTANT NUMBER := 1;
10 G_INFO CONSTANT NUMBER := 5;
11 G_MESSAGE CONSTANT NUMBER := 9;
12
13 G_NULL_NUM CONSTANT NUMBER := -9;
14 G_NULL_CHAR CONSTANT VARCHAR2(1) := '@';
15 G_PRECISION CONSTANT NUMBER := 5;
16
17 -- package level debug variable
18 g_progress VARCHAR(500) := 'none';
19
20 -- Types used by Convert_UOM
21 TYPE to_uom_code_tb IS TABLE OF NUMBER INDEX BY VARCHAR2(3);
22 TYPE from_uom_code_tb IS TABLE OF to_uom_code_tb INDEX BY VARCHAR2(3);
23 TYPE item_uom_conversion_tb IS TABLE OF from_uom_code_tb INDEX BY BINARY_INTEGER;
24 g_item_uom_conversion_tb item_uom_conversion_tb;
25 g_item_uom_conversion_tb_cnt NUMBER := 0;
26
27 PROCEDURE mdebug(msg IN VARCHAR2, LEVEL NUMBER := G_MESSAGE) IS
28 BEGIN
29 --DBMS_OUTPUT.put_line(msg);
30 INV_TRX_UTIL_PUB.TRACE(msg, g_pkg_name, LEVEL);
31 END;
32
33 FUNCTION Convert_UOM (
34 p_inventory_item_id IN NUMBER
35 , p_fm_quantity IN NUMBER
36 , p_fm_uom IN VARCHAR2
37 , p_to_uom IN VARCHAR2
38 , p_mode IN VARCHAR2 := null
39 ) RETURN NUMBER
40 IS
41 l_debug number := NVL(FND_PROFILE.VALUE('INV_DEBUG_TRACE'),0);
42
43 l_conversion_rate NUMBER;
44 l_inventory_item_id NUMBER;
45
46 BEGIN
47 g_progress := 'Entered Convert_UOM';
48
49 -- IF to_uom is the same as from_uom, Return from quantity
50 IF p_fm_uom = p_to_uom THEN
51 RETURN p_fm_quantity;
52 ELSE
53 --- Bug 5507188
54 --- l_inventory_item_id := NVL(l_inventory_item_id, 0);
55 l_inventory_item_id := NVL(p_inventory_item_id, 0);
56 --- End bug 5507188
57
58 -- Need to convert fm_qty
59 g_progress := 'First check whether the convesrion rate has been cached';
60 IF ( g_item_uom_conversion_tb.EXISTS(l_inventory_item_id) AND
61 g_item_uom_conversion_tb(l_inventory_item_id).EXISTS(p_fm_uom) AND
62 g_item_uom_conversion_tb(l_inventory_item_id)(p_fm_uom).EXISTS(p_to_uom) )
63 THEN
64 g_progress := 'Conversion rate is cached so just use the value';
65 RETURN p_fm_quantity * g_item_uom_conversion_tb(l_inventory_item_id)(p_fm_uom)(p_to_uom);
66 ELSE
67 -- conversion rate is not cached
68 g_progress := 'Call convert API and store the value';
69 inv_convert.inv_um_conversion (
70 from_unit => p_fm_uom
71 , to_unit => p_to_uom
72 , item_id => l_inventory_item_id
73 , uom_rate => l_conversion_rate );
74
75 IF ( l_conversion_rate > 0 ) THEN
76 g_progress := 'Store the conversion rate';
77 g_item_uom_conversion_tb(l_inventory_item_id)(p_fm_uom)(p_to_uom) := l_conversion_rate;
78 g_item_uom_conversion_tb(l_inventory_item_id)(p_to_uom)(p_fm_uom) := 1 / l_conversion_rate;
79 g_item_uom_conversion_tb_cnt := g_item_uom_conversion_tb_cnt + 1;
80
81 g_progress := 'Need to purge table after a certain number of records';
82 IF ( g_item_uom_conversion_tb_cnt > 1000 ) THEN
83 g_item_uom_conversion_tb.delete;
84 g_item_uom_conversion_tb_cnt := 0;
85 END IF;
86
87 RETURN p_fm_quantity * l_conversion_rate;
88 ELSE -- Can not convert
89 IF ( l_debug = 1 ) THEN
90 mdebug('No coversion rate between '||p_fm_uom||' and '||p_to_uom||' mode='||p_mode, G_ERROR);
91 END IF;
92 fnd_message.set_name('INV', 'INV_UOM_CONVERSION_ERROR');
93 fnd_message.set_token('uom1', p_fm_uom);
94 fnd_message.set_token('uom2', p_to_uom);
95 fnd_message.set_token('module', g_pkg_name);
96 fnd_msg_pub.ADD;
97
98 IF ( p_mode = G_NO_CONV_RETURN_NULL ) THEN
99 RETURN NULL;
100 ELSIF ( p_mode = G_NO_CONV_RETURN_ZERO ) THEN
101 RETURN 0;
102 ELSE -- Normal converstion error
103 fnd_msg_pub.ADD;
104 RAISE fnd_api.g_exc_error;
105 END IF;
106 END IF;
107 END IF; -- IF cache exists
108 END IF; -- IF p_fm_uom = p_to_uom
109 END Convert_UOM;
110
111 -- ----------------------------------------------------------------------------------
112 -- ----------------------------------------------------------------------------------
113
114 PROCEDURE Get_Update_LPN_Start_Num (
115 p_org_id IN NUMBER
116 , p_qty IN NUMBER
117 , x_curr_seq OUT NOCOPY NUMBER
118 ) IS PRAGMA AUTONOMOUS_TRANSACTION;
119 l_debug number := NVL(FND_PROFILE.VALUE('INV_DEBUG_TRACE'),0);
120 l_lpn_start_num NUMBER:=0;
121
122 BEGIN
123 --Creating an overloaded procedure so that the select of the
124 --starting number and the update happens with the same autonomous transaction
125 -- If the org default lpn starting number was used, we will need to update
126 -- that value so that the same number will not be used again the next time
127 -- Generate_LPN is called for that org
128
129 SELECT lpn_starting_number INTO l_lpn_start_num
130 FROM mtl_parameters
131 WHERE organization_id=p_org_id
132 FOR UPDATE;
133
134 UPDATE MTL_PARAMETERS
135 SET lpn_starting_number = l_lpn_start_num+p_qty,
136 last_update_date = SYSDATE,
137 last_updated_by = FND_GLOBAL.USER_ID
138 WHERE organization_id = p_org_id;
139
140 x_curr_seq:=l_lpn_start_num;
141
142 COMMIT;
143 END Get_Update_LPN_Start_Num;
144
145 -- ----------------------------------------------------------------------------------
146 -- ----------------------------------------------------------------------------------
147 -- 1 = Resides in Inventory
148 -- 2 = Resides in WIP
149 -- 3 = Resides in Receiving
150 -- 4 = Issued out of Stores
151 -- 5 = Pre-generated
152 -- 6 = Resides in intransit
153 -- 7 = Resides at vendor site
154 -- 8 = Packing context, used as a temporary context value
155 -- when the user wants to reassociate the LPN with a
156 -- different license plate number and/or container item ID
157 -- 9 = Loaded for shipment
158 -- 10 = Prepack of WIP
159 -- 11 = LPN Picked
160 -- 12 = Loaded in staging: Temporary context for staged (picked) LPNs
161
162 FUNCTION Valid_Context_Change (
163 p_caller VARCHAR
164 , p_old_context NUMBER
165 , p_new_context NUMBER
166 ) RETURN BOOLEAN IS
167
168 l_lookup_meaning MFG_LOOKUPS.MEANING%TYPE;
169
170 BEGIN
171 IF ( p_old_context = LPN_CONTEXT_INV ) THEN
172 IF ( p_new_context IN(1, 2, 3, 4, 5, 6, 8, 11) ) THEN
173 RETURN TRUE;
174 END IF;
175 ELSIF ( p_old_context = LPN_CONTEXT_WIP ) THEN
176 IF ( p_new_context IN(1, 2, 5, 11 ) ) THEN
177 RETURN TRUE;
178 END IF;
179 ELSIF ( p_old_context = LPN_CONTEXT_RCV ) THEN
180 IF ( p_new_context IN(1, 3, 4, 5, 11) ) THEN
181 RETURN TRUE;
182 END IF;
183 ELSIF ( p_old_context = LPN_CONTEXT_STORES ) THEN
184 IF ( p_new_context IN(4, 6) ) THEN
185 RETURN TRUE;
186 END IF;
187 ELSIF ( p_old_context = LPN_CONTEXT_PREGENERATED ) THEN
188 IF ( p_new_context IN(1, 2, 3, 4, 5, 6, 7, 8, 9, 11) ) THEN
189 RETURN TRUE;
190 END IF;
191 ELSIF ( p_old_context = LPN_CONTEXT_INTRANSIT ) THEN
192 IF ( p_new_context IN(1, 3, 5, 6, 11) ) THEN
193 RETURN TRUE;
194 END IF;
195 ELSIF ( p_old_context = LPN_CONTEXT_VENDOR ) THEN
196 IF ( p_new_context IN(1, 3, 5, 7) ) THEN
197 RETURN TRUE;
198 END IF;
199 ELSIF ( p_old_context = LPN_CONTEXT_PACKING ) THEN
200 IF ( p_new_context IN(1, 5, 8, 11) ) THEN
201 RETURN TRUE;
202 END IF;
203 ELSIF ( p_old_context = LPN_LOADED_FOR_SHIPMENT ) THEN
204 IF ( p_new_context IN(1, 4, 5, 6, 9, 11) ) THEN
205 RETURN TRUE;
206 END IF;
207 ELSIF ( p_old_context = LPN_PREPACK_FOR_WIP ) THEN
208 IF ( p_new_context IN(1, 2, 5, 10) ) THEN
209 RETURN TRUE;
210 END IF;
211 ELSIF ( p_old_context = LPN_CONTEXT_PICKED ) THEN
212 IF ( p_new_context IN(1, 4, 5, 6, 9, 11, 12) ) THEN
213 RETURN TRUE;
214 END IF;
215 ELSIF ( p_old_context = LPN_LOADED_IN_STAGE ) THEN
216 IF ( p_new_context IN(11, 12) ) THEN
217 RETURN TRUE;
218 END IF;
219 END IF;
220
221 -- If haven't returned true must be disallowed context change
222 -- return false and add error message
223 fnd_message.set_name('INV', 'WMS_CONTEXT_CHANGE_ERR');
224
225 SELECT meaning
226 INTO l_lookup_meaning
227 FROM mfg_lookups
228 WHERE lookup_type = 'WMS_LPN_CONTEXT'
229 AND lookup_code = p_old_context;
230 fnd_message.set_token('CONTEXT1', l_lookup_meaning);
231
232 SELECT meaning
233 INTO l_lookup_meaning
234 FROM mfg_lookups
235 WHERE lookup_type = 'WMS_LPN_CONTEXT'
236 AND lookup_code = p_new_context;
237 fnd_message.set_token('CONTEXT2', l_lookup_meaning);
238
239 fnd_msg_pub.ADD;
240 RAISE fnd_api.g_exc_error;
241 RETURN FALSE;
242 END Valid_Context_Change;
243
244 -- ----------------------------------------------------------------------------------
245 -- ----------------------------------------------------------------------------------
246
247 PROCEDURE To_LPNBulkRecType (
248 p_lpn_table IN WMS_Data_Type_Definitions_PUB.LPNTableType
249 , p_table_first IN NUMBER
250 , p_table_last IN NUMBER
251 , p_record_last IN NUMBER
252 , x_lpn_bulk_rec IN OUT NOCOPY LPNBulkRecType
253 ) IS
254 l_table_first NUMBER;
255 l_table_last NUMBER;
256 l_rec_last NUMBER;
257
258 BEGIN
259 IF ( p_lpn_table.first IS NOT NULL ) THEN
260 l_table_first := NVL(p_table_first, p_lpn_table.first);
261 l_table_last := NVL(p_table_last, p_lpn_table.last);
262 l_rec_last := NVL(p_record_last, NVL(x_lpn_bulk_rec.lpn_id.last, p_lpn_table.first - 1));
263
264 FOR i IN l_table_first .. l_table_last LOOP
265 l_rec_last := l_rec_last + 1;
266
267 x_lpn_bulk_rec.lpn_id(l_rec_last) := p_lpn_table(i).lpn_id;
268 x_lpn_bulk_rec.license_plate_number(l_rec_last) := p_lpn_table(i).license_plate_number;
269 x_lpn_bulk_rec.parent_lpn_id(l_rec_last) := p_lpn_table(i).parent_lpn_id;
270 x_lpn_bulk_rec.outermost_lpn_id(l_rec_last) := p_lpn_table(i).outermost_lpn_id;
271 x_lpn_bulk_rec.lpn_context(l_rec_last) := p_lpn_table(i).lpn_context;
272
273 x_lpn_bulk_rec.organization_id(l_rec_last) := p_lpn_table(i).organization_id;
274 x_lpn_bulk_rec.subinventory_code(l_rec_last) := p_lpn_table(i).subinventory_code;
275 x_lpn_bulk_rec.locator_id(l_rec_last) := p_lpn_table(i).locator_id;
276
277 x_lpn_bulk_rec.inventory_item_id(l_rec_last) := p_lpn_table(i).inventory_item_id;
278 x_lpn_bulk_rec.revision(l_rec_last) := p_lpn_table(i).revision;
279 x_lpn_bulk_rec.lot_number(l_rec_last) := p_lpn_table(i).lot_number;
280 x_lpn_bulk_rec.serial_number(l_rec_last) := p_lpn_table(i).serial_number;
281 x_lpn_bulk_rec.cost_group_id(l_rec_last) := p_lpn_table(i).cost_group_id;
282
283 x_lpn_bulk_rec.tare_weight_uom_code(l_rec_last) := p_lpn_table(i).tare_weight_uom_code;
284 x_lpn_bulk_rec.tare_weight(l_rec_last) := p_lpn_table(i).tare_weight;
285 x_lpn_bulk_rec.gross_weight_uom_code(l_rec_last) := p_lpn_table(i).gross_weight_uom_code;
286 x_lpn_bulk_rec.gross_weight(l_rec_last) := p_lpn_table(i).gross_weight;
287 x_lpn_bulk_rec.container_volume_uom(l_rec_last) := p_lpn_table(i).container_volume_uom;
288 x_lpn_bulk_rec.container_volume(l_rec_last) := p_lpn_table(i).container_volume;
289 x_lpn_bulk_rec.content_volume_uom_code(l_rec_last) := p_lpn_table(i).content_volume_uom_code;
290 x_lpn_bulk_rec.content_volume(l_rec_last) := p_lpn_table(i).content_volume;
291
292 x_lpn_bulk_rec.source_type_id(l_rec_last) := p_lpn_table(i).source_type_id;
293 x_lpn_bulk_rec.source_header_id(l_rec_last) := p_lpn_table(i).source_header_id;
294 x_lpn_bulk_rec.source_line_id(l_rec_last) := p_lpn_table(i).source_line_id;
295 x_lpn_bulk_rec.source_line_detail_id(l_rec_last) := p_lpn_table(i).source_line_detail_id;
296 x_lpn_bulk_rec.source_name(l_rec_last) := p_lpn_table(i).source_name;
297 x_lpn_bulk_rec.source_transaction_id(l_rec_last) := p_lpn_table(i).source_transaction_id;
298 x_lpn_bulk_rec.reference_id(l_rec_last) := p_lpn_table(i).reference_id;
299
300 x_lpn_bulk_rec.attribute_category(l_rec_last) := p_lpn_table(i).attribute_category;
301 x_lpn_bulk_rec.attribute1(l_rec_last) := p_lpn_table(i).attribute1;
302 x_lpn_bulk_rec.attribute2(l_rec_last) := p_lpn_table(i).attribute2;
303 x_lpn_bulk_rec.attribute3(l_rec_last) := p_lpn_table(i).attribute3;
304 x_lpn_bulk_rec.attribute4(l_rec_last) := p_lpn_table(i).attribute4;
305 x_lpn_bulk_rec.attribute5(l_rec_last) := p_lpn_table(i).attribute5;
306 x_lpn_bulk_rec.attribute6(l_rec_last) := p_lpn_table(i).attribute6;
307 x_lpn_bulk_rec.attribute7(l_rec_last) := p_lpn_table(i).attribute7;
308 x_lpn_bulk_rec.attribute8(l_rec_last) := p_lpn_table(i).attribute8;
309 x_lpn_bulk_rec.attribute9(l_rec_last) := p_lpn_table(i).attribute9;
310 x_lpn_bulk_rec.attribute10(l_rec_last) := p_lpn_table(i).attribute10;
311 x_lpn_bulk_rec.attribute11(l_rec_last) := p_lpn_table(i).attribute11;
312 x_lpn_bulk_rec.attribute12(l_rec_last) := p_lpn_table(i).attribute12;
313 x_lpn_bulk_rec.attribute13(l_rec_last) := p_lpn_table(i).attribute13;
314 x_lpn_bulk_rec.attribute14(l_rec_last) := p_lpn_table(i).attribute14;
315 x_lpn_bulk_rec.attribute15(l_rec_last) := p_lpn_table(i).attribute15;
316 END LOOP;
317 END IF;
318 END To_LPNBulkRecType;
319
320 -- ----------------------------------------------------------------------------------
321 -- ----------------------------------------------------------------------------------
322
323 FUNCTION To_LPNBulkRecType (
324 p_lpn_table IN WMS_Data_Type_Definitions_PUB.LPNTableType
325 )
326 RETURN LPNBulkRecType
327 IS
328 l_lpn_bulk_rec LPNBulkRecType;
329
330 BEGIN
331 To_LPNBulkRecType (
332 p_lpn_table => p_lpn_table
333 , p_table_first => null
334 , p_table_last => null
335 , p_record_last => null
336 , x_lpn_bulk_rec => l_lpn_bulk_rec );
337
338 RETURN l_lpn_bulk_rec;
339 END To_LPNBulkRecType;
340
341 FUNCTION To_DeliveryDetailsRecType (
342 p_lpn_record IN WMS_Data_Type_Definitions_PUB.LPNRecordType
343 )
344 RETURN WSH_Glbl_Var_Strct_GRP.Delivery_Details_Rec_Type IS
345
346 l_debug NUMBER := NVL(FND_PROFILE.VALUE('INV_DEBUG_TRACE'),0);
347 l_wsh_dd_rec WSH_Glbl_Var_Strct_GRP.Delivery_Details_Rec_Type;
348
349 BEGIN
350
351 l_wsh_dd_rec.lpn_id := p_lpn_record.lpn_id;
352 l_wsh_dd_rec.container_name := p_lpn_record.license_plate_number;
353 l_wsh_dd_rec.inventory_item_id := p_lpn_record.inventory_item_id;
354
355 l_wsh_dd_rec.organization_id := p_lpn_record.organization_id;
356 l_wsh_dd_rec.subinventory := p_lpn_record.subinventory_code;
357 l_wsh_dd_rec.locator_id := p_lpn_record.locator_id;
358
359 l_wsh_dd_rec.gross_weight := p_lpn_record.gross_weight;
360 l_wsh_dd_rec.weight_uom_code := p_lpn_record.gross_weight_uom_code;
361
362 l_wsh_dd_rec.filled_volume := p_lpn_record.content_volume;
363 l_wsh_dd_rec.volume_uom_code := p_lpn_record.content_volume_uom_code;
364
365 -- Need to caclcuate this net_weight = gross_weight - tare_weight
366 IF ( NVL(p_lpn_record.tare_weight, 0) = 0 OR p_lpn_record.tare_weight_uom_code IS NULL ) THEN
367 l_wsh_dd_rec.net_weight := p_lpn_record.gross_weight;
368 ELSIF ( NVL(p_lpn_record.gross_weight, 0) = 0 OR p_lpn_record.gross_weight_uom_code IS NULL ) THEN
369 l_wsh_dd_rec.net_weight := 0;
370 l_wsh_dd_rec.weight_uom_code := p_lpn_record.tare_weight_uom_code;
371 ELSIF ( p_lpn_record.tare_weight_uom_code = p_lpn_record.gross_weight_uom_code ) THEN
372 l_wsh_dd_rec.net_weight := p_lpn_record.gross_weight - p_lpn_record.tare_weight;
373 ELSE -- Both are not null but with different UOMs need to convert
374 l_wsh_dd_rec.net_weight := Convert_UOM(p_lpn_record.inventory_item_id, p_lpn_record.tare_weight, p_lpn_record.tare_weight_uom_code, p_lpn_record.gross_weight_uom_code);
375 l_wsh_dd_rec.net_weight := p_lpn_record.gross_weight - l_wsh_dd_rec.net_weight;
376 END IF;
377
378 IF ( l_wsh_dd_rec.net_weight < 0 ) THEN
379 l_wsh_dd_rec.net_weight := 0;
380 END IF;
381
382 -- Need to convert container volume into the content volume uom for shipping
383 IF ( NVL(p_lpn_record.container_volume, -1) < 0 OR p_lpn_record.container_volume_uom IS NULL ) THEN
384 l_wsh_dd_rec.volume := NULL;
385 ELSIF ( p_lpn_record.container_volume_uom = NVL(p_lpn_record.content_volume_uom_code, p_lpn_record.container_volume_uom) ) THEN
386 l_wsh_dd_rec.volume := p_lpn_record.container_volume;
387 l_wsh_dd_rec.volume_uom_code := p_lpn_record.container_volume_uom;
388 ELSE
389 l_wsh_dd_rec.volume := Convert_UOM(p_lpn_record.inventory_item_id, p_lpn_record.container_volume, p_lpn_record.container_volume_uom, p_lpn_record.content_volume_uom_code);
390 END IF;
391
392 IF ( l_debug = 1 ) THEN
393 mdebug('ddrectype lpnid='||l_wsh_dd_rec.lpn_id||' lpn='||l_wsh_dd_rec.container_name||' itm='||l_wsh_dd_rec.inventory_item_id||' org='||l_wsh_dd_rec.organization_id||' sub='||l_wsh_dd_rec.subinventory||' loc='||l_wsh_dd_rec.locator_id, G_INFO);
394 mdebug('gwt='||l_wsh_dd_rec.gross_weight||' nwt='||l_wsh_dd_rec.net_weight||' wuom='||l_wsh_dd_rec.weight_uom_code||' fvol='||l_wsh_dd_rec.filled_volume||' vol='||l_wsh_dd_rec.volume||' vuom='||l_wsh_dd_rec.volume_uom_code, G_INFO);
395 END IF;
396
397 RETURN l_wsh_dd_rec;
398 END To_DeliveryDetailsRecType;
399
400 -- ----------------------------------------------------------------------------------
401 -- ----------------------------------------------------------------------------------
402
403 PROCEDURE Get_Greater_Qty (
404 p_debug IN NUMBER
405 , p_inventory_item_id IN NUMBER
406 , p_quantity1 IN NUMBER
407 , p_quantity1_uom IN VARCHAR2
408 , p_quantity2 IN NUMBER
409 , p_quantity2_uom IN VARCHAR2
410 , x_greater_qty OUT NOCOPY NUMBER
411 , x_greater_qty_uom OUT NOCOPY VARCHAR2
412 ) IS
413 l_api_name CONSTANT VARCHAR2(30) := 'Get_Greater_Qty';
414
415 BEGIN
416 IF ( NVL(p_quantity1, 0) = 0 OR p_quantity1_uom IS NULL ) THEN
417 x_greater_qty := p_quantity2;
418 x_greater_qty_uom := p_quantity2_uom;
419 ELSIF ( NVL(p_quantity2, 0) = 0 OR p_quantity2_uom IS NULL ) THEN
420 x_greater_qty := p_quantity1;
421 x_greater_qty_uom := p_quantity1_uom;
422 ELSIF ( p_quantity1_uom = p_quantity2_uom ) THEN
423 x_greater_qty := GREATEST(p_quantity1, p_quantity2);
424 x_greater_qty_uom := p_quantity2_uom;
425 ELSE -- Both are not null but with different UOMs need to convert
426 x_greater_qty_uom := p_quantity2_uom;
427
428 x_greater_qty := Convert_UOM(p_inventory_item_id, p_quantity1, p_quantity1_uom, x_greater_qty_uom);
429 x_greater_qty := GREATEST(x_greater_qty, p_quantity2);
430 END IF;
431
432 IF (p_debug = 1) THEN
433 mdebug('x_greater_qty='||x_greater_qty||' x_greater_qty_uom='||x_greater_qty_uom, G_INFO);
434 END IF;
435 END Get_Greater_Qty;
436
437 -- ----------------------------------------------------------------------------------
438 -- ----------------------------------------------------------------------------------
439
440 PROCEDURE Calc_Vol_Change (
441 p_debug IN NUMBER
442 , p_old_lpn IN WMS_Data_Type_Definitions_PUB.LPNRecordType
443 , p_new_lpn IN WMS_Data_Type_Definitions_PUB.LPNRecordType
444 , p_volume_change OUT NOCOPY NUMBER
445 , p_volume_uom_change OUT NOCOPY VARCHAR2
446 ) IS
447 l_api_name CONSTANT VARCHAR2(30) := 'Calc_Vol_Change';
448 l_progress VARCHAR2(500) := 'Entered API';
449
450 l_old_max_volume NUMBER;
451 l_old_max_volume_uom VARCHAR2(3);
452 l_new_max_volume NUMBER;
453 l_new_max_volume_uom VARCHAR2(3);
454
455 BEGIN
456 l_progress := 'Calculate the greater for old container/content volume';
457 -- First determine which was greater before update, container or content
458 Get_Greater_Qty (
459 p_debug => p_debug
460 , p_inventory_item_id => p_old_lpn.inventory_item_id
461 , p_quantity1 => p_old_lpn.container_volume
462 , p_quantity1_uom => p_old_lpn.container_volume_uom
463 , p_quantity2 => p_old_lpn.content_volume
464 , p_quantity2_uom => p_old_lpn.content_volume_uom_code
465 , x_greater_qty => l_old_max_volume
466 , x_greater_qty_uom => l_old_max_volume_uom );
467
468 IF (p_debug = 1) THEN
469 mdebug('old max vol='||l_old_max_volume||' old max vol uom='||l_old_max_volume_uom, G_INFO);
470 END IF;
471
472 Get_Greater_Qty (
473 p_debug => p_debug
474 , p_inventory_item_id => p_new_lpn.inventory_item_id
475 , p_quantity1 => p_new_lpn.container_volume
476 , p_quantity1_uom => p_new_lpn.container_volume_uom
477 , p_quantity2 => p_new_lpn.content_volume
478 , p_quantity2_uom => p_new_lpn.content_volume_uom_code
479 , x_greater_qty => l_new_max_volume
480 , x_greater_qty_uom => l_new_max_volume_uom );
481
482 IF (p_debug = 1) THEN
483 mdebug('new max vol='||l_new_max_volume||' new max vol uom='||l_new_max_volume_uom, G_INFO);
484 END IF;
485
486 -- Now we need to compare the difference between the greatest of the new and old
487 -- volumes to get the change in volume
488 -- again if the lpn is newly packed, then just use the new value
489 IF ( (p_old_lpn.parent_lpn_id IS NULL AND p_new_lpn.parent_lpn_id IS NOT NULL) OR
490 NVL(l_old_max_volume, 0) = 0 OR l_old_max_volume_uom IS NULL ) THEN
491 p_volume_change := l_new_max_volume;
492 p_volume_uom_change := l_new_max_volume_uom;
493 ELSIF ( NVL(l_new_max_volume, 0) = 0 OR l_new_max_volume_uom IS NULL ) THEN
494 p_volume_change := 0 - l_old_max_volume;
495 p_volume_uom_change := l_old_max_volume_uom;
496 ELSIF ( l_old_max_volume_uom = l_new_max_volume_uom ) THEN
497 p_volume_change := l_new_max_volume - l_old_max_volume;
498 p_volume_uom_change := l_new_max_volume_uom;
499 ELSE -- Both are not null but with different UOMs need to convert
500 l_old_max_volume := Convert_UOM(p_new_lpn.inventory_item_id, l_old_max_volume, l_old_max_volume_uom, l_new_max_volume_uom);
501 -- Change old max volume uom just for completeness sake
502 l_old_max_volume_uom := l_new_max_volume_uom;
503
504 p_volume_change := l_new_max_volume - l_old_max_volume;
505 p_volume_uom_change := l_new_max_volume_uom;
506 END IF;
507
508 IF (p_debug = 1) THEN
509 mdebug('change vol='||p_volume_change||' change vuom='||p_volume_uom_change, G_INFO);
510 END IF;
511 END;
512
513 --Bug 4144326. Added the following procedure.
514 --This procedure has to be called with the LPN before updating the attributes.
515 --This procedure will calculate the change in weight and volume for the LPN
516 --and update the Locator capacity with the difference.
517 PROCEDURE Update_Locator_Capacity (
518 x_return_status OUT NOCOPY VARCHAR2
519 , x_msg_count OUT NOCOPY NUMBER
520 , x_msg_data OUT NOCOPY VARCHAR2
521 , p_organization_id IN NUMBER
522 , p_subinventory IN VARCHAR2
523 , p_locator_id IN NUMBER
524 , p_weight_change IN NUMBER
525 , p_weight_uom_change IN VARCHAR2
526 , p_volume_change IN NUMBER
527 , p_volume_uom_change IN VARCHAR2
528 ) IS
529
530 l_api_name CONSTANT VARCHAR2(30) := 'Update_Locator_Capacity';
531 l_debug NUMBER := NVL(FND_PROFILE.VALUE('INV_DEBUG_TRACE'),0);
532 wtdiff NUMBER := 0;
533 voldiff NUMBER := 0;
534 l_loc_wt_uom VARCHAR2(3);
535 l_loc_vol_uom VARCHAR2(3);
536
537 BEGIN
538 -- Standard Start of API savepoint
539 SAVEPOINT WMS_Update_Locator_Capacity;
540
541 x_return_status := fnd_api.g_ret_sts_success ; --set to Success by default.
542
543 IF (l_debug = 1) THEN
544 mdebug(l_api_name|| ' Entered ' ||g_pkg_version, 1);
545 mdebug('orgid='||p_organization_id||' sub='||p_subinventory||' loc='||p_locator_id||' wt='||p_weight_change||' wuom='||p_weight_uom_change||' vol='||p_volume_change||' vuom='||p_volume_uom_change, G_INFO);
546 END IF;
547
548
549 -- Bug 5150314, LPNs in non wms orgs may not have sub and loc info
550 -- bypass the update in this case
551 IF ( p_subinventory IS NOT NULL AND p_locator_id IS NOT NULL ) THEN
552 g_progress := 'Get UOM for Weight and volume of Locator';
553
554 -- Get locator information from cache
555 /*IF NOT ( INV_Cache.set_to_locator( p_locator_id ) THEN
556 --set_to_locator not implemented
557 END IF;*/
558
559 SELECT mil.location_weight_uom_code
560 , mil.volume_uom_code
561 INTO l_loc_wt_uom
562 , l_loc_vol_uom
563 FROM mtl_item_locations mil
564 WHERE mil.organization_id = p_organization_id
565 AND mil.subinventory_code = p_subinventory
566 AND mil.inventory_location_id = p_locator_id;
567
568 IF (l_debug = 1) THEN
569 mdebug('Got locator uoms location_weight_uom_code='||l_loc_wt_uom||' volume_uom_code='||l_loc_vol_uom, G_INFO);
570 END IF;
571
572 -- Find out the weight difference
573 IF ( l_loc_wt_uom IS NOT NULL ) THEN
574 IF ( NVL(p_weight_change, 0) <> 0 AND p_weight_uom_change IS NOT NULL ) THEN
575 g_progress := 'Convert change in weight to locator weight uom';
576 wtdiff := Convert_UOM (
577 p_inventory_item_id => 0
578 , p_fm_quantity => p_weight_change
579 , p_fm_uom => p_weight_uom_change
580 , p_to_uom => l_loc_wt_uom );
581 END IF;
582 END IF;
583
584 -- Find out the volume difference
585 IF ( l_loc_vol_uom IS NOT NULL ) THEN
586 IF ( NVL(p_volume_change, 0) <> 0 AND p_volume_uom_change IS NOT NULL) THEN
587 g_progress := 'Convert change in volume to locator volume uom';
588 voldiff := Convert_UOM (
589 p_inventory_item_id => 0
590 , p_fm_quantity => p_volume_change
591 , p_fm_uom => p_volume_uom_change
592 , p_to_uom => l_loc_vol_uom );
593 END IF;
594 END IF;
595 END IF;
596
597 IF (l_debug = 1) THEN
598 mdebug('wtdiff='||wtdiff||' voldiff='||voldiff, G_INFO);
599 END IF;
600
601 IF ( wtdiff <> 0 OR voldiff <> 0 ) THEN
602 g_progress := 'Update Locator capacity';
603
604 UPDATE mtl_item_locations mil
605 SET current_weight = nvl(current_weight,0) + wtdiff
606 , available_weight = nvl(available_weight,0) - wtdiff
607 , current_cubic_area = nvl(current_cubic_area,0) + voldiff
608 , available_cubic_area = nvl(available_cubic_area,0) - voldiff
609 WHERE mil.organization_id = p_organization_id
610 AND mil.subinventory_code = p_subinventory
611 AND mil.inventory_location_id = p_locator_id;
612 END IF;
613 EXCEPTION
614 WHEN OTHERS THEN
615 IF (l_debug = 1) THEN
616 mdebug(l_api_name ||' Error g_progress= '||g_progress, 1);
617 IF ( SQLCODE IS NOT NULL ) THEN
618 mdebug('SQL error: ' || SQLERRM(SQLCODE), 1);
619 END IF;
620 END IF;
621
622 ROLLBACK TO WMS_Update_Locator_Capacity;
623 x_return_status := fnd_api.g_ret_sts_unexp_error;
624 FND_MSG_PUB.Count_And_Get(p_count => x_msg_count, p_data => x_msg_data);
625 END Update_Locator_Capacity;
626
627
628 -- ======================================================================
629 -- FUNCTION Generate_Check_Digit
630 -- ======================================================================
631 -- Purpose
632 -- Generate the Check Digit for LPN using Modulo 10 Check Digit Algorithm
633 -- 1. Consider the right most digit of the code to be in an 'even'
634 -- position and assign odd/even to each character moving from right to
635 -- left.
636 -- 2. Sum the digits in all odd positions
637 -- 3. Sum the digits in all even positions and multiply the result by 3 .
638 -- 4. Sum the totals calculated in steps 2 and 3.
639 -- 5. The Check digit is the number which, when added to the totals
640 -- calculated in step 4, result in a number evenly divisible by 10.
641
642 -- Input Parameters
643 -- P_lpn_str (Required)
644 --
645 -- Output value :
646 -- Valid single check digit .
647 --
648
649 FUNCTION Generate_Check_Digit( p_debug NUMBER, p_lpn_str IN VARCHAR2 )
650
651 RETURN NUMBER
652 IS
653 l_api_name CONSTANT VARCHAR2(30) := 'Generate_Check_Digit';
654
655 L NUMBER;
656 I NUMBER;
657 l_evensum NUMBER := 0;
658 l_oddsum NUMBER := 0;
659 l_total NUMBER := 0;
660 l_checkdigit NUMBER := 0;
661 l_remainder NUMBER := 0;
662
663 l_length NUMBER;
664 l_lpn_str varchar2(255);
665 BEGIN
666 IF ( p_debug = 1 ) THEN
667 mdebug('p_lpn_str : ' || p_lpn_str, G_INFO);
668 END IF;
669
670 L := 0;
671 l_lpn_str := rtrim(p_lpn_str);
672 l_length := LENGTH(l_lpn_str);
673
674 FOR I IN REVERSE 1..l_length
675 LOOP
676 -- mdebug('l_lpn_str(' || I || ') : ' || to_number(substr(l_lpn_str,I,1)), G_INFO);
677 IF (mod(L,2) = 0) THEN
678 l_Evensum := l_Evensum + to_number(substr(l_lpn_str,I,1));
679 ELSE
680 l_Oddsum := l_Oddsum + to_number(substr(l_lpn_str,I,1));
681 END IF;
682 L := L + 1;
683 END LOOP;
684
685 l_Evensum := l_Evensum * 3;
686 l_Total := l_Evensum + l_Oddsum;
687 l_remainder := mod(l_total,10);
688
689 IF ( p_debug = 1 ) THEN
690 mdebug('l_total:' || l_total || ' l_remainder : ' || l_remainder, G_INFO);
691 END IF;
692
693 IF (l_remainder > 0) THEN
694 l_checkdigit := 10 - l_remainder;
695 END IF;
696
697 IF ( p_debug = 1 ) THEN
698 mdebug('l_checkdigit : ' || l_checkdigit, G_INFO);
699 END IF;
700
701 RETURN l_checkdigit;
702 END Generate_Check_Digit;
703
704 -- ----------------------------------------------------------------------------------
705 -- ----------------------------------------------------------------------------------
706
707 PROCEDURE Create_LPNs (
708 p_api_version IN NUMBER
709 , p_init_msg_list IN VARCHAR2
710 , p_commit IN VARCHAR2
711 , x_return_status OUT NOCOPY VARCHAR2
712 , x_msg_count OUT NOCOPY NUMBER
713 , x_msg_data OUT NOCOPY VARCHAR2
714 , p_caller IN VARCHAR2
715 , p_lpn_table IN OUT NOCOPY WMS_Data_Type_Definitions_PUB.LPNTableType
716 ) IS
717 l_api_name CONSTANT VARCHAR2(30) := 'Create_LPNs';
718 l_api_version CONSTANT NUMBER := 1.0;
719 l_debug NUMBER := NVL(FND_PROFILE.VALUE('INV_DEBUG_TRACE'),0);
720 l_progress VARCHAR2(500) := 'Entered API';
721 l_msgdata VARCHAR2(1000);
722
723 l_lpn_bulk_rec LPNBulkRecType;
724
725 l_user_id NUMBER;
726 l_request_id NUMBER;
727
728 l_label_status VARCHAR2(300);
729 l_dummy_num NUMBER;
730
731 -- Variables for call to Print_Label
732 l_input_param_tbl inv_label.input_parameter_rec_type;
733 l_return_status VARCHAR2(30);
734
735 -- Variables used for Creating LPNs in shipping
736 l_detail_info_tab WSH_GLBL_VAR_STRCT_GRP.delivery_details_Attr_tbl_Type;
737 l_IN_rec WSH_GLBL_VAR_STRCT_GRP.detailInRecType;
738 l_OUT_rec WSH_GLBL_VAR_STRCT_GRP.detailOutRecType;
739
740 BEGIN
741 -- Standard Start of API savepoint
742 SAVEPOINT CREATE_LPNS_PVT;
743
744 -- Standard call to check for call compatibility.
745 IF NOT fnd_api.compatible_api_call(l_api_version, p_api_version, l_api_name, g_pkg_name) THEN
746 fnd_message.set_name('WMS', 'WMS_CONT_INCOMPATIBLE_API_CALL');
747 fnd_msg_pub.ADD;
748 RAISE fnd_api.g_exc_unexpected_error;
749 END IF;
750
751 -- Initialize message list if p_init_msg_list is set to TRUE.
752 IF fnd_api.to_boolean(p_init_msg_list) THEN
753 fnd_msg_pub.initialize;
754 END IF;
755
756 -- Initialize API return status to success
757 x_return_status := fnd_api.g_ret_sts_success;
758
759 -- API body
760 IF (l_debug = 1) THEN
761 mdebug(l_api_name || ' Entered ' || g_pkg_version, 1);
762 mdebug('ver='||p_api_version||' initmsg='||p_init_msg_list||' commit='||p_commit||' caller='||p_caller||' tabcnt='||p_lpn_table.last, G_INFO);
763 END IF;
764
765 l_progress := 'Getting any profile user values';
766
767 SELECT fnd_global.user_id
768 , FND_PROFILE.value('CONC_REQUEST_ID')
769 INTO l_user_id
770 , l_request_id
771 FROM DUAL;
772
773 IF (l_debug = 1) THEN
774 mdebug('Got profile info user_id='||l_user_id||' request_id='||l_request_id , G_INFO);
775 END IF;
776
777 l_progress := 'Validation for each LPN in record';
778
779 FOR i IN p_lpn_table.first .. p_lpn_table.last LOOP
780 IF ( l_debug = 1 ) THEN
781 mdebug('lpn='||p_lpn_table(i).license_plate_number||' org='||p_lpn_table(i).organization_id||' sub='||p_lpn_table(i).subinventory_code||' loc='||p_lpn_table(i).locator_id||' ctx='||p_lpn_table(i).lpn_context||
782 ' itm='||p_lpn_table(i).inventory_item_id||' plpn='||p_lpn_table(i).parent_lpn_id||' olpn='||p_lpn_table(i).outermost_lpn_id, G_INFO);
783 mdebug('gwt='||p_lpn_table(i).gross_weight||' gwuom='||p_lpn_table(i).gross_weight_uom_code||' twt='||p_lpn_table(i).tare_weight_uom_code|| ' twuom='||p_lpn_table(i).tare_weight_uom_code||
784 ' ctrvuom='||p_lpn_table(i).container_volume_uom||' ctrvol='||p_lpn_table(i).container_volume||' cntvuom='||p_lpn_table(i).content_volume_uom_code||' cntvol='||p_lpn_table(i).content_volume, G_INFO);
785 END IF;
786
787 -- Organization is required. Make sure that it is populated
788 IF ( p_lpn_table(i).organization_id IS NULL ) THEN
789 fnd_message.set_name('WMS', 'WMS_CONT_INVALID_ORG');
790 fnd_msg_pub.ADD;
791 RAISE fnd_api.g_exc_error;
792 END IF;
793
794 IF ( p_lpn_table(i).inventory_item_id IS NOT NULL) THEN
795 l_progress := 'Calling INV_CACHE.Set_Item_Rec to get item values';
796
797 IF ( inv_cache.set_item_rec(
798 p_organization_id => p_lpn_table(i).organization_id
799 , p_item_id => p_lpn_table(i).inventory_item_id ) )
800 THEN
801 IF (l_debug = 1) THEN
802 mdebug('Got Item info citm='||inv_cache.item_rec.container_item_flag||' snctl='||inv_cache.item_rec.serial_number_control_code, G_INFO);
803 mdebug('wuom='||inv_cache.item_rec.weight_uom_code||' wt='||inv_cache.item_rec.unit_weight||' vuom='||inv_cache.item_rec.volume_uom_code||' vol='||inv_cache.item_rec.unit_volume, G_INFO);
804 END IF;
805
806 IF ( inv_cache.item_rec.container_item_flag = 'N' ) THEN
807 IF (l_debug = 1) THEN
808 mdebug(p_lpn_table(i).inventory_item_id || ' is not a container', 1);
809 END IF;
810 fnd_message.set_name('WMS', 'WMS_ITEM_NOT_CONTAINER');
811 fnd_message.set_token('ITEM', inv_cache.item_rec.segment1);
812 fnd_msg_pub.ADD;
813 RAISE fnd_api.g_exc_error;
814 END IF;
815
816 p_lpn_table(i).tare_weight_uom_code := inv_cache.item_rec.weight_uom_code;
817 p_lpn_table(i).tare_weight := inv_cache.item_rec.unit_weight;
818 p_lpn_table(i).container_volume_uom := inv_cache.item_rec.volume_uom_code;
819 p_lpn_table(i).container_volume := inv_cache.item_rec.unit_volume;
820 ELSE
821 l_progress := 'Error calling INV_CACHE.Set_Item_Rec for orgid'||p_lpn_table(i).organization_id||' item id='||p_lpn_table(i).inventory_item_id;
822 fnd_message.set_name('WMS', 'WMS_CONT_INVALID_ITEM');
823 fnd_msg_pub.ADD;
824 RAISE fnd_api.g_exc_error;
825 END IF;
826 END IF;
827
828 -- LPN Context cannot be null
829 p_lpn_table(i).lpn_context := NVL(p_lpn_table(i).lpn_context, WMS_CONTAINER_PUB.LPN_CONTEXT_PREGENERATED);
830
831 -- If context is pregenerated, do not allow sub and loc info
832 IF ( p_lpn_table(i).lpn_context = WMS_CONTAINER_PUB.LPN_CONTEXT_PREGENERATED ) THEN
833 p_lpn_table(i).subinventory_code := NULL;
834 p_lpn_table(i).locator_id := NULL;
835 END IF;
836
837 --Check LPN for leading or trailing spaces if they exist
838 p_lpn_table(i).license_plate_number := RTRIM(LTRIM(p_lpn_table(i).license_plate_number,' '),' ');
839
840 IF ( length(p_lpn_table(i).license_plate_number) = 0 ) THEN
841 IF (l_debug = 1) THEN
842 mdebug(' LPN name parameter consists of only spaces cannot create', G_ERROR);
843 END IF;
844 fnd_message.set_name('WMS', 'WMS_LPN_INAPPROPRIATE_SPACES');
845 fnd_msg_pub.ADD;
846 RAISE FND_API.G_EXC_ERROR;
847 END IF;
848
849 SELECT wms_license_plate_numbers_s1.NEXTVAL
850 INTO p_lpn_table(i).lpn_id
851 FROM DUAL;
852
853 IF (l_debug = 1) THEN
854 mdebug('Created lpn_id='||p_lpn_table(i).lpn_id||' for LPN '||p_lpn_table(i).license_plate_number, G_INFO);
855 END IF;
856
857 p_lpn_table(i).outermost_lpn_id := p_lpn_table(i).lpn_id;
858
859 l_progress := 'Passed validation inserting into bulk table';
860
861 To_LPNBulkRecType(
862 p_lpn_table => p_lpn_table
863 , p_table_first => i
864 , p_table_last => i
865 , p_record_last => l_lpn_bulk_rec.lpn_id.last
866 , x_lpn_bulk_rec => l_lpn_bulk_rec );
867
868 -- Insert into label printing table
869 l_input_param_tbl(i).lpn_id := p_lpn_table(i).lpn_id;
870
871 -- If caller is shipping we need to put LPNs in WDD as well
872 -- since they are in WDD, we will need to default the LPNs to picked
873 IF ( p_caller like 'WSH%' ) THEN
874 l_detail_info_tab(i).lpn_id := p_lpn_table(i).lpn_id;
875 l_detail_info_tab(i).container_name := p_lpn_table(i).license_plate_number;
876 l_detail_info_tab(i).organization_id := p_lpn_table(i).organization_id;
877 l_detail_info_tab(i).subinventory := p_lpn_table(i).subinventory_code;
878 l_detail_info_tab(i).locator_id := p_lpn_table(i).locator_id;
879 l_detail_info_tab(i).inventory_item_id := p_lpn_table(i).inventory_item_id;
880
881 l_detail_info_tab(i).net_weight := p_lpn_table(i).tare_weight;
882 l_detail_info_tab(i).gross_weight := p_lpn_table(i).tare_weight;
883 l_detail_info_tab(i).weight_uom_code := p_lpn_table(i).tare_weight_uom_code;
884
885 l_detail_info_tab(i).filled_volume := NULL;
886 l_detail_info_tab(i).volume := p_lpn_table(i).container_volume;
887 l_detail_info_tab(i).volume_uom_code := p_lpn_table(i).container_volume_uom;
888 END IF;
889 END LOOP;
890
891 -- Insert the newly created lpn id/license plate number record into the table
892 BEGIN
893 IF (l_debug = 1) THEN
894 mdebug('Bulk insert LPNs in WLPN: '||to_char(l_lpn_bulk_rec.lpn_id.first)||'-'||to_char(l_lpn_bulk_rec.lpn_id.last), G_INFO);
895 END IF;
896
897 FORALL j IN l_lpn_bulk_rec.lpn_id.first..l_lpn_bulk_rec.lpn_id.last
898 INSERT INTO wms_license_plate_numbers (
899 last_update_date
900 , last_updated_by
901 , creation_date
902 , created_by
903 , request_id
904
905 , lpn_id
906 , license_plate_number
907 , parent_lpn_id
908 , outermost_lpn_id
909 , lpn_context
910 , sealed_status
911
912 , organization_id
913 , subinventory_code
914 , locator_id
915
916 , inventory_item_id
917 , revision
918 , lot_number
919 , serial_number
920 , cost_group_id
921
922 , tare_weight_uom_code
923 , tare_weight
924 , gross_weight_uom_code
925 , gross_weight
926 , container_volume_uom
927 , container_volume
928 , content_volume_uom_code
929 , content_volume
930
931 , source_type_id
932 , source_header_id
933 , source_line_id
934 , source_line_detail_id
935 , source_name
936 )
937 VALUES (
938 SYSDATE
939 , l_user_id
940 , SYSDATE
941 , l_user_id
942 , l_request_id
943
944 , l_lpn_bulk_rec.lpn_id(j)
945 , l_lpn_bulk_rec.license_plate_number(j)
946 , l_lpn_bulk_rec.parent_lpn_id(j)
947 , l_lpn_bulk_rec.outermost_lpn_id(j)
948 , l_lpn_bulk_rec.lpn_context(j)
949 , 2 --sealed_status
950
951 , l_lpn_bulk_rec.organization_id(j)
952 , l_lpn_bulk_rec.subinventory_code(j)
953 , l_lpn_bulk_rec.locator_id(j)
954
955 , l_lpn_bulk_rec.inventory_item_id(j)
956 , l_lpn_bulk_rec.revision(j)
957 , l_lpn_bulk_rec.lot_number(j)
958 , l_lpn_bulk_rec.serial_number(j)
959 , l_lpn_bulk_rec.cost_group_id(j)
960
961 , l_lpn_bulk_rec.tare_weight_uom_code(j)
962 , l_lpn_bulk_rec.tare_weight(j)
963 , l_lpn_bulk_rec.tare_weight_uom_code(j)
964 , l_lpn_bulk_rec.tare_weight(j)
965 , l_lpn_bulk_rec.container_volume_uom(j)
966 , l_lpn_bulk_rec.container_volume(j)
967 , l_lpn_bulk_rec.content_volume_uom_code(j)
968 , NULL --content_volume
969
970 , l_lpn_bulk_rec.source_type_id(j)
971 , l_lpn_bulk_rec.source_header_id(j)
972 , l_lpn_bulk_rec.source_line_id(j)
973 , l_lpn_bulk_rec.source_line_detail_id(j)
974 , l_lpn_bulk_rec.source_name(j)
975 );
976 IF (l_debug = 1) THEN
977 mdebug('Bulk insert LPNs in WLPN done count='||SQL%ROWCOUNT, G_INFO);
978 END IF;
979 EXCEPTION
980 WHEN OTHERS THEN
981 IF (l_debug = 1) THEN
982 mdebug('Insert into WLPN failed SQL error: '|| SQLERRM(SQLCODE), G_ERROR);
983 END IF;
984
985 IF ( SQLCODE = 00001 ) THEN
986 FOR k IN l_lpn_bulk_rec.lpn_id.first..l_lpn_bulk_rec.lpn_id.last LOOP
987 --l_progress := 'Validate if LPN already exists in the system';
988 BEGIN
989 SELECT 1 INTO l_dummy_num
990 FROM wms_license_plate_numbers
991 WHERE license_plate_number = l_lpn_bulk_rec.license_plate_number(k);
992
993 IF ( l_debug = 1 ) THEN
994 mdebug('LPN '||l_lpn_bulk_rec.license_plate_number(k)||' already exists, cannot create it', G_ERROR);
995 END IF;
996 fnd_message.set_name('WMS', 'WMS_CONT_DUPLICATE_LPN');
997 fnd_message.set_token('LPN', l_lpn_bulk_rec.license_plate_number(k));
998 fnd_msg_pub.ADD;
999 RAISE fnd_api.g_exc_error;
1000 EXCEPTION
1001 WHEN NO_DATA_FOUND THEN
1002 NULL;
1003 END;
1004 END LOOP;
1005 END IF;
1006
1007 l_progress := 'Could not find reason for LPN insert failure. Give generic failure msg';
1008 fnd_message.set_name('WMS', 'WMS_LPN_NOTGEN');
1009 fnd_msg_pub.ADD;
1010 RAISE fnd_api.g_exc_error;
1011 END;
1012
1013 l_progress := 'Create LPN call to label printing';
1014
1015 BEGIN
1016 inv_label.print_label (
1017 p_api_version => 1.0
1018 , x_return_status => l_return_status
1019 , x_msg_count => x_msg_count
1020 , x_msg_data => x_msg_data
1021 , x_label_status => l_label_status
1022 , p_print_mode => 2
1023 , p_business_flow_code => 16
1024 , p_input_param_rec => l_input_param_tbl );
1025
1026 IF ( l_return_status <> fnd_api.g_ret_sts_success ) THEN
1027 IF (l_debug = 1) THEN
1028 mdebug('failed to print labels in create_lpns', G_ERROR);
1029 END IF;
1030 fnd_message.set_name('WMS', 'WMS_PRINT_LABEL_FAIL');
1031 fnd_msg_pub.ADD;
1032 END IF;
1033 EXCEPTION
1034 WHEN OTHERS THEN
1035 IF (l_debug = 1) THEN
1036 mdebug('Exception occured while calling print_label in create_lpns', G_ERROR);
1037 END IF;
1038 fnd_message.set_name('WMS', 'WMS_PRINT_LABEL_FAIL');
1039 fnd_msg_pub.ADD;
1040 END;
1041
1042 l_progress := 'Call shipping with new LPNs in need be';
1043 IF ( l_detail_info_tab.last > 0 )THEN
1044 IF (l_debug = 1) THEN
1045 mdebug('Calling Create_Update_Containers size='||l_detail_info_tab.last, G_INFO);
1046 END IF;
1047
1048 l_IN_rec.caller := 'WMS';
1049 l_IN_rec.action_code := 'CREATE';
1050
1051 WSH_WMS_LPN_GRP.Create_Update_Containers (
1052 p_api_version => 1.0
1053 , p_init_msg_list => fnd_api.g_false
1054 , p_commit => fnd_api.g_false
1055 , x_return_status => x_return_status
1056 , x_msg_count => x_msg_count
1057 , x_msg_data => x_msg_data
1058 , p_detail_info_tab => l_detail_info_tab
1059 , p_IN_rec => l_IN_rec
1060 , x_OUT_rec => l_OUT_rec );
1061
1062 IF ( x_return_status <> fnd_api.g_ret_sts_success ) THEN
1063 IF (l_debug = 1) THEN
1064 mdebug('Create_Update_Containers Failed', G_ERROR);
1065 END IF;
1066 RAISE fnd_api.g_exc_error;
1067 ELSIF ( l_debug = 1 ) THEN
1068 mdebug('Done with Create_Update_Containers', G_INFO);
1069 END IF;
1070 END IF;
1071
1072 l_progress := 'End of API body';
1073
1074 -- Standard check of p_commit.
1075 IF fnd_api.to_boolean(p_commit) THEN
1076 COMMIT WORK;
1077 END IF;
1078
1079 -- Standard call to get message count and data
1080 fnd_msg_pub.count_and_get(p_count => x_msg_count, p_data => x_msg_data);
1081 EXCEPTION
1082 WHEN FND_API.G_EXC_ERROR THEN
1083 x_return_status := fnd_api.g_ret_sts_error;
1084 FND_MSG_PUB.Count_And_Get(p_count => x_msg_count, p_data => x_msg_data);
1085 IF (l_debug = 1) THEN
1086 FOR i in 1..x_msg_count LOOP
1087 l_msgdata := substr(l_msgdata||' | '||substr(fnd_msg_pub.get(x_msg_count-i+1, 'F'), 0, 200),1,2000);
1088 END LOOP;
1089 mdebug(l_api_name ||' Error progress='||l_progress||' SQL error: '|| SQLERRM(SQLCODE), G_ERROR);
1090 mdebug('msg: '||l_msgdata, G_ERROR);
1091 END IF;
1092 ROLLBACK TO CREATE_LPNS_PVT;
1093
1094 -- Failed to generate remove lpn_ids from table
1095 FOR i IN p_lpn_table.first .. p_lpn_table.last LOOP
1096 p_lpn_table(i).lpn_id := NULL;
1097 END LOOP;
1098 WHEN OTHERS THEN
1099 x_return_status := fnd_api.g_ret_sts_unexp_error;
1100 fnd_message.set_name('WMS', 'WMS_LPN_NOTGEN');
1101 fnd_msg_pub.ADD;
1102 FND_MSG_PUB.Count_And_Get(p_count => x_msg_count, p_data => x_msg_data);
1103 IF (l_debug = 1) THEN
1104 mdebug(l_api_name ||' Error progress='||l_progress||' SQL error: '|| SQLERRM(SQLCODE), G_ERROR);
1105 END IF;
1106 ROLLBACK TO CREATE_LPNS_PVT;
1107
1108 -- Failed to generate remove lpn_ids from table
1109 FOR i IN p_lpn_table.first .. p_lpn_table.last LOOP
1110 p_lpn_table(i).lpn_id := NULL;
1111 END LOOP;
1112 END Create_LPNs;
1113
1114 -- ----------------------------------------------------------------------------------
1115 -- ----------------------------------------------------------------------------------
1116
1117 PROCEDURE Auto_Create_LPNs (
1118 p_api_version IN NUMBER
1119 , p_init_msg_list IN VARCHAR2
1120 , p_commit IN VARCHAR2
1121 , x_return_status OUT NOCOPY VARCHAR2
1122 , x_msg_count OUT NOCOPY NUMBER
1123 , x_msg_data OUT NOCOPY VARCHAR2
1124 , p_caller IN VARCHAR2
1125 , p_quantity IN NUMBER
1126 , p_lpn_prefix IN VARCHAR2
1127 , p_lpn_suffix IN VARCHAR2
1128 , p_starting_number IN NUMBER
1129 , p_total_lpn_length IN NUMBER
1130 , p_ucc_128_suffix_flag IN VARCHAR2
1131 , p_lpn_attributes IN WMS_Data_Type_Definitions_PUB.LPNRecordType
1132 , p_serial_ranges IN WMS_Data_Type_Definitions_PUB.SerialRangeTableType
1133 , x_created_lpns OUT NOCOPY WMS_Data_Type_Definitions_PUB.LPNTableType
1134 ) IS
1135 l_api_name CONSTANT VARCHAR2(30) := 'Auto_Create_LPNs';
1136 l_api_version CONSTANT NUMBER := 1.0;
1137 l_debug NUMBER := NVL(FND_PROFILE.VALUE('INV_DEBUG_TRACE'),0);
1138 l_progress VARCHAR2(500) := 'Entered API';
1139 l_msgdata VARCHAR2(1000);
1140
1141 -- Constants used for LPN processing
1142 l_from_user CONSTANT NUMBER := 1;
1143 l_from_db_seq CONSTANT NUMBER := 2;
1144 l_from_org CONSTANT NUMBER := 3;
1145
1146 l_lpn_tab WMS_Data_Type_Definitions_PUB.LPNTableType;
1147 l_serial_rec WMS_Data_Type_Definitions_PUB.SerialRangeRecordType;
1148
1149 -- Local copies of input params that may need update from defaults
1150 l_quantity NUMBER := p_quantity ;
1151 l_lpn_prefix VARCHAR2(50) := p_lpn_prefix;
1152 l_lpn_suffix VARCHAR2(50) := p_lpn_suffix;
1153 l_total_lpn_length NUMBER := p_total_lpn_length;
1154 l_ucc_128_suffix_flag VARCHAR2(1) := p_ucc_128_suffix_flag;
1155
1156 -- Variable used to creaate LPN name
1157 l_seq_source NUMBER;
1158 l_loop_cnt NUMBER;
1159 l_lpn_cnt NUMBER;
1160 l_curr_seq NUMBER;
1161 l_last_org_seq NUMBER;
1162 l_lpn_seq_length NUMBER;
1163 l_dummy_number NUMBER;
1164
1165 -- Varibles used for Serial processing
1166 l_current_serial VARCHAR2(30);
1167 l_current_number NUMBER;
1168 l_padded_length NUMBER;
1169
1170 BEGIN
1171 -- Standard Start of API savepoint
1172 SAVEPOINT AUTO_CREATE_LPNS_PVT;
1173
1174 -- Standard call to check for call compatibility.
1175 IF NOT fnd_api.compatible_api_call(l_api_version, p_api_version, l_api_name, g_pkg_name) THEN
1176 fnd_message.set_name('WMS', 'WMS_CONT_INCOMPATIBLE_API_CALL');
1177 fnd_msg_pub.ADD;
1178 RAISE fnd_api.g_exc_unexpected_error;
1179 END IF;
1180
1181 -- Initialize message list if p_init_msg_list is set to TRUE.
1182 IF fnd_api.to_boolean(p_init_msg_list) THEN
1183 fnd_msg_pub.initialize;
1184 END IF;
1185
1186 -- Initialize API return status to success
1187 x_return_status := fnd_api.g_ret_sts_success;
1188
1189 -- API body
1190 IF (l_debug = 1) THEN
1191 mdebug(l_api_name || ' Entered ' || g_pkg_version, 1);
1192 mdebug('ver='||p_api_version||' initmsg='||p_init_msg_list||' commit='||p_commit||' caller='||p_caller, G_INFO);
1193 mdebug('org='||p_lpn_attributes.organization_id||' sub='||p_lpn_attributes.subinventory_code||' loc='||p_lpn_attributes.locator_id||' itm='||p_lpn_attributes.inventory_item_id||' pfx='||p_lpn_prefix||' sfx='||p_lpn_suffix||
1194 ' snum='||p_starting_number||' qty='||p_quantity||' ctx='||p_lpn_attributes.lpn_context||' lgth='||p_total_lpn_length||' ucc='||p_ucc_128_suffix_flag, G_INFO);
1195 mdebug('srctype='||p_lpn_attributes.source_type_id||' srchdr='||p_lpn_attributes.source_header_id||' srcln='||p_lpn_attributes.source_line_id||' trxid='||p_lpn_attributes.source_transaction_id, G_INFO);
1196 END IF;
1197
1198 l_progress := 'Validate quantity';
1199 IF ( NVL(p_quantity, -1) < 0 ) THEN
1200 fnd_message.set_name('WMS', 'WMS_INVALID_QTY');
1201 fnd_msg_pub.ADD;
1202 RAISE fnd_api.g_exc_error;
1203 END IF;
1204
1205 l_progress := 'Validate Organization ID';
1206
1207 IF ( NOT Inv_Cache.set_org_rec( p_organization_id => p_lpn_attributes.organization_id ) )THEN
1208 IF (l_debug = 1) THEN
1209 mdebug(p_lpn_attributes.organization_id||' is an invalid organization id', G_ERROR);
1210 END IF;
1211 fnd_message.set_name('WMS', 'WMS_CONT_INVALID_ORG');
1212 fnd_msg_pub.ADD;
1213 RAISE fnd_api.g_exc_error;
1214 END IF;
1215
1216 IF (l_debug = 1) THEN
1217 mdebug('Got org info pfx='||inv_cache.org_rec.lpn_prefix||' sfx='||inv_cache.org_rec.lpn_suffix||' seq='||inv_cache.org_rec.lpn_starting_number||' lgth='||inv_cache.org_rec.total_lpn_length||' ucc='||inv_cache.org_rec.ucc_128_suffix_flag, 5);
1218 END IF;
1219
1220 IF ( p_lpn_attributes.inventory_item_id IS NOT NULL) THEN
1221 l_progress := 'Validate Container Item';
1222
1223 IF ( inv_cache.set_item_rec(
1224 p_organization_id => p_lpn_attributes.organization_id
1225 , p_item_id => p_lpn_attributes.inventory_item_id ) )
1226 THEN
1227 IF (l_debug = 1) THEN
1228 mdebug('Itm info citm='||inv_cache.item_rec.container_item_flag||' snctl='||inv_cache.item_rec.serial_number_control_code, G_INFO);
1229 END IF;
1230
1231 IF ( inv_cache.item_rec.container_item_flag = 'N' ) THEN
1232 IF (l_debug = 1) THEN
1233 mdebug(p_lpn_attributes.inventory_item_id|| ' is not a container', G_ERROR);
1234 END IF;
1235 fnd_message.set_name('WMS', 'WMS_ITEM_NOT_CONTAINER');
1236 fnd_message.set_token('ITEM', inv_cache.item_rec.segment1);
1237 fnd_msg_pub.ADD;
1238 RAISE fnd_api.g_exc_error;
1239 END IF;
1240 ELSE
1241 l_progress := 'Error calling INV_CACHE.Set_Item_Rec for orgid'||p_lpn_attributes.organization_id||' item id='||p_lpn_attributes.inventory_item_id;
1242 fnd_message.set_name('WMS', 'WMS_CONT_INVALID_ITEM');
1243 fnd_msg_pub.ADD;
1244 RAISE fnd_api.g_exc_error;
1245 END IF;
1246 END IF;
1247
1248 l_progress := 'Determine the source for LPN seq starting number';
1249
1250 IF ( p_starting_number IS NOT NULL ) THEN
1251 IF ( p_starting_number < 0 ) THEN
1252 IF (l_debug = 1) THEN
1253 mdebug(p_starting_number || ' is an invalid start num', G_ERROR);
1254 END IF;
1255 fnd_message.set_name('WMS', 'WMS_CONT_INVALID_START_NUM');
1256 fnd_msg_pub.ADD;
1257 RAISE fnd_api.g_exc_error;
1258 END IF;
1259
1260 l_seq_source := l_from_user;
1261 l_curr_seq := p_starting_number;
1262 ELSIF ( inv_cache.org_rec.lpn_starting_number IS NOT NULL ) THEN
1263 l_seq_source := l_from_org;
1264 l_curr_seq := null;
1265 ELSE
1266 -- neither defined at org level or user level use db seq
1267 l_seq_source := l_from_db_seq;
1268 END IF;
1269
1270 l_progress := 'UCC128 validation';
1271 -- If any user defined values are not given, use values defined
1272 -- at the organization level
1273
1274 IF ( l_ucc_128_suffix_flag IS NULL ) THEN
1275 l_ucc_128_suffix_flag := inv_cache.org_rec.ucc_128_suffix_flag;
1276 END IF;
1277
1278 IF ( l_lpn_prefix = FND_API.G_MISS_CHAR ) THEN
1279 l_lpn_prefix := NULL;
1280 ELSE
1281 l_lpn_prefix := NVL(l_lpn_prefix, inv_cache.org_rec.lpn_prefix);
1282 END IF;
1283
1284 IF ( l_lpn_suffix = FND_API.G_MISS_CHAR ) THEN
1285 l_lpn_suffix := NULL;
1286 ELSE
1287 l_lpn_suffix := NVL(l_lpn_suffix, inv_cache.org_rec.lpn_suffix );
1288 END IF;
1289
1290 IF ( l_total_lpn_length = FND_API.G_MISS_NUM ) THEN
1291 l_total_lpn_length := NULL;
1292 ELSE
1293 l_total_lpn_length := NVL(l_total_lpn_length, inv_cache.org_rec.total_lpn_length);
1294 END IF;
1295
1296 IF ( l_ucc_128_suffix_flag = 'Y' ) THEN
1297 BEGIN
1298 l_dummy_number := to_number(l_lpn_prefix);
1299 EXCEPTION
1300 WHEN OTHERS THEN
1301 IF (l_debug = 1) THEN
1302 mdebug('LPN prefix is invalid: ' || l_lpn_prefix, G_ERROR);
1303 END IF;
1304 fnd_message.set_name('INV', 'INV_INTEGER_GREATER_THAN_0');
1305 fnd_message.set_token('ENTITY1','INV_LPN_PREFIX');
1306 fnd_msg_pub.ADD;
1307 RAISE fnd_api.g_exc_error;
1308 END;
1309 END IF;
1310
1311 IF ( l_total_lpn_length IS NOT NULL ) THEN
1312 l_lpn_seq_length := l_total_lpn_length - NVL(LENGTH(l_lpn_prefix), 0);
1313
1314 -- UCC128 uses a check digit in place of suffix. subtract one for that digit
1315 IF ( l_ucc_128_suffix_flag = 'Y' ) THEN
1316 l_lpn_seq_length := l_lpn_seq_length - 1;
1317 ELSE
1318 l_lpn_seq_length := l_lpn_seq_length - NVL(LENGTH(l_lpn_suffix), 0);
1319 END IF;
1320
1321 IF ( l_lpn_seq_length <= 0 ) THEN
1322 IF (l_debug = 1) THEN
1323 mdebug('total length '||l_total_lpn_length||' less than sum length of prefix '||l_lpn_prefix||' and suffix '||l_lpn_suffix, G_ERROR);
1324 END IF;
1325 fnd_message.set_name('WMS', 'WMS_LPN_TOTAL_LENGTH_INVALID');
1326 fnd_msg_pub.ADD;
1327 RAISE fnd_api.g_exc_error;
1328 END IF;
1329 ELSE
1330 l_lpn_seq_length := 0;
1331 END IF;
1332
1333 l_progress := 'Checking for serial numbers';
1334
1335 IF ( p_serial_ranges.last > 0 AND p_serial_ranges(1).fm_serial_number IS NOT NULL ) THEN
1336 -- Check that item is under serial control
1337 IF ( p_lpn_attributes.inventory_item_id IS NULL OR inv_cache.item_rec.serial_number_control_code = 1 ) THEN
1338 IF (l_debug = 1) THEN
1339 mdebug('Item '||inv_cache.item_rec.inventory_item_id||' is not serial controlled', G_ERROR);
1340 END IF;
1341 fnd_message.set_name('WMS', 'WMS_CONT_INVALID_SER');
1342 fnd_msg_pub.ADD;
1343 RAISE fnd_api.g_exc_error;
1344 END IF;
1345
1346 -- For now only support a single range of serial numbers
1347 l_serial_rec.fm_serial_number := p_serial_ranges(1).fm_serial_number;
1348 l_serial_rec.to_serial_number := NVL(p_serial_ranges(1).to_serial_number, p_serial_ranges(1).fm_serial_number);
1349 l_current_serial := l_serial_rec.fm_serial_number;
1350
1351 l_progress := 'Call this API to inv_serial_info';
1352
1353 IF ( NOT mtl_serial_check.inv_serial_info (
1354 p_from_serial_number => l_serial_rec.fm_serial_number
1355 , p_to_serial_number => l_serial_rec.to_serial_number
1356 , x_prefix => l_serial_rec.prefix
1357 , x_quantity => l_serial_rec.quantity
1358 , x_from_number => l_serial_rec.fm_number
1359 , x_to_number => l_serial_rec.to_number
1360 , x_errorcode => l_dummy_number ) )
1361 THEN
1362 IF (l_debug = 1) THEN
1363 mdebug(l_serial_rec.to_serial_number||' failed INV_Serial_Info x_errorcode='||l_dummy_number, G_ERROR);
1364 END IF;
1365 fnd_message.set_name('WMS', 'WMS_CONT_INVALID_SER');
1366 fnd_msg_pub.ADD;
1367 RAISE fnd_api.g_exc_error;
1368 END IF;
1369
1370 -- Quantity of LPNs will be determined by serial range
1371 l_quantity := l_serial_rec.quantity;
1372 l_current_serial := l_serial_rec.fm_serial_number;
1373 l_current_number := l_serial_rec.fm_number;
1374
1375 IF (l_debug = 1) THEN
1376 mdebug('SN info qty='||l_quantity||' pfx='||l_serial_rec.prefix||' fm#='||l_serial_rec.fm_number||' to#='||l_serial_rec.to_number, G_INFO);
1377 END IF;
1378 ELSE
1379 l_current_serial := NULL;
1380 END IF;
1381
1382 IF (l_debug = 1) THEN
1383 mdebug('prefix='||l_lpn_prefix||' suffix='||l_lpn_suffix||' seq='||l_curr_seq||' suffix flag='||l_ucc_128_suffix_flag, G_INFO);
1384 END IF;
1385
1386 l_loop_cnt := 1;
1387 l_lpn_cnt := 1;
1388
1389 WHILE ( l_lpn_cnt <= l_quantity ) LOOP
1390
1391 IF ( l_seq_source = l_from_db_seq ) THEN
1392 SELECT wms_license_plate_numbers_s2.NEXTVAL
1393 INTO l_curr_seq
1394 FROM DUAL;
1395 ELSIF ( l_seq_source = l_from_org ) THEN
1396 -- If taken from org parameters make sure the new seq is within the range
1397 -- already allocated, if not will need to allocate more
1398 IF ( l_curr_seq IS NULL OR l_curr_seq = l_last_org_seq ) THEN
1399 Get_Update_LPN_Start_Num (
1400 p_org_id => p_lpn_attributes.organization_id
1401 , p_qty => l_quantity - l_lpn_cnt + 1
1402 , x_curr_seq => l_curr_seq );
1403
1404 -- Keep track of the last sequence fetched from the org params
1405 l_last_org_seq := l_curr_seq + l_quantity - l_lpn_cnt + 1;
1406 IF (l_debug = 1) THEN
1407 mdebug('Got seq from org curr_seq='||l_curr_seq||' last_org_seq='||l_last_org_seq, G_INFO);
1408 END IF;
1409 END IF;
1410 END IF;
1411
1412 -- Generate a valid license plate number
1413 l_lpn_tab(l_lpn_cnt).license_plate_number := l_lpn_prefix || LPAD(l_curr_seq, GREATEST(length(l_curr_seq), l_lpn_seq_length), '0');
1414
1415 IF ( l_ucc_128_suffix_flag = 'Y' ) THEN
1416 l_progress := 'Call api to calculate and append check digit to end of LPN';
1417 l_lpn_tab(l_lpn_cnt).license_plate_number := l_lpn_tab(l_lpn_cnt).license_plate_number || Generate_Check_Digit(l_debug, l_lpn_tab(l_lpn_cnt).license_plate_number);
1418 ELSE
1419 l_progress := 'Not UCC128 LPN normal LPN name generatation';
1420 l_lpn_tab(l_lpn_cnt).license_plate_number := l_lpn_tab(l_lpn_cnt).license_plate_number || l_lpn_suffix;
1421 END IF;
1422
1423 l_progress := 'Check that new LPN does not alreay exist in WLPN';
1424
1425 BEGIN
1426 SELECT 1
1427 INTO l_dummy_number
1428 FROM WMS_LICENSE_PLATE_NUMBERS
1429 WHERE license_plate_number = l_lpn_tab(l_lpn_cnt).license_plate_number;
1430 EXCEPTION
1431 WHEN NO_DATA_FOUND THEN
1432 l_dummy_number := 2;
1433 END;
1434
1435 IF ( l_dummy_number <> 1 ) THEN
1436 l_progress := 'LPN does not exist yet insert into LPN table';
1437
1438 -- Validate LPN total length if total length is passed.
1439 IF ( l_total_lpn_length < length(l_lpn_tab(l_lpn_cnt).license_plate_number) ) THEN
1440 IF (l_debug = 1) THEN
1441 mdebug('LPN name '||l_lpn_tab(l_lpn_cnt).license_plate_number||' exceeds total length '||l_total_lpn_length, G_ERROR);
1442 END IF;
1443 fnd_message.set_name('WMS', 'WMS_LPN_TOTAL_LENGTH_INVALID');
1444 fnd_msg_pub.ADD;
1445 RAISE fnd_api.g_exc_error;
1446 END IF;
1447
1448 l_progress := 'Insert the newly created lpn id/license plate number record into the table';
1449
1450 l_lpn_tab(l_lpn_cnt).lpn_context := p_lpn_attributes.lpn_context;
1451 l_lpn_tab(l_lpn_cnt).organization_id := p_lpn_attributes.organization_id;
1452 l_lpn_tab(l_lpn_cnt).subinventory_code := p_lpn_attributes.subinventory_code;
1453 l_lpn_tab(l_lpn_cnt).locator_id := p_lpn_attributes.locator_id;
1454
1455 l_lpn_tab(l_lpn_cnt).inventory_item_id := p_lpn_attributes.inventory_item_id;
1456 l_lpn_tab(l_lpn_cnt).revision := p_lpn_attributes.revision;
1457 l_lpn_tab(l_lpn_cnt).lot_number := p_lpn_attributes.lot_number;
1458 l_lpn_tab(l_lpn_cnt).serial_number := l_current_serial;
1459 l_lpn_tab(l_lpn_cnt).cost_group_id := p_lpn_attributes.cost_group_id;
1460
1461 l_lpn_tab(l_lpn_cnt).source_type_id := p_lpn_attributes.source_type_id;
1462 l_lpn_tab(l_lpn_cnt).source_header_id := p_lpn_attributes.source_header_id;
1463 l_lpn_tab(l_lpn_cnt).source_line_id := p_lpn_attributes.source_line_id;
1464 l_lpn_tab(l_lpn_cnt).source_line_detail_id := p_lpn_attributes.source_line_detail_id;
1465 l_lpn_tab(l_lpn_cnt).source_name := p_lpn_attributes.source_name;
1466 l_lpn_tab(l_lpn_cnt).source_transaction_id := p_lpn_attributes.source_transaction_id;
1467
1468 IF (l_debug = 1) THEN
1469 mdebug('Created LPN name '||l_lpn_tab(l_lpn_cnt).license_plate_number||' lpn_cnt='||l_lpn_cnt||' curr_seq='||l_curr_seq||' loop_cnt='||l_loop_cnt, G_INFO);
1470 END IF;
1471
1472 l_progress := 'Increment the current serial number';
1473
1474 IF ( l_current_serial IS NOT NULL ) THEN
1475 l_padded_length := LENGTH(l_current_serial) - LENGTH(l_current_number);
1476 l_current_number := l_current_number + 1;
1477
1478 -- See bug 2375043 for info on why this is done
1479 IF ( l_serial_rec.prefix IS NOT NULL ) THEN
1480 l_current_serial := RPAD(l_serial_rec.prefix, l_padded_length, '0') || l_current_number;
1481 ELSE
1482 l_current_serial := RPAD('@',l_padded_length+1,'0') || l_current_number;
1483 l_current_serial := Substr(l_current_serial,2);
1484 END IF;
1485 END IF;
1486
1487 l_progress := 'Done creating LPN name increment counter';
1488 l_lpn_cnt := l_lpn_cnt + 1;
1489 ELSE -- LPN already exists in WLPN
1490 IF ( l_seq_source = l_from_user ) THEN
1491 IF ( l_debug = 1 ) THEN
1492 mdebug('Cannot generate LPNs with user defined starting number', G_ERROR);
1493 END IF;
1494 fnd_message.set_name('WMS', 'WMS_CONT_DUPLICATE_LPN');
1495 fnd_message.set_token('LPN', l_lpn_tab(l_lpn_cnt).license_plate_number);
1496 fnd_msg_pub.ADD;
1497 RAISE fnd_api.g_exc_error;
1498 ELSIF ( l_loop_cnt > l_quantity + 1000 ) THEN
1499 IF ( l_debug = 1 ) THEN
1500 mdebug('Cannot find valid LPN sequence after 1000 Attempts', G_ERROR);
1501 END IF;
1502 fnd_message.set_name('WMS', 'WMS_GEN_LPN_LOOP_ERR');
1503 fnd_message.set_token('NUM', '1000');
1504 fnd_msg_pub.ADD;
1505 RAISE fnd_api.g_exc_error;
1506 ELSIF ( l_debug = 1 ) THEN
1507 mdebug('LPN '||l_lpn_tab(l_lpn_cnt).license_plate_number||' already exists trying new sequence', G_INFO);
1508 END IF;
1509 END IF;
1510
1511 -- If LPN sequence is not taken from DB, need to incrament manually
1512 l_curr_seq := l_curr_seq + 1;
1513
1514 -- Keep track of total number of loops done to avoid infinite loop
1515 l_loop_cnt := l_loop_cnt + 1;
1516 END LOOP;
1517
1518 l_progress := 'Call Create_LPNs number of rec='||l_lpn_tab.last;
1519
1520 Create_LPNs (
1521 p_api_version => p_api_version
1522 , p_init_msg_list => fnd_api.g_false
1523 , p_commit => fnd_api.g_false
1524 , x_return_status => x_return_status
1525 , x_msg_count => x_msg_count
1526 , x_msg_data => x_msg_data
1527 , p_caller => p_caller
1528 , p_lpn_table => l_lpn_tab );
1529
1530 IF ( x_return_status <> fnd_api.g_ret_sts_success ) THEN
1531 IF (l_debug = 1) THEN
1532 mdebug('Create_LPNs failed', G_ERROR);
1533 END IF;
1534 RAISE fnd_api.g_exc_error;
1535 END IF;
1536
1537 x_created_lpns := l_lpn_tab;
1538
1539 -- Standard check of p_commit.
1540 IF fnd_api.to_boolean(p_commit) THEN
1541 COMMIT WORK;
1542 END IF;
1543
1544 -- Standard call to get message count and data
1545 fnd_msg_pub.count_and_get(p_count => x_msg_count, p_data => x_msg_data);
1546 EXCEPTION
1547 WHEN FND_API.G_EXC_ERROR THEN
1548 x_return_status := fnd_api.g_ret_sts_error;
1549 FND_MSG_PUB.Count_And_Get(p_count => x_msg_count, p_data => x_msg_data);
1550 IF (l_debug = 1) THEN
1551 FOR i in 1..x_msg_count LOOP
1552 l_msgdata := substr(l_msgdata||' | '||substr(fnd_msg_pub.get(x_msg_count-i+1, 'F'), 0, 200),1,2000);
1553 END LOOP;
1554 mdebug(l_api_name ||' Error progress='||l_progress||' SQL error: '|| SQLERRM(SQLCODE), G_ERROR);
1555 mdebug('msg: '||l_msgdata, G_ERROR);
1556 END IF;
1557 ROLLBACK TO AUTO_CREATE_LPNS_PVT;
1558 WHEN OTHERS THEN
1559 x_return_status := fnd_api.g_ret_sts_unexp_error;
1560 fnd_message.set_name('WMS', 'WMS_LPN_GENERATION_FAIL');
1561 fnd_msg_pub.ADD;
1562 FND_MSG_PUB.Count_And_Get(p_count => x_msg_count, p_data => x_msg_data);
1563 IF (l_debug = 1) THEN
1564 mdebug(l_api_name ||' Error progress='||l_progress||' SQL error: '|| SQLERRM(SQLCODE), G_ERROR);
1565 END IF;
1566 ROLLBACK TO AUTO_CREATE_LPNS_PVT;
1567 END Auto_Create_LPNs;
1568
1569 -- ----------------------------------------------------------------------------------
1570 -- ----------------------------------------------------------------------------------
1571
1572 PROCEDURE Modify_LPNs (
1573 p_api_version IN NUMBER
1574 , p_init_msg_list IN VARCHAR2
1575 , p_commit IN VARCHAR2
1576 , x_return_status OUT NOCOPY VARCHAR2
1577 , x_msg_count OUT NOCOPY NUMBER
1578 , x_msg_data OUT NOCOPY VARCHAR2
1579 , p_caller IN VARCHAR2
1580 , p_lpn_table IN WMS_Data_Type_Definitions_PUB.LPNTableType
1581 ) IS
1582 l_api_name CONSTANT VARCHAR2(30) := 'Modify_LPNs';
1583 l_api_version CONSTANT NUMBER := 1.0;
1584 l_debug NUMBER := NVL(FND_PROFILE.VALUE('INV_DEBUG_TRACE'),0);
1585 l_progress VARCHAR2(500) := 'Entered API';
1586 l_msgdata VARCHAR2(1000);
1587 l_delivery_id NUMBER ; --7119011
1588 l_status_code VARCHAR2(2) := 'OP'; --7119011 / 7603755
1589 l_return_status VARCHAR2(2); --7119011
1590
1591 CURSOR nested_parent_lpn_cursor (p_parent_lpn_id NUMBER) IS
1592 SELECT lpn_id
1593 , license_plate_number
1594 , parent_lpn_id
1595 , outermost_lpn_id
1596 , lpn_context
1597
1598 , organization_id
1599 , subinventory_code
1600 , locator_id
1601
1602 , inventory_item_id
1603 , revision
1604 , lot_number
1605 , serial_number
1606 , cost_group_id
1607
1608 , tare_weight_uom_code
1609 , tare_weight
1610 , gross_weight_uom_code
1611 , gross_weight
1612 , container_volume_uom
1613 , container_volume
1614 , content_volume_uom_code
1615 , content_volume
1616
1617 , source_type_id
1618 , source_header_id
1619 , source_line_id
1620 , source_line_detail_id
1621 , source_name
1622
1623 , attribute_category
1624 , attribute1
1625 , attribute2
1626 , attribute3
1627 , attribute4
1628 , attribute5
1629 , attribute6
1630 , attribute7
1631 , attribute8
1632 , attribute9
1633 , attribute10
1634 , attribute11
1635 , attribute12
1636 , attribute13
1637 , attribute14
1638 , attribute15
1639 FROM wms_license_plate_numbers
1640 START WITH lpn_id = p_parent_lpn_id
1641 CONNECT BY lpn_id = PRIOR parent_lpn_id
1642 FOR UPDATE NOWAIT;
1643
1644 CURSOR nested_child_lpn_cursor (p_lpn_id NUMBER) IS
1645 SELECT lpn_id
1646 , license_plate_number
1647 , parent_lpn_id
1648 , outermost_lpn_id
1649 , lpn_context
1650
1651 , organization_id
1652 , subinventory_code
1653 , locator_id
1654
1655 , inventory_item_id
1656 , revision
1657 , lot_number
1658 , serial_number
1659 , cost_group_id
1660
1661 , tare_weight_uom_code
1662 , tare_weight
1663 , gross_weight_uom_code
1664 , gross_weight
1665 , container_volume_uom
1666 , container_volume
1667 , content_volume_uom_code
1668 , content_volume
1669
1670 , source_type_id
1671 , source_header_id
1672 , source_line_id
1673 , source_line_detail_id
1674 , source_name
1675
1676 , attribute_category
1677 , attribute1
1678 , attribute2
1679 , attribute3
1680 , attribute4
1681 , attribute5
1682 , attribute6
1683 , attribute7
1684 , attribute8
1685 , attribute9
1686 , attribute10
1687 , attribute11
1688 , attribute12
1689 , attribute13
1690 , attribute14
1691 , attribute15
1692 FROM wms_license_plate_numbers
1693 START WITH parent_lpn_id = p_lpn_id
1694 CONNECT BY parent_lpn_id = PRIOR lpn_id
1695 FOR UPDATE NOWAIT;
1696
1697 --Bug #3516547
1698 CURSOR lpn_item_control_cursor (p_old_org_id NUMBER, p_new_org_id NUMBER, p_outermost_lpn_id NUMBER) IS
1699 SELECT wlc.rowid
1700 , wlc.inventory_item_id
1701 , msi.primary_uom_code
1702 , msi.serial_number_control_code
1703 , msi.lot_control_code
1704 , msi.revision_qty_control_code
1705 FROM wms_license_plate_numbers wlpn
1706 , wms_lpn_contents wlc
1707 , mtl_system_items msi
1708 WHERE wlpn.organization_id = p_old_org_id
1709 AND wlpn.outermost_lpn_id = p_outermost_lpn_id
1710 AND wlc.parent_lpn_id = wlpn.lpn_id
1711 AND msi.inventory_item_id = wlc.inventory_item_id
1712 AND msi.organization_id = p_new_org_id
1713 ORDER BY wlc.inventory_item_id;
1714 --End of changes for Bug #3516547
1715
1716 -- Types needed for WSH_WMS_LPN_GRP.Create_Update_Containers
1717 wsh_update_tbl WSH_Glbl_Var_Strct_GRP.delivery_details_Attr_tbl_Type;
1718 wsh_create_tbl WSH_Glbl_Var_Strct_GRP.delivery_details_Attr_tbl_Type;
1719 l_IN_rec WSH_GLBL_VAR_STRCT_GRP.detailInRecType;
1720 l_OUT_rec WSH_GLBL_VAR_STRCT_GRP.detailOutRecType;
1721
1722 -- Types needed for WSH_WMS_LPN_GRP.Delivery_Detail_Action
1723 l_wsh_del_det_id_tbl wsh_util_core.id_tab_type;
1724 l_wsh_action_prms WSH_GLBL_VAR_STRCT_GRP.dd_action_parameters_rec_type;
1725 l_wsh_defaults WSH_GLBL_VAR_STRCT_GRP.dd_default_parameters_rec_type;
1726 l_wsh_action_out_rec WSH_GLBL_VAR_STRCT_GRP.dd_action_out_rec_type;
1727
1728 -- Types needed for WSH_WMS_LPN_GRP.Delivery_Detail_Action
1729 -- Need 2 different tables one for lpns that need to be unpacked one for
1730 -- lpns thatn need to be deleted
1731 l_wsh_unpack_lpn_id_tbl wsh_util_core.id_tab_type;
1732 l_wsh_delete_lpn_id_tbl wsh_util_core.id_tab_type;
1733
1734 -- Variables used to store LPN information
1735 l_lpn_ids WMS_Data_Type_Definitions_PUB.NumberTableType;
1736 l_outer_lpn_ids WMS_Data_Type_Definitions_PUB.NumberTableType;
1737
1738 l_lpn_tab_i NUMBER;
1739 l_tmp_i NUMBER;
1740 l_dummy_num NUMBER;
1741
1742 l_tmp_new WMS_Data_Type_Definitions_PUB.LPNRecordType;
1743 l_tmp_old WMS_Data_Type_Definitions_PUB.LPNRecordType;
1744 l_new WMS_Data_Type_Definitions_PUB.LPNRecordType;
1745 l_old WMS_Data_Type_Definitions_PUB.LPNRecordType;
1746 l_lpns WMS_Data_Type_Definitions_PUB.LPNTableType;
1747 l_outer_lpns WMS_Data_Type_Definitions_PUB.LPNTableType;
1748 l_lpn_bulk_rec LPNBulkRecType;
1749
1750 -- Temp variables needed for wt/vol calculation
1751 l_change_in_gross_weight NUMBER;
1752 l_change_in_gross_weight_uom VARCHAR2(3);
1753
1754 l_change_in_weight NUMBER; --Added for Bug#6504032
1755 l_change_in_weight_uom VARCHAR2(3); --Added for Bug#6504032
1756
1757 -- bug5404902 added to store tare weight change
1758 l_change_in_tare_weight NUMBER;
1759 l_change_in_tare_weight_uom VARCHAR2(3);
1760
1761 l_change_in_volume NUMBER;
1762 l_change_in_volume_uom VARCHAR2(3);
1763
1764 --Flag added to identify LPN context change from 'Loaded to Truck' to
1765 --'Defined but not used' which is only for Internal Orders
1766 --Bug number 5639121
1767 l_internal_order_flag NUMBER := 0;
1768
1769 BEGIN
1770 -- Standard Start of API savepoint
1771 SAVEPOINT MODIFY_LPNS_PVT;
1772
1773 -- Standard call to check for call compatibility.
1774 IF NOT fnd_api.compatible_api_call(l_api_version, p_api_version, l_api_name, g_pkg_name) THEN
1775 fnd_message.set_name('WMS', 'WMS_CONT_INCOMPATIBLE_API_CALL');
1776 fnd_msg_pub.ADD;
1777 RAISE fnd_api.g_exc_unexpected_error;
1778 END IF;
1779
1780 -- Initialize message list if p_init_msg_list is set to TRUE.
1781 IF fnd_api.to_boolean(p_init_msg_list) THEN
1782 fnd_msg_pub.initialize;
1783 END IF;
1784
1785 -- Initialize API return status to success
1786 x_return_status := fnd_api.g_ret_sts_success;
1787
1788 -- API body
1789 IF (l_debug = 1) THEN
1790 mdebug(l_api_name || ' Entered ' || g_pkg_version, 1);
1791 mdebug('ver='||p_api_version||' initmsg='||p_init_msg_list||' commit='||p_commit||' caller='||p_caller||' tabfst='||p_lpn_table.first||' tablst='||p_lpn_table.last, G_INFO);
1792 END IF;
1793
1794 FOR lpn_tbl_cnt IN p_lpn_table.first .. p_lpn_table.last LOOP
1795 IF (l_debug = 1) THEN
1796 l_old := p_lpn_table(lpn_tbl_cnt);
1797
1798 l_old.lpn_id := l_old.lpn_id;
1799 l_old.license_plate_number := l_old.license_plate_number;
1800 l_old.parent_lpn_id := substr(l_old.parent_lpn_id, 1, 10);
1801 l_old.outermost_lpn_id := l_old.outermost_lpn_id;
1802 l_old.lpn_context := l_old.lpn_context;
1803
1804 l_old.organization_id := l_old.organization_id;
1805 l_old.subinventory_code := substr(l_old.subinventory_code, 1, 10);
1806 l_old.locator_id := substr(l_old.locator_id, 1, 10);
1807
1808 l_old.inventory_item_id := substr(l_old.inventory_item_id, 1, 10);
1809 l_old.revision := substr(l_old.revision, 1, 10);
1810 l_old.lot_number := substr(l_old.lot_number, 1, 10);
1811 l_old.serial_number := substr(l_old.serial_number, 1, 10);
1812 l_old.cost_group_id := substr(l_old.cost_group_id, 1, 10);
1813
1814 l_old.tare_weight_uom_code := substr(l_old.tare_weight_uom_code, 1, 10);
1815 l_old.tare_weight := substr(l_old.tare_weight, 1, 10);
1816 l_old.gross_weight_uom_code := substr(l_old.gross_weight_uom_code, 1, 10);
1817 l_old.gross_weight := substr(l_old.gross_weight, 1, 10);
1818 l_old.container_volume_uom := substr(l_old.container_volume_uom, 1, 10);
1819 l_old.container_volume := substr(l_old.container_volume, 1, 10);
1820 l_old.content_volume_uom_code := substr(l_old.content_volume_uom_code, 1, 10);
1821 l_old.content_volume := substr(l_old.content_volume, 1, 10);
1822
1823 l_old.source_type_id := substr(l_old.source_type_id, 1, 10);
1824 l_old.source_header_id := substr(l_old.source_header_id, 1, 10);
1825 l_old.source_line_id := substr(l_old.source_line_id, 1, 10);
1826 l_old.source_line_detail_id := substr(l_old.source_line_detail_id, 1, 10);
1827 l_old.source_name := l_old.source_name;
1828
1829 l_old.attribute_category := substr(l_old.attribute_category, 1, 10);
1830 l_old.attribute1 := substr(l_old.attribute1, 1, 10);
1831 l_old.attribute2 := substr(l_old.attribute2, 1, 10);
1832 l_old.attribute3 := substr(l_old.attribute3, 1, 10);
1833 l_old.attribute4 := substr(l_old.attribute4, 1, 10);
1834 l_old.attribute5 := substr(l_old.attribute5, 1, 10);
1835 l_old.attribute6 := substr(l_old.attribute6, 1, 10);
1836 l_old.attribute7 := substr(l_old.attribute7, 1, 10);
1837 l_old.attribute8 := substr(l_old.attribute8, 1, 10);
1838 l_old.attribute9 := substr(l_old.attribute9, 1, 10);
1839 l_old.attribute10 := substr(l_old.attribute10, 1, 10);
1840 l_old.attribute11 := substr(l_old.attribute11, 1, 10);
1841 l_old.attribute12 := substr(l_old.attribute12, 1, 10);
1842 l_old.attribute13 := substr(l_old.attribute13, 1, 10);
1843 l_old.attribute14 := substr(l_old.attribute14, 1, 10);
1844 l_old.attribute15 := substr(l_old.attribute15, 1, 10);
1845
1846 mdebug('-------------------------------------------------');
1847 mdebug('Values passed by caller to be updated l_lpn_tab_i='||l_lpn_tab_i||' lpn_tbl_cnt='||lpn_tbl_cnt, G_INFO);
1848 mdebug('lpnid='||l_old.lpn_id||' lpn='||l_old.license_plate_number||' ctx='||l_old.lpn_context||' plpn='||l_old.parent_lpn_id||' olpn='||l_old.outermost_lpn_id||' itm='||l_old.inventory_item_id||' rev='||l_old.revision, G_INFO);
1849 mdebug('lot='||l_old.lot_number||' sn='||l_old.serial_number||' cg='||l_old.cost_group_id||' org='||l_old.organization_id||' sub='||l_old.subinventory_code||' loc='||l_old.locator_id, G_INFO);
1850 mdebug('twt='||l_old.tare_weight||' twuom='||l_old.tare_weight_uom_code||' gwt='||l_old.gross_weight||' gwuom='||l_old.gross_weight_uom_code||
1851 ' ctrvol='||l_old.container_volume||' ctrvoluom='||l_old.container_volume_uom||' ctnvol='||l_old.content_volume||' ctvuom='||l_old.content_volume_uom_code, G_INFO);
1852 mdebug('stype='||l_old.source_type_id||' shdr='||l_old.source_header_id||' srcln='||l_old.source_line_id||' srclndt='||l_old.source_line_detail_id||' srcnm='||l_old.source_name, G_INFO);
1853 --mdebug('reuse='||l_old.lpn_reusability||' hom='||l_old.homogeneous_container||' stat='||l_old.status_id ||' seal='||l_old.sealed_status, G_INFO);
1854 mdebug('acat='||l_old.attribute_category||' a1='||l_old.attribute1||' a2='||l_old.attribute2||' a3='||l_old.attribute3||' a4='||l_old.attribute4||' a5='||l_old.attribute5||' a6='||l_old.attribute6||' a7='||l_old.attribute7, G_INFO);
1855 mdebug('a8='||l_old.attribute8||' a9='||l_old.attribute9||' a10='||l_old.attribute10||' a11='||l_old.attribute11||' a12='||l_old.attribute12||' a13='||l_old.attribute13||' a14='||l_old.attribute14||' a15='||l_old.attribute15, G_INFO);
1856 mdebug('-------------------------------------------------');
1857 END IF;
1858
1859 l_progress := 'Validate and massage data given by user lpnid='||p_lpn_table(lpn_tbl_cnt).lpn_id;
1860
1861 -- General validations for data protection
1862 IF ( p_lpn_table(lpn_tbl_cnt).outermost_lpn_id IS NOT NULL ) THEN
1863 -- Specific validations of attributes limited to certain callers
1864 IF ( NVL(p_caller, G_NULL_CHAR) <> 'WMS_PackUnpack_Container' ) THEN
1865 l_progress := 'Updating outermost_lpn_id is restricted to PackUnpack_Container API';
1866 fnd_message.set_name('WMS', 'WMS_UPDATE_LPN_ATTR_ERR');
1867 fnd_message.set_token('ATTR', 'outermost_lpn_id');
1868 fnd_msg_pub.ADD;
1869 RAISE fnd_api.g_exc_error;
1870 END IF;
1871 END IF;
1872
1873 l_progress := 'Done with general validation';
1874
1875 IF ( l_lpn_ids.exists(p_lpn_table(lpn_tbl_cnt).lpn_id) ) THEN
1876 IF (l_debug = 1) THEN
1877 mdebug('LPN attributes already exist in table lpnid='||p_lpn_table(lpn_tbl_cnt).lpn_id, G_INFO);
1878 END IF;
1879 l_lpn_tab_i := l_lpn_ids(p_lpn_table(lpn_tbl_cnt).lpn_id);
1880 l_old := l_lpns(l_lpn_tab_i);
1881 ELSE
1882 IF (l_debug = 1) THEN
1883 mdebug('Retrieve attributes of LPN lpnid='||p_lpn_table(lpn_tbl_cnt).lpn_id, G_INFO);
1884 END IF;
1885 l_lpn_tab_i := NULL;
1886
1887 BEGIN
1888 SELECT lpn_id
1889 , license_plate_number
1890 , parent_lpn_id
1891 , outermost_lpn_id
1892 , lpn_context
1893
1894 , organization_id
1895 , subinventory_code
1896 , locator_id
1897
1898 , inventory_item_id
1899 , revision
1900 , lot_number
1901 , serial_number
1902 , cost_group_id
1903
1904 , tare_weight_uom_code
1905 , tare_weight
1906 , gross_weight_uom_code
1907 , gross_weight
1908 , container_volume_uom
1909 , container_volume
1910 , content_volume_uom_code
1911 , content_volume
1912
1913 , source_type_id
1914 , source_header_id
1915 , source_line_id
1916 , source_line_detail_id
1917 , source_name
1918
1919 , attribute_category
1920 , attribute1
1921 , attribute2
1922 , attribute3
1923 , attribute4
1924 , attribute5
1925 , attribute6
1926 , attribute7
1927 , attribute8
1928 , attribute9
1929 , attribute10
1930 , attribute11
1931 , attribute12
1932 , attribute13
1933 , attribute14
1934 , attribute15
1935 INTO l_old.lpn_id
1936 , l_old.license_plate_number
1937 , l_old.parent_lpn_id
1938 , l_old.outermost_lpn_id
1939 , l_old.lpn_context
1940
1941 , l_old.organization_id
1942 , l_old.subinventory_code
1943 , l_old.locator_id
1944
1945 , l_old.inventory_item_id
1946 , l_old.revision
1947 , l_old.lot_number
1948 , l_old.serial_number
1949 , l_old.cost_group_id
1950
1951 , l_old.tare_weight_uom_code
1952 , l_old.tare_weight
1953 , l_old.gross_weight_uom_code
1954 , l_old.gross_weight
1955 , l_old.container_volume_uom
1956 , l_old.container_volume
1957 , l_old.content_volume_uom_code
1958 , l_old.content_volume
1959
1960 , l_old.source_type_id
1961 , l_old.source_header_id
1962 , l_old.source_line_id
1963 , l_old.source_line_detail_id
1964 , l_old.source_name
1965
1966 , l_old.attribute_category
1967 , l_old.attribute1
1968 , l_old.attribute2
1969 , l_old.attribute3
1970 , l_old.attribute4
1971 , l_old.attribute5
1972 , l_old.attribute6
1973 , l_old.attribute7
1974 , l_old.attribute8
1975 , l_old.attribute9
1976 , l_old.attribute10
1977 , l_old.attribute11
1978 , l_old.attribute12
1979 , l_old.attribute13
1980 , l_old.attribute14
1981 , l_old.attribute15
1982 FROM wms_license_plate_numbers
1983 WHERE lpn_id = p_lpn_table(lpn_tbl_cnt).lpn_id;
1984 EXCEPTION
1985 WHEN NO_DATA_FOUND THEN
1986 fnd_message.set_name('WMS', 'WMS_CONT_INVALID_LPN');
1987 fnd_msg_pub.ADD;
1988 RAISE fnd_api.g_exc_error;
1989 END;
1990
1991 l_progress := 'Done getting LPN attributes, Add LPN to hash table';
1992 END IF;
1993
1994 -- Store Original attributes
1995 l_new := l_old;
1996
1997 IF (l_debug = 1) THEN
1998 mdebug('Old values from LPN to be updated l_lpn_tab_i='||l_lpn_tab_i||' lpn_tbl_cnt='||lpn_tbl_cnt, G_INFO);
1999 mdebug('lpnid='||l_old.lpn_id||' lpn='||l_old.license_plate_number||' ctx='||l_old.lpn_context||' plpn='||l_old.parent_lpn_id||' olpn='||l_old.outermost_lpn_id||' itm='||l_old.inventory_item_id||' rev='||l_old.revision, G_INFO);
2000 mdebug('lot='||l_old.lot_number||' sn='||l_old.serial_number||' cg='||l_old.cost_group_id||' org='||l_old.organization_id||' sub='||l_old.subinventory_code||' loc='||l_old.locator_id, G_INFO);
2001 mdebug('twt='||l_old.tare_weight||' twuom='||l_old.tare_weight_uom_code||' gwt='||l_old.gross_weight||' gwuom='||l_old.gross_weight_uom_code||
2002 ' ctrvol='||l_old.container_volume||' ctrvoluom='||l_old.container_volume_uom||' ctnvol='||l_old.content_volume||' ctvuom='||l_old.content_volume_uom_code, G_INFO);
2003 mdebug('stype='||l_old.source_type_id||' shdr='||l_old.source_header_id||' srcln='||l_old.source_line_id||' srclndt='||l_old.source_line_detail_id||' srcnm='||l_old.source_name, G_INFO);
2004 --mdebug('reuse='||l_old.lpn_reusability||' hom='||l_old.homogeneous_container||' stat='||l_old.status_id ||' seal='||l_old.sealed_status, G_INFO);
2005 mdebug('acat='||l_old.attribute_category||' a1='||l_old.attribute1||' a2='||l_old.attribute2||' a3='||l_old.attribute3||' a4='||l_old.attribute4||' a5='||l_old.attribute5||' a6='||l_old.attribute6||' a7='||l_old.attribute7, G_INFO);
2006 mdebug('a8='||l_old.attribute8||' a9='||l_old.attribute9||' a10='||l_old.attribute10||' a11='||l_old.attribute11||' a12='||l_old.attribute12||' a13='||l_old.attribute13||' a14='||l_old.attribute14||' a15='||l_old.attribute15, G_INFO);
2007 END IF;
2008
2009 l_progress := 'Start of section to massage data';
2010
2011 -- List of attributes that pertain to the LPN itself and not to the
2012 -- entire hierarchy
2013 IF ( p_lpn_table(lpn_tbl_cnt).license_plate_number <> NVL(l_old.license_plate_number, FND_API.G_MISS_CHAR) OR
2014 p_lpn_table(lpn_tbl_cnt).parent_lpn_id <> NVL(l_old.parent_lpn_id, FND_API.G_MISS_NUM) OR
2015 Nvl(p_lpn_table(lpn_tbl_cnt).inventory_item_id,0)<> NVL(l_old.inventory_item_id, FND_API.G_MISS_NUM) OR --Bug#6504032 Added nvl condition
2016 p_lpn_table(lpn_tbl_cnt).revision <> NVL(l_old.revision, FND_API.G_MISS_CHAR) OR
2017 p_lpn_table(lpn_tbl_cnt).lot_number <> NVL(l_old.lot_number, FND_API.G_MISS_CHAR) OR
2018 p_lpn_table(lpn_tbl_cnt).serial_number <> NVL(l_old.serial_number, FND_API.G_MISS_CHAR) OR
2019 p_lpn_table(lpn_tbl_cnt).cost_group_id <> NVL(l_old.cost_group_id, FND_API.G_MISS_NUM) OR
2020 p_lpn_table(lpn_tbl_cnt).tare_weight_uom_code <> NVL(l_old.tare_weight_uom_code, FND_API.G_MISS_CHAR) OR
2021 p_lpn_table(lpn_tbl_cnt).tare_weight <> NVL(l_old.tare_weight, FND_API.G_MISS_NUM) OR
2022 p_lpn_table(lpn_tbl_cnt).gross_weight_uom_code <> NVL(l_old.gross_weight_uom_code, FND_API.G_MISS_CHAR) OR
2023 p_lpn_table(lpn_tbl_cnt).gross_weight <> NVL(l_old.gross_weight, FND_API.G_MISS_NUM) OR
2024 p_lpn_table(lpn_tbl_cnt).container_volume_uom <> NVL(l_old.container_volume_uom, FND_API.G_MISS_CHAR) OR
2025 p_lpn_table(lpn_tbl_cnt).container_volume <> NVL(l_old.container_volume, FND_API.G_MISS_NUM) OR
2026 p_lpn_table(lpn_tbl_cnt).content_volume_uom_code <> NVL(l_old.content_volume_uom_code, FND_API.G_MISS_CHAR) OR
2027 p_lpn_table(lpn_tbl_cnt).content_volume <> NVL(l_old.content_volume, FND_API.G_MISS_NUM) OR
2028 p_lpn_table(lpn_tbl_cnt).attribute_category <> NVL(l_old.attribute_category, FND_API.G_MISS_CHAR) OR
2029 p_lpn_table(lpn_tbl_cnt).attribute1 <> NVL(l_old.attribute1, FND_API.G_MISS_CHAR) OR
2030 p_lpn_table(lpn_tbl_cnt).attribute2 <> NVL(l_old.attribute2, FND_API.G_MISS_CHAR) OR
2031 p_lpn_table(lpn_tbl_cnt).attribute3 <> NVL(l_old.attribute3, FND_API.G_MISS_CHAR) OR
2032 p_lpn_table(lpn_tbl_cnt).attribute4 <> NVL(l_old.attribute4, FND_API.G_MISS_CHAR) OR
2033 p_lpn_table(lpn_tbl_cnt).attribute5 <> NVL(l_old.attribute5, FND_API.G_MISS_CHAR) OR
2034 p_lpn_table(lpn_tbl_cnt).attribute6 <> NVL(l_old.attribute6, FND_API.G_MISS_CHAR) OR
2035 p_lpn_table(lpn_tbl_cnt).attribute7 <> NVL(l_old.attribute7, FND_API.G_MISS_CHAR) OR
2036 p_lpn_table(lpn_tbl_cnt).attribute8 <> NVL(l_old.attribute8, FND_API.G_MISS_CHAR) OR
2037 p_lpn_table(lpn_tbl_cnt).attribute9 <> NVL(l_old.attribute9, FND_API.G_MISS_CHAR) OR
2038 p_lpn_table(lpn_tbl_cnt).attribute10 <> NVL(l_old.attribute10, FND_API.G_MISS_CHAR) OR
2039 p_lpn_table(lpn_tbl_cnt).attribute11 <> NVL(l_old.attribute11, FND_API.G_MISS_CHAR) OR
2040 p_lpn_table(lpn_tbl_cnt).attribute12 <> NVL(l_old.attribute12, FND_API.G_MISS_CHAR) OR
2041 p_lpn_table(lpn_tbl_cnt).attribute13 <> NVL(l_old.attribute13, FND_API.G_MISS_CHAR) OR
2042 p_lpn_table(lpn_tbl_cnt).attribute14 <> NVL(l_old.attribute14, FND_API.G_MISS_CHAR) OR
2043 p_lpn_table(lpn_tbl_cnt).attribute15 <> NVL(l_old.attribute15, FND_API.G_MISS_CHAR) )
2044 THEN
2045 l_progress := 'Initialize temp variables used for each loop';
2046 l_change_in_gross_weight := 0;
2047 l_change_in_gross_weight_uom := NULL;
2048 l_change_in_tare_weight := 0;
2049 l_change_in_tare_weight_uom := NULL;
2050 l_change_in_volume := 0;
2051 l_change_in_volume_uom := NULL;
2052
2053 -- If this LPN has not been updated, create record
2054 IF ( l_lpn_tab_i IS NULL ) THEN
2055 l_lpn_tab_i := NVL(l_lpns.last, 0) + 1;
2056 l_lpns(l_lpn_tab_i) := l_old;
2057 l_lpn_ids(p_lpn_table(lpn_tbl_cnt).lpn_id) := l_lpn_tab_i;
2058 END IF;
2059
2060 IF (l_debug = 1) THEN
2061 mdebug('Need to update based on lpn_id l_lpn_tab_i='||l_lpn_tab_i, G_INFO);
2062 END IF;
2063
2064 l_progress := 'License Plate Number';
2065 IF ( p_lpn_table(lpn_tbl_cnt).license_plate_number <> l_old.license_plate_number ) THEN
2066 l_progress := 'Validate Organization ID';
2067
2068 IF ( NOT Inv_Cache.set_org_rec( p_organization_id => NVL(p_lpn_table(lpn_tbl_cnt).organization_id, l_old.organization_id)) )THEN
2069 IF (l_debug = 1) THEN
2070 mdebug(NVL(p_lpn_table(lpn_tbl_cnt).organization_id, l_old.organization_id)||' is an invalid organization id', G_ERROR);
2071 END IF;
2072 fnd_message.set_name('WMS', 'WMS_CONT_INVALID_ORG');
2073 fnd_msg_pub.ADD;
2074 RAISE fnd_api.g_exc_error;
2075 END IF;
2076
2077 IF (l_debug = 1) THEN
2078 mdebug('Got org info wms_enabled='||inv_cache.org_rec.wms_enabled_flag, 5);
2079 END IF;
2080
2081 IF ( inv_cache.org_rec.wms_enabled_flag = 'Y' ) THEN
2082 -- License Plate Number cannot be updated in a WMS organziation
2083 fnd_message.set_name('WMS', 'WMS_UPDATE_LPN_ATTR_ERR');
2084 fnd_message.set_token('ATTR', 'License Plate Number');
2085 fnd_msg_pub.ADD;
2086 RAISE fnd_api.g_exc_error;
2087 ELSE
2088 l_new.license_plate_number := p_lpn_table(lpn_tbl_cnt).license_plate_number;
2089 END IF;
2090 END IF;
2091
2092 l_progress := 'Validate container item';
2093 IF ( (p_lpn_table(lpn_tbl_cnt).inventory_item_id IS NOT NULL)
2094 AND (Nvl(p_lpn_table(lpn_tbl_cnt).inventory_item_id,G_NULL_NUM) <> NVL(l_old.inventory_item_id, G_NULL_NUM)) ) THEN --Bug#6504032 Modified IF condition and commented following code
2095 -- Can change an LPNs existing container item for context 1 and 5 LPNs
2096 /*IF NOT ( l_old.lpn_context = lpn_context_pregenerated OR l_old.inventory_item_id IS NULL ) THEN
2097 IF (l_debug = 1) THEN
2098 mdebug(' LPN is not empty or already is assigned cannot update container item ctx='||l_old.lpn_context, G_ERROR);
2099 END IF;
2100 fnd_message.set_name('WMS', 'WMS_UPDATE_CONTAINER_ITEM_ERR');
2101 fnd_msg_pub.ADD;
2102
2103 IF ( l_old.lpn_context <> lpn_context_pregenerated ) THEN
2104 fnd_message.set_name('WMS', 'WMS_LPN_NOT_EMPTY');
2105 fnd_msg_pub.ADD;
2106 END IF;
2107 RAISE fnd_api.g_exc_error;
2108 END IF;*/
2109
2110 l_progress := 'Calling INV_CACHE.Set_Item_Rec to get item values';
2111 IF ( inv_cache.set_item_rec(
2112 p_organization_id => NVL(p_lpn_table(lpn_tbl_cnt).organization_id, l_old.organization_id)
2113 , p_item_id => p_lpn_table(lpn_tbl_cnt).inventory_item_id ) )
2114 THEN
2115 IF (l_debug = 1) THEN
2116 mdebug('Got Item info citm='||inv_cache.item_rec.container_item_flag||' snctl='||inv_cache.item_rec.serial_number_control_code, G_INFO);
2117 mdebug('wuom='||inv_cache.item_rec.weight_uom_code||' wt='||inv_cache.item_rec.unit_weight||' vuom='||inv_cache.item_rec.volume_uom_code||' vol='||inv_cache.item_rec.unit_volume, G_INFO);
2118 END IF;
2119
2120 IF ( inv_cache.item_rec.container_item_flag = 'N' ) THEN
2121 IF (l_debug = 1) THEN
2122 mdebug(p_lpn_table(lpn_tbl_cnt).inventory_item_id || ' is not a container', 1);
2123 END IF;
2124 fnd_message.set_name('WMS', 'WMS_ITEM_NOT_CONTAINER');
2125 fnd_message.set_token('ITEM', inv_cache.item_rec.segment1);
2126 fnd_msg_pub.ADD;
2127 RAISE fnd_api.g_exc_error;
2128 END IF;
2129 ELSE
2130 l_progress := 'Error calling INV_CACHE.Set_Item_Rec for orgid='||NVL(p_lpn_table(lpn_tbl_cnt).organization_id, l_old.organization_id)||' item id='||p_lpn_table(lpn_tbl_cnt).inventory_item_id;
2131 fnd_message.set_name('WMS', 'WMS_CONT_INVALID_ITEM');
2132 fnd_msg_pub.ADD;
2133 RAISE fnd_api.g_exc_error;
2134 END IF;
2135
2136 -- Container item is valid, change container item
2137 l_new.inventory_item_id := p_lpn_table(lpn_tbl_cnt).inventory_item_id;
2138 END IF;
2139
2140 -- bug5404902 changed l_change_in_gross_weight(_uom) to l_change_in_tare_weight(_uom)
2141 l_progress := 'Tare weight';
2142 IF ( p_lpn_table(lpn_tbl_cnt).tare_weight = FND_API.G_MISS_NUM OR p_lpn_table(lpn_tbl_cnt).tare_weight_uom_code = FND_API.G_MISS_CHAR ) THEN
2143 l_new.tare_weight := NULL;
2144 l_new.tare_weight_uom_code := NULL;
2145
2146 IF ( NVL(l_old.tare_weight, 0) <> 0 AND l_old.tare_weight_uom_code IS NOT NULL ) THEN
2147 l_change_in_tare_weight := 0 - l_old.tare_weight;
2148 l_change_in_tare_weight_uom := l_old.tare_weight_uom_code;
2149 END IF;
2150 ELSIF ( p_lpn_table(lpn_tbl_cnt).tare_weight IS NOT NULL AND p_lpn_table(lpn_tbl_cnt).tare_weight_uom_code IS NOT NULL ) THEN
2151 -- Check that value is not negative. If it is, floor at zero
2152 IF ( p_lpn_table(lpn_tbl_cnt).tare_weight < 0 ) THEN
2153 l_new.tare_weight := 0;
2154 ELSE
2155 l_new.tare_weight := p_lpn_table(lpn_tbl_cnt).tare_weight;
2156 END IF;
2157
2158 l_new.tare_weight_uom_code := p_lpn_table(lpn_tbl_cnt).tare_weight_uom_code;
2159
2160 IF ( NVL(l_old.tare_weight,0) <> 0 AND l_old.tare_weight_uom_code IS NOT NULL ) THEN
2161 l_change_in_tare_weight_uom := l_old.tare_weight_uom_code;
2162 l_change_in_tare_weight := Convert_UOM(l_new.inventory_item_id, l_new.tare_weight, l_new.tare_weight_uom_code, l_change_in_tare_weight_uom, G_NO_CONV_RETURN_NULL);
2163 l_change_in_tare_weight := l_change_in_tare_weight - l_old.tare_weight;
2164 ELSE
2165 l_change_in_tare_weight := l_new.tare_weight;
2166 l_change_in_tare_weight_uom := l_new.tare_weight_uom_code;
2167 END IF;
2168 ELSIF ( p_lpn_table(lpn_tbl_cnt).inventory_item_id IS NOT NULL
2169 AND (Nvl(p_lpn_table(lpn_tbl_cnt).inventory_item_id,G_NULL_NUM) <> Nvl(l_old.inventory_item_id,G_NULL_NUM)) ) THEN --Bug#6504032 Modified this ELSIF to allow modifying and attaching container
2170 IF ( l_old.inventory_item_id IS NOT NULL ) THEN
2171 IF (inv_cache.set_item_rec(
2172 p_organization_id => NVL(p_lpn_table(lpn_tbl_cnt).organization_id, l_old.organization_id)
2173 , p_item_id => l_old.inventory_item_id ))
2174 THEN
2175 IF (l_debug = 1) THEN
2176 mdebug('Got Old Item info citm='||inv_cache.item_rec.container_item_flag||' snctl='||inv_cache.item_rec.serial_number_control_code, G_INFO);
2177 mdebug('wuom='||inv_cache.item_rec.weight_uom_code||' wt='||inv_cache.item_rec.unit_weight||' vuom='||inv_cache.item_rec.volume_uom_code||' vol='||inv_cache.item_rec.unit_volume, G_INFO);
2178 END IF;
2179 ELSE
2180 l_progress := 'Error calling INV_CACHE.Set_Item_Rec for orgid='||NVL(p_lpn_table(lpn_tbl_cnt).organization_id, l_old.organization_id)||' item id='||l_old.inventory_item_id;
2181 fnd_message.set_name('WMS', 'WMS_CONT_INVALID_ITEM');
2182 fnd_msg_pub.ADD;
2183 RAISE fnd_api.g_exc_error;
2184 END IF;
2185 IF ( inv_cache.item_rec.unit_weight IS NOT NULL AND
2186 inv_cache.item_rec.weight_uom_code IS NOT NULL ) THEN
2187
2188 IF ( NVL(l_old.tare_weight, 0) = 0 OR l_old.tare_weight_uom_code IS NULL ) THEN
2189 l_new.tare_weight := 0;
2190 l_new.tare_weight_uom_code := NULL;
2191 ELSIF ( l_old.tare_weight_uom_code = inv_cache.item_rec.weight_uom_code ) THEN
2192 l_new.tare_weight := l_old.tare_weight - inv_cache.item_rec.unit_weight;
2193 l_old.tare_weight := l_old.tare_weight - inv_cache.item_rec.unit_weight;
2194 l_new.tare_weight_uom_code := l_old.tare_weight_uom_code;
2195 ELSE -- Both are not null but with different UOMs need to convert
2196 l_new.tare_weight := Convert_UOM(inv_cache.item_rec.inventory_item_id, inv_cache.item_rec.unit_weight, inv_cache.item_rec.weight_uom_code, l_old.tare_weight_uom_code, G_NO_CONV_RETURN_NULL);
2197
2198 l_new.tare_weight := l_old.tare_weight - l_new.tare_weight;
2199 l_old.tare_weight := l_old.tare_weight - inv_cache.item_rec.unit_weight;
2200 l_new.tare_weight_uom_code := l_old.tare_weight_uom_code;
2201 END IF;
2202
2203 l_change_in_tare_weight := 0-inv_cache.item_rec.unit_weight;
2204 l_change_in_tare_weight_uom := l_old.tare_weight_uom_code;
2205 END IF;
2206 END IF;
2207 IF ( inv_cache.set_item_rec(
2208 p_organization_id => NVL(p_lpn_table(lpn_tbl_cnt).organization_id, l_old.organization_id)
2209 , p_item_id => p_lpn_table(lpn_tbl_cnt).inventory_item_id ) )
2210 THEN
2211 IF (l_debug = 1) THEN
2212 mdebug('Got Item info citm='||inv_cache.item_rec.container_item_flag||' snctl='||inv_cache.item_rec.serial_number_control_code, G_INFO);
2213 mdebug('wuom='||inv_cache.item_rec.weight_uom_code||' wt='||inv_cache.item_rec.unit_weight||' vuom='||inv_cache.item_rec.volume_uom_code||' vol='||inv_cache.item_rec.unit_volume, G_INFO);
2214 END IF;
2215 ELSE
2216 l_progress := 'Error calling INV_CACHE.Set_Item_Rec for orgid='||NVL(p_lpn_table(lpn_tbl_cnt).organization_id, l_old.organization_id)||' item id='||p_lpn_table(lpn_tbl_cnt).inventory_item_id;
2217 fnd_message.set_name('WMS', 'WMS_CONT_INVALID_ITEM');
2218 fnd_msg_pub.ADD;
2219 RAISE fnd_api.g_exc_error;
2220 END IF;
2221 IF ( inv_cache.item_rec.unit_weight IS NOT NULL AND
2222 inv_cache.item_rec.weight_uom_code IS NOT NULL ) THEN
2223
2224 IF ( NVL(l_old.tare_weight, 0) = 0 OR l_old.tare_weight_uom_code IS NULL ) THEN
2225 l_new.tare_weight := inv_cache.item_rec.unit_weight;
2226 l_new.tare_weight_uom_code := inv_cache.item_rec.weight_uom_code;
2227 ELSIF ( l_old.tare_weight_uom_code = inv_cache.item_rec.weight_uom_code ) THEN
2228 l_new.tare_weight := l_new.tare_weight + inv_cache.item_rec.unit_weight;
2229 l_new.tare_weight_uom_code := l_old.tare_weight_uom_code;
2230 ELSE -- Both are not null but with different UOMs need to convert
2231 l_new.tare_weight := Convert_UOM(inv_cache.item_rec.inventory_item_id, inv_cache.item_rec.unit_weight, inv_cache.item_rec.weight_uom_code, l_old.tare_weight_uom_code, G_NO_CONV_RETURN_NULL);
2232
2233 l_new.tare_weight := l_new.tare_weight + l_old.tare_weight;
2234 l_new.tare_weight_uom_code := l_old.tare_weight_uom_code;
2235 END IF;
2236
2237 -- bug5404902 now that we are just adding the container item unit weight to the
2238 -- existing tare, change in tare is just the container item unit weight
2239 l_change_in_tare_weight := l_change_in_tare_weight + inv_cache.item_rec.unit_weight;
2240 l_change_in_tare_weight_uom := inv_cache.item_rec.weight_uom_code;
2241 END IF;
2242 ELSIF ( p_lpn_table(lpn_tbl_cnt).inventory_item_id IS NULL ----Bug#6504032 Added this ELSIF to take care of container removal
2243 AND l_old.inventory_item_id IS NOT NULL
2244 AND l_old.lpn_context IN (1,5)
2245 AND p_caller = 'UpdateLPNPage' ) THEN
2246 IF (inv_cache.set_item_rec(
2247 p_organization_id => NVL(p_lpn_table(lpn_tbl_cnt).organization_id, l_old.organization_id)
2248 , p_item_id => l_old.inventory_item_id ))
2249 THEN
2250 IF (l_debug = 1) THEN
2251 mdebug('Got Old Item info citm='||inv_cache.item_rec.container_item_flag||' snctl='||inv_cache.item_rec.serial_number_control_code, G_INFO);
2252 mdebug('wuom='||inv_cache.item_rec.weight_uom_code||' wt='||inv_cache.item_rec.unit_weight||' vuom='||inv_cache.item_rec.volume_uom_code||' vol='||inv_cache.item_rec.unit_volume, G_INFO);
2253 END IF;
2254 ELSE
2255 l_progress := 'Error calling INV_CACHE.Set_Item_Rec for orgid='||NVL(p_lpn_table(lpn_tbl_cnt).organization_id, l_old.organization_id)||' item id='||p_lpn_table(lpn_tbl_cnt).inventory_item_id;
2256 fnd_message.set_name('WMS', 'WMS_CONT_INVALID_ITEM');
2257 fnd_msg_pub.ADD;
2258 RAISE fnd_api.g_exc_error;
2259 END IF;
2260
2261 IF (inv_cache.item_rec.unit_weight IS NOT NULL AND
2262 inv_cache.item_rec.weight_uom_code IS NOT NULL ) THEN
2263
2264 IF ( NVL(l_old.tare_weight, 0) = 0 OR l_old.tare_weight_uom_code IS NULL ) THEN
2265 l_new.tare_weight := 0;
2266 l_new.tare_weight_uom_code := NULL;
2267 ELSIF ( l_old.tare_weight_uom_code = inv_cache.item_rec.weight_uom_code ) THEN
2268 l_new.tare_weight := l_old.tare_weight - inv_cache.item_rec.unit_weight;
2269 l_new.tare_weight_uom_code := l_old.tare_weight_uom_code;
2270 ELSE -- Both are not null but with different UOMs need to convert
2271 l_new.tare_weight := Convert_UOM(inv_cache.item_rec.inventory_item_id, inv_cache.item_rec.unit_weight, inv_cache.item_rec.weight_uom_code, l_old.tare_weight_uom_code, G_NO_CONV_RETURN_NULL);
2272
2273 l_new.tare_weight := l_old.tare_weight - l_new.tare_weight;
2274 l_new.tare_weight_uom_code := l_old.tare_weight_uom_code;
2275 END IF;
2276
2277 l_change_in_tare_weight := 0-inv_cache.item_rec.unit_weight;
2278 l_change_in_tare_weight_uom := l_old.tare_weight_uom_code;
2279 END IF;
2280 l_new.inventory_item_id := NULL;
2281 l_new.container_volume := NULL;
2282 l_new.container_volume_uom := NULL;
2283 END IF;
2284
2285 l_progress := 'Gross Weight';
2286 IF ( p_lpn_table(lpn_tbl_cnt).gross_weight = FND_API.G_MISS_NUM OR p_lpn_table(lpn_tbl_cnt).gross_weight_uom_code = FND_API.G_MISS_CHAR ) THEN
2287 l_new.gross_weight := NULL;
2288 l_new.gross_weight_uom_code := NULL;
2289 ELSIF ( p_lpn_table(lpn_tbl_cnt).gross_weight IS NOT NULL AND p_lpn_table(lpn_tbl_cnt).gross_weight_uom_code IS NOT NULL ) THEN
2290 -- Check that value is not negative. If it is, floor at zero
2291 IF ( p_lpn_table(lpn_tbl_cnt).gross_weight < 0 ) THEN
2292 l_new.gross_weight := 0;
2293 ELSE
2294 l_new.gross_weight := p_lpn_table(lpn_tbl_cnt).gross_weight;
2295 END IF;
2296 l_new.gross_weight_uom_code := p_lpn_table(lpn_tbl_cnt).gross_weight_uom_code;
2297 END IF;
2298
2299 --Bug#6504032 Separated calculation of change in Gr Wt due to container association
2300 IF ( p_caller = 'UpdateLPNPage' ) THEN
2301 IF ( NVL(l_new.gross_weight, 0) = 0 OR l_new.gross_weight_uom_code IS NULL ) THEN
2302 l_change_in_weight := 0 - l_old.gross_weight;
2303 l_change_in_weight_uom := l_old.gross_weight_uom_code;
2304 ELSIF ( NVL(l_old.gross_weight, 0) = 0 OR l_old.gross_weight_uom_code IS NULL ) THEN
2305 l_change_in_weight := l_new.gross_weight;
2306 l_change_in_weight_uom := l_new.gross_weight_uom_code;
2307 ELSIF ( l_old.gross_weight_uom_code = l_new.gross_weight_uom_code ) THEN
2308 l_change_in_weight := l_new.gross_weight - l_old.gross_weight;
2309 l_change_in_weight_uom := l_old.gross_weight_uom_code;
2310 ELSE -- Both are not null but with different UOMs need to convert
2311 l_change_in_weight_uom := l_old.gross_weight_uom_code;
2312
2313 l_change_in_weight := Convert_UOM(l_new.inventory_item_id, l_new.gross_weight, l_new.gross_weight_uom_code, l_change_in_weight_uom, G_NO_CONV_RETURN_NULL);
2314 l_change_in_weight := l_change_in_weight - l_old.gross_weight;
2315 END IF;
2316
2317 /*Bug#6845814 If there is a change in gross weight, it will be a change in tare weight. */
2318 IF ( l_change_in_weight <> 0
2319 AND p_caller='UpdateLPNPage'
2320 --AND NVL(p_lpn_table(lpn_tbl_cnt).inventory_item_id ,G_NULL_NUM) = G_NULL_NUM
2321 ) THEN
2322 IF (l_new.tare_weight_uom_code IS NOT NULL ) THEN
2323 IF ( l_change_in_weight_uom <> l_new.tare_weight_uom_code ) THEN
2324 l_new.tare_weight := NVL( l_new.tare_weight,0) + inv_convert.inv_um_convert(
2325 l_new.inventory_item_id,
2326 6,
2327 l_change_in_weight,
2328 l_change_in_weight_uom ,
2329 l_new.tare_weight_uom_code
2330 ,NULL,NULL);
2331 ELSE
2332 l_new.tare_weight := NVL( l_new.tare_weight,0) + l_change_in_weight ;
2333 END IF;
2334 ELSE --l_new.tare_weight_uom_code IS NULL
2335 l_new.tare_weight := l_change_in_weight ;
2336 l_new.tare_weight_uom_code := NVL( l_change_in_weight_uom , l_new.gross_weight_uom_code );
2337 END IF;
2338
2339 IF (l_new.tare_weight <= 0 ) THEN
2340 l_new.tare_weight := 0 ;
2341 l_new.tare_weight_uom_code := NULL ;
2342 END IF;
2343 END IF;
2344 END IF;
2345
2346 IF ( NVL(l_change_in_tare_weight, 0) <> 0 AND l_change_in_tare_weight_uom IS NOT NULL ) THEN
2347 -- bug5404902 changed l_change_in_gross_weight(_uom) to l_change_in_tare_weight(_uom)
2348 -- If tare weight has changed need to add the difference to gross
2349 IF ( NVL(l_old.gross_weight, 0) = 0 OR l_old.gross_weight_uom_code IS NULL ) THEN
2350 l_new.gross_weight := l_new.tare_weight;
2351 l_new.gross_weight_uom_code := l_new.tare_weight_uom_code;
2352 ELSIF ( l_old.gross_weight_uom_code = l_change_in_gross_weight_uom ) THEN
2353 l_new.gross_weight := l_new.gross_weight + l_change_in_tare_weight;
2354 l_new.gross_weight_uom_code := l_old.gross_weight_uom_code;
2355 ELSE -- Both are not null but with different UOMs need to convert
2356 -- bug5404902 intentionally used l_change_in_gross_weight to store conversion value
2357 -- so that l_change_in_tare_weight can maintain it's original UOM
2358 -- Marker
2359 l_change_in_gross_weight := Convert_UOM(l_new.inventory_item_id, l_change_in_tare_weight, l_change_in_tare_weight_uom, l_new.gross_weight_uom_code, G_NO_CONV_RETURN_ZERO);
2360 l_change_in_gross_weight_uom := l_new.gross_weight_uom_code;
2361
2362 l_new.gross_weight := l_new.gross_weight + l_change_in_tare_weight;
2363 END IF;
2364 END IF;
2365
2366 l_progress := 'Container Volume';
2367 IF ( p_lpn_table(lpn_tbl_cnt).container_volume = FND_API.G_MISS_NUM OR p_lpn_table(lpn_tbl_cnt).container_volume_uom = FND_API.G_MISS_CHAR ) THEN
2368 l_new.container_volume := NULL;
2369 l_new.container_volume_uom := NULL;
2370 ELSIF ( p_lpn_table(lpn_tbl_cnt).container_volume IS NOT NULL AND p_lpn_table(lpn_tbl_cnt).container_volume_uom IS NOT NULL ) THEN
2371 -- Check that value is not negative. If it is, floor at zero
2372 IF ( p_lpn_table(lpn_tbl_cnt).container_volume < 0 ) THEN
2373 l_new.container_volume := 0;
2374 ELSE
2375 l_new.container_volume := p_lpn_table(lpn_tbl_cnt).container_volume;
2376 END IF;
2377
2378 l_new.container_volume_uom := p_lpn_table(lpn_tbl_cnt).container_volume_uom;
2379 ELSIF ( p_lpn_table(lpn_tbl_cnt).inventory_item_id IS NOT NULL ) THEN
2380 -- use new container item tare weight and uom if values are not defined yet
2381 --IF ( l_old.container_volume IS NULL OR l_old.container_volume_uom IS NULL ) THEN --Bug#6504032 Commented this IF as container can be updated now
2382 l_new.container_volume := inv_cache.item_rec.unit_volume;
2383 l_new.container_volume_uom := inv_cache.item_rec.volume_uom_code;
2384 --END IF;
2385 END IF;
2386
2387 l_progress := 'Content Volume';
2388 IF ( p_lpn_table(lpn_tbl_cnt).content_volume = FND_API.G_MISS_NUM OR p_lpn_table(lpn_tbl_cnt).content_volume_uom_code = FND_API.G_MISS_CHAR ) THEN
2389 l_new.content_volume := NULL;
2390 l_new.content_volume_uom_code := NULL;
2391 ELSIF ( p_lpn_table(lpn_tbl_cnt).content_volume IS NOT NULL AND p_lpn_table(lpn_tbl_cnt).content_volume_uom_code IS NOT NULL ) THEN
2392 -- Check that value is not negative. If it is, floor at zero
2393 IF ( p_lpn_table(lpn_tbl_cnt).content_volume < 0 ) THEN
2394 l_new.content_volume := 0;
2395 ELSE
2396 l_new.content_volume := p_lpn_table(lpn_tbl_cnt).content_volume;
2397 END IF;
2398
2399 l_new.content_volume_uom_code := p_lpn_table(lpn_tbl_cnt).content_volume_uom_code;
2400 END IF;
2401
2402 /* Not sure if we need to support this
2403 l_progress := 'Status ID?';
2404 IF ( p_lpn_table(lpn_tbl_cnt).status_id = FND_API.G_MISS_NUM ) THEN
2405 l_new.status_id := NULL;
2406 ELSIF ( p_lpn_table(lpn_tbl_cnt).status_id IS NOT NULL ) THEN
2407 l_new.status_id := p_lpn_table(lpn_tbl_cnt).status_id;
2408 END IF;*/
2409
2410 l_progress := 'Update attribute_category';
2411 IF ( p_lpn_table(lpn_tbl_cnt).attribute_category = FND_API.G_MISS_CHAR ) THEN
2412 l_new.attribute_category := NULL;
2413 ELSIF ( p_lpn_table(lpn_tbl_cnt).attribute_category IS NOT NULL ) THEN
2414 l_new.attribute_category := p_lpn_table(lpn_tbl_cnt).attribute_category;
2415 END IF;
2416
2417 l_progress := 'Update attribute1';
2418 IF ( p_lpn_table(lpn_tbl_cnt).attribute1 = FND_API.G_MISS_CHAR ) THEN
2419 l_new.attribute1 := NULL;
2420 ELSIF ( p_lpn_table(lpn_tbl_cnt).attribute1 IS NOT NULL ) THEN
2421 l_new.attribute1 := p_lpn_table(lpn_tbl_cnt).attribute1;
2422 END IF;
2423
2424 l_progress := 'Update attribute2';
2425 IF ( p_lpn_table(lpn_tbl_cnt).attribute2 = FND_API.G_MISS_CHAR ) THEN
2426 l_new.attribute2 := NULL;
2427 ELSIF ( p_lpn_table(lpn_tbl_cnt).attribute2 IS NOT NULL ) THEN
2428 l_new.attribute2 := p_lpn_table(lpn_tbl_cnt).attribute2;
2429 END IF;
2430
2431 l_progress := 'Update attribute3';
2432 IF ( p_lpn_table(lpn_tbl_cnt).attribute3 = FND_API.G_MISS_CHAR ) THEN
2433 l_new.attribute3 := NULL;
2434 ELSIF ( p_lpn_table(lpn_tbl_cnt).attribute3 IS NOT NULL ) THEN
2435 l_new.attribute3 := p_lpn_table(lpn_tbl_cnt).attribute3;
2436 END IF;
2437
2438 l_progress := 'Update attribute4';
2439 IF ( p_lpn_table(lpn_tbl_cnt).attribute4 = FND_API.G_MISS_CHAR ) THEN
2440 l_new.attribute4 := NULL;
2441 ELSIF ( p_lpn_table(lpn_tbl_cnt).attribute4 IS NOT NULL ) THEN
2442 l_new.attribute4 := p_lpn_table(lpn_tbl_cnt).attribute4;
2443 END IF;
2444
2445 l_progress := 'Update attribute5';
2446 IF ( p_lpn_table(lpn_tbl_cnt).attribute5 = FND_API.G_MISS_CHAR ) THEN
2447 l_new.attribute5 := NULL;
2448 ELSIF ( p_lpn_table(lpn_tbl_cnt).attribute5 IS NOT NULL ) THEN
2449 l_new.attribute5 := p_lpn_table(lpn_tbl_cnt).attribute5;
2450 END IF;
2451
2452 l_progress := 'Update attribute6';
2453 IF ( p_lpn_table(lpn_tbl_cnt).attribute6 = FND_API.G_MISS_CHAR ) THEN
2454 l_new.attribute6 := NULL;
2455 ELSIF ( p_lpn_table(lpn_tbl_cnt).attribute6 IS NOT NULL ) THEN
2456 l_new.attribute6 := p_lpn_table(lpn_tbl_cnt).attribute6;
2457 END IF;
2458
2459 l_progress := 'Update attribute7';
2460 IF ( p_lpn_table(lpn_tbl_cnt).attribute7 = FND_API.G_MISS_CHAR ) THEN
2461 l_new.attribute7 := NULL;
2462 ELSIF ( p_lpn_table(lpn_tbl_cnt).attribute7 IS NOT NULL ) THEN
2463 l_new.attribute7 := p_lpn_table(lpn_tbl_cnt).attribute7;
2464 END IF;
2465
2466 l_progress := 'Update attribute8';
2467 IF ( p_lpn_table(lpn_tbl_cnt).attribute8 = FND_API.G_MISS_CHAR ) THEN
2468 l_new.attribute8 := NULL;
2469 ELSIF ( p_lpn_table(lpn_tbl_cnt).attribute8 IS NOT NULL ) THEN
2470 l_new.attribute8 := p_lpn_table(lpn_tbl_cnt).attribute8;
2471 END IF;
2472
2473 l_progress := 'Update attribute9';
2474 IF ( p_lpn_table(lpn_tbl_cnt).attribute9 = FND_API.G_MISS_CHAR ) THEN
2475 l_new.attribute9 := NULL;
2476 ELSIF ( p_lpn_table(lpn_tbl_cnt).attribute9 IS NOT NULL ) THEN
2477 l_new.attribute9 := p_lpn_table(lpn_tbl_cnt).attribute9;
2478 END IF;
2479
2480 l_progress := 'Update attribute10';
2481 IF ( p_lpn_table(lpn_tbl_cnt).attribute10 = FND_API.G_MISS_CHAR ) THEN
2482 l_new.attribute10 := NULL;
2483 ELSIF ( p_lpn_table(lpn_tbl_cnt).attribute10 IS NOT NULL ) THEN
2484 l_new.attribute10 := p_lpn_table(lpn_tbl_cnt).attribute10;
2485 END IF;
2486
2487 l_progress := 'Update attribute11';
2488 IF ( p_lpn_table(lpn_tbl_cnt).attribute11 = FND_API.G_MISS_CHAR ) THEN
2489 l_new.attribute11 := NULL;
2490 ELSIF ( p_lpn_table(lpn_tbl_cnt).attribute11 IS NOT NULL ) THEN
2491 l_new.attribute11 := p_lpn_table(lpn_tbl_cnt).attribute11;
2492 END IF;
2493
2494 l_progress := 'Update attribute12';
2495 IF ( p_lpn_table(lpn_tbl_cnt).attribute12 = FND_API.G_MISS_CHAR ) THEN
2496 l_new.attribute12 := NULL;
2497 ELSIF ( p_lpn_table(lpn_tbl_cnt).attribute12 IS NOT NULL ) THEN
2498 l_new.attribute12 := p_lpn_table(lpn_tbl_cnt).attribute12;
2499 END IF;
2500
2501 l_progress := 'Update attribute13';
2502 IF ( p_lpn_table(lpn_tbl_cnt).attribute13 = FND_API.G_MISS_CHAR ) THEN
2503 l_new.attribute13 := NULL;
2504 ELSIF ( p_lpn_table(lpn_tbl_cnt).attribute13 IS NOT NULL ) THEN
2505 l_new.attribute13 := p_lpn_table(lpn_tbl_cnt).attribute13;
2506 END IF;
2507
2508 l_progress := 'Update attribute14';
2509 IF ( p_lpn_table(lpn_tbl_cnt).attribute14 = FND_API.G_MISS_CHAR ) THEN
2510 l_new.attribute14 := NULL;
2511 ELSIF ( p_lpn_table(lpn_tbl_cnt).attribute14 IS NOT NULL ) THEN
2512 l_new.attribute14 := p_lpn_table(lpn_tbl_cnt).attribute14;
2513 END IF;
2514
2515 l_progress := 'Update attribute15';
2516 IF ( p_lpn_table(lpn_tbl_cnt).attribute15 = FND_API.G_MISS_CHAR ) THEN
2517 l_new.attribute15 := NULL;
2518 ELSIF ( p_lpn_table(lpn_tbl_cnt).attribute15 IS NOT NULL ) THEN
2519 l_new.attribute15 := p_lpn_table(lpn_tbl_cnt).attribute15;
2520 END IF;
2521
2522 l_progress := 'Parent LPN';
2523 IF ( p_lpn_table(lpn_tbl_cnt).parent_lpn_id IS NOT NULL ) THEN
2524 IF ( NVL(p_caller, G_NULL_CHAR) <> 'WMS_PackUnpack_Container' ) THEN
2525 l_progress := 'Updating parent_lpn_id is retructed to PackUnpack_Container API';
2526 fnd_message.set_name('WMS', 'WMS_UPDATE_LPN_ATTR_ERR');
2527 fnd_message.set_token('ATTR', 'parent_lpn_id');
2528 fnd_msg_pub.ADD;
2529 RAISE fnd_api.g_exc_error;
2530 ELSIF ( p_lpn_table(lpn_tbl_cnt).parent_lpn_id = FND_API.G_MISS_NUM ) THEN
2531 -- UNPACKING LPN
2532 l_new.parent_lpn_id := NULL;
2533 l_new.outermost_lpn_id := l_new.lpn_id;
2534 ELSIF ( l_old.parent_lpn_id IS NOT NULL ) THEN
2535 -- Nesting an lpn that is already nested not allowed in a single
2536 -- operaiton. Must unpack LPN before packing into new LPN
2537 fnd_message.set_name('WMS', 'WMS_LPN_ALREADY_NESTED_ERR');
2538 fnd_msg_pub.ADD;
2539 RAISE fnd_api.g_exc_error;
2540 ELSE
2541 -- PACKING LPN
2542 l_new.parent_lpn_id := p_lpn_table(lpn_tbl_cnt).parent_lpn_id;
2543
2544 -- Need to populate new outermost lpn id
2545 IF ( p_lpn_table(lpn_tbl_cnt).outermost_lpn_id IS NOT NULL ) THEN
2546 l_new.outermost_lpn_id := p_lpn_table(lpn_tbl_cnt).outermost_lpn_id;
2547 ELSIF ( l_lpn_ids.exists(l_new.parent_lpn_id) ) THEN
2548 l_new.outermost_lpn_id := l_lpns(l_lpn_ids(l_new.parent_lpn_id)).outermost_lpn_id;
2549 ELSE -- not in table just get from db
2550 l_progress := 'Getting outermost_lpn_id for plpnid='||l_new.parent_lpn_id;
2551 SELECT outermost_lpn_id
2552 INTO l_new.outermost_lpn_id
2553 FROM wms_license_plate_numbers
2554 WHERE lpn_id = l_new.parent_lpn_id;
2555 END IF;
2556 END IF;
2557 END IF;
2558
2559 l_progress := 'Done with section that deals with LPN itself';
2560
2561 /************************************************************/
2562 /* Calculate changes to weight and volume */
2563 /* */
2564 /************************************************************/
2565 l_progress := 'Calculate total change in gross weight';
2566
2567 IF ( NVL(l_new.gross_weight, 0) = 0 OR l_new.gross_weight_uom_code IS NULL ) THEN
2568 l_change_in_gross_weight := 0 - l_old.gross_weight;
2569 l_change_in_gross_weight_uom := l_old.gross_weight_uom_code;
2570 ELSIF ( NVL(l_old.gross_weight, 0) = 0 OR l_old.gross_weight_uom_code IS NULL ) THEN
2571 l_change_in_gross_weight := l_new.gross_weight;
2572 l_change_in_gross_weight_uom := l_new.gross_weight_uom_code;
2573 ELSIF ( l_old.gross_weight_uom_code = l_new.gross_weight_uom_code ) THEN
2574 l_change_in_gross_weight := l_new.gross_weight - l_old.gross_weight;
2575 l_change_in_gross_weight_uom := l_old.gross_weight_uom_code;
2576 ELSE -- Both are not null but with different UOMs need to convert
2577 l_change_in_gross_weight_uom := l_old.gross_weight_uom_code;
2578
2579 l_change_in_gross_weight := Convert_UOM(l_new.inventory_item_id, l_new.gross_weight, l_new.gross_weight_uom_code, l_change_in_gross_weight_uom, G_NO_CONV_RETURN_NULL);
2580 l_change_in_gross_weight := l_change_in_gross_weight - l_old.gross_weight;
2581 END IF;
2582
2583 IF (l_debug = 1) THEN
2584 mdebug('change wt='||l_change_in_gross_weight||' change wuom='||l_change_in_gross_weight_uom, G_INFO);
2585 mdebug('New item='||p_lpn_table(lpn_tbl_cnt).inventory_item_id ||',old item='||l_old.inventory_item_id,G_INFO);
2586 END IF;
2587
2588 l_progress := 'Call helper procedure to calculate change in volume';
2589 Calc_Vol_Change (
2590 p_debug => l_debug
2591 , p_old_lpn => l_old
2592 , p_new_lpn => l_new
2593 , p_volume_change => l_change_in_volume
2594 , p_volume_uom_change => l_change_in_volume_uom );
2595
2596 -- bug 4144326 When there is a change in wt/vol need to update locator capacity.
2597 -- Only for explicit update transactions. Not for TM invoked updates.
2598 /*IF ( NVL(p_caller, G_NULL_CHAR) <> 'WMS_PackUnpack_Container' AND
2599 NVL(p_caller, G_NULL_CHAR) <> 'INV_TRNSACTION' )
2600 THEN*/
2601 IF ( NVL(p_caller, G_NULL_CHAR) not in ('WMS_PackUnpack_Container', 'INV_TRNSACTION') ) THEN
2602 l_progress := 'Calling Update_Locator_Capacity';
2603
2604 Update_Locator_Capacity (
2605 x_return_status => x_return_status
2606 , x_msg_count => x_msg_count
2607 , x_msg_data => x_msg_data
2608 , p_organization_id => l_new.organization_id
2609 , p_subinventory => l_new.subinventory_code
2610 , p_locator_id => l_new.locator_id
2611 , p_weight_change => l_change_in_gross_weight
2612 , p_weight_uom_change => l_change_in_gross_weight_uom
2613 , p_volume_change => l_change_in_volume
2614 , p_volume_uom_change => l_change_in_volume_uom
2615 );
2616
2617 IF ( x_return_status <> fnd_api.g_ret_sts_success) THEN
2618 IF (l_debug = 1) THEN
2619 mdebug('Call to WMS_CONTAINER_PVT.Update_Locator_capacity failed !!!');
2620 END IF;
2621 END IF;
2622 END IF;
2623 /*ELSE
2624 l_progress := 'No change is weight/vol of lpn, set vars to null';
2625
2626 l_change_in_gross_weight := null;
2627 l_change_in_gross_weight_uom := null;
2628 l_change_in_volume := null;
2629 l_change_in_volume_uom := null;
2630 END IF;*/
2631
2632 /************************************************************/
2633 /* Changes that only pertain to LPNs nested inside this LPN */
2634 /* Update child LPNs */
2635 /************************************************************/
2636 IF ( l_old.outermost_lpn_id <> l_new.outermost_lpn_id ) THEN
2637 IF ( l_old.lpn_id = l_old.outermost_lpn_id ) THEN
2638 -- This LPN was the outermost can update based on outermost LPN column
2639
2640 IF ( l_outer_lpn_ids.exists(l_old.outermost_lpn_id) ) THEN
2641 l_tmp_i := l_outer_lpn_ids(l_old.outermost_lpn_id);
2642 IF (l_debug = 1) THEN
2643 mdebug('LPN old outer already exist in table l_tmp_i='||l_tmp_i, G_INFO);
2644 END IF;
2645 ELSE
2646 l_tmp_i := NVL(l_outer_lpns.last, 0) + 1;
2647 l_outer_lpn_ids(l_old.outermost_lpn_id) := l_tmp_i;
2648 l_outer_lpns(l_tmp_i).reference_id := l_old.outermost_lpn_id;
2649
2650 IF (l_debug = 1) THEN
2651 mdebug('Create old outer entry in outer table l_tmp_i='||l_tmp_i, G_INFO);
2652 END IF;
2653 END IF;
2654
2655 l_outer_lpns(l_tmp_i).outermost_lpn_id := l_new.outermost_lpn_id;
2656 l_outer_lpns(l_tmp_i).organization_id := l_new.organization_id;
2657 l_outer_lpns(l_tmp_i).subinventory_code := l_new.subinventory_code;
2658 l_outer_lpns(l_tmp_i).locator_id := l_new.locator_id;
2659 l_outer_lpns(l_tmp_i).lpn_context := l_new.lpn_context;
2660 l_outer_lpns(l_tmp_i).source_type_id := l_new.source_type_id;
2661 l_outer_lpns(l_tmp_i).source_header_id := l_new.source_header_id;
2662 l_outer_lpns(l_tmp_i).source_line_id := l_new.source_line_id;
2663 l_outer_lpns(l_tmp_i).source_line_detail_id := l_new.source_line_detail_id;
2664 l_outer_lpns(l_tmp_i).source_name := l_new.source_name;
2665 ELSE
2666 -- LPN an inner LPN. Need to update child lpns
2667 FOR child_lpn_rec IN nested_child_lpn_cursor( l_old.lpn_id ) LOOP
2668 IF (l_debug = 1) THEN
2669 mdebug('Got child lpn lpnid='||child_lpn_rec.lpn_id, G_INFO);
2670 END IF;
2671
2672 IF ( l_lpn_ids.exists(child_lpn_rec.lpn_id) ) THEN
2673 l_progress := 'LPN attributes already exist in table';
2674 l_tmp_i := l_lpn_ids(child_lpn_rec.lpn_id);
2675
2676 IF (l_debug = 1) THEN
2677 mdebug('LPN attributes already exist in table lpnid='||l_old.lpn_id||' plpn='||l_old.parent_lpn_id||' olpn='||l_old.outermost_lpn_id, G_INFO);
2678 END IF;
2679 ELSE
2680 l_progress := 'Does not already exist in table get from rec';
2681 l_tmp_i := NVL(l_lpns.last, 0) + 1;
2682 l_lpn_ids(child_lpn_rec.lpn_id) := l_tmp_i;
2683
2684 -- Add attributes from rec type to table of lpns
2685 l_lpns(l_tmp_i).lpn_id := child_lpn_rec.lpn_id;
2686 l_lpns(l_tmp_i).license_plate_number := child_lpn_rec.license_plate_number;
2687 l_lpns(l_tmp_i).parent_lpn_id := child_lpn_rec.parent_lpn_id;
2688 l_lpns(l_tmp_i).outermost_lpn_id := child_lpn_rec.outermost_lpn_id;
2689 l_lpns(l_tmp_i).lpn_context := child_lpn_rec.lpn_context;
2690
2691 l_lpns(l_tmp_i).organization_id := child_lpn_rec.organization_id;
2692 l_lpns(l_tmp_i).subinventory_code := child_lpn_rec.subinventory_code;
2693 l_lpns(l_tmp_i).locator_id := child_lpn_rec.locator_id;
2694
2695 l_lpns(l_tmp_i).inventory_item_id := child_lpn_rec.inventory_item_id;
2696 l_lpns(l_tmp_i).revision := child_lpn_rec.revision;
2697 l_lpns(l_tmp_i).lot_number := child_lpn_rec.lot_number;
2698 l_lpns(l_tmp_i).serial_number := child_lpn_rec.serial_number;
2699 l_lpns(l_tmp_i).cost_group_id := child_lpn_rec.cost_group_id;
2700
2701 l_lpns(l_tmp_i).tare_weight_uom_code := child_lpn_rec.tare_weight_uom_code;
2702 l_lpns(l_tmp_i).tare_weight := child_lpn_rec.tare_weight;
2703 l_lpns(l_tmp_i).gross_weight_uom_code := child_lpn_rec.gross_weight_uom_code;
2704 l_lpns(l_tmp_i).gross_weight := child_lpn_rec.gross_weight;
2705 l_lpns(l_tmp_i).container_volume_uom := child_lpn_rec.container_volume_uom;
2706 l_lpns(l_tmp_i).container_volume := child_lpn_rec.container_volume;
2707 l_lpns(l_tmp_i).content_volume_uom_code := child_lpn_rec.content_volume_uom_code;
2708 l_lpns(l_tmp_i).content_volume := child_lpn_rec.content_volume;
2709
2710 l_lpns(l_tmp_i).source_type_id := child_lpn_rec.source_type_id;
2711 l_lpns(l_tmp_i).source_header_id := child_lpn_rec.source_header_id;
2712 l_lpns(l_tmp_i).source_line_id := child_lpn_rec.source_line_id;
2713 l_lpns(l_tmp_i).source_line_detail_id := child_lpn_rec.source_line_detail_id;
2714 l_lpns(l_tmp_i).source_name := child_lpn_rec.source_name;
2715
2716 l_lpns(l_tmp_i).attribute_category := child_lpn_rec.attribute_category;
2717 l_lpns(l_tmp_i).attribute1 := child_lpn_rec.attribute1;
2718 l_lpns(l_tmp_i).attribute2 := child_lpn_rec.attribute2;
2719 l_lpns(l_tmp_i).attribute3 := child_lpn_rec.attribute3;
2720 l_lpns(l_tmp_i).attribute4 := child_lpn_rec.attribute4;
2721 l_lpns(l_tmp_i).attribute5 := child_lpn_rec.attribute5;
2722 l_lpns(l_tmp_i).attribute6 := child_lpn_rec.attribute6;
2723 l_lpns(l_tmp_i).attribute7 := child_lpn_rec.attribute7;
2724 l_lpns(l_tmp_i).attribute8 := child_lpn_rec.attribute8;
2725 l_lpns(l_tmp_i).attribute9 := child_lpn_rec.attribute9;
2726 l_lpns(l_tmp_i).attribute10 := child_lpn_rec.attribute10;
2727 l_lpns(l_tmp_i).attribute11 := child_lpn_rec.attribute11;
2728 l_lpns(l_tmp_i).attribute12 := child_lpn_rec.attribute12;
2729 l_lpns(l_tmp_i).attribute13 := child_lpn_rec.attribute13;
2730 l_lpns(l_tmp_i).attribute14 := child_lpn_rec.attribute14;
2731 l_lpns(l_tmp_i).attribute15 := child_lpn_rec.attribute15;
2732
2733 IF (l_debug = 1) THEN
2734 mdebug('Retrieve attr from rec lpnid='||l_lpns(l_tmp_i).lpn_id||' plpn='||l_lpns(l_tmp_i).parent_lpn_id||' olpn='||l_lpns(l_tmp_i).outermost_lpn_id, G_INFO);
2735 END IF;
2736 END IF;
2737
2738 -- Child LPN record may have already been processed, so there is the possiblity
2739 -- that it is no longer has the same parent lpn. If not then, it is no longer
2740 -- part of this hierarchy, so skip update
2741 IF ( l_lpns(l_tmp_i).parent_lpn_id = child_lpn_rec.parent_lpn_id ) THEN
2742 IF (l_debug = 1) THEN
2743 mdebug('Update values to be inline with new outermost lpn l_tmp_i='||l_tmp_i, G_INFO);
2744 END IF;
2745
2746 -- Values that need updating in child LPNs
2747 l_lpns(l_tmp_i).outermost_lpn_id := l_new.outermost_lpn_id;
2748 ELSIF ( l_debug = 1) THEN
2749 mdebug('Child LPNs parent lpn is not the same skip new='||l_lpns(l_tmp_i).parent_lpn_id||' old='||child_lpn_rec.parent_lpn_id, G_INFO);
2750 END IF;
2751 END LOOP;
2752 END IF;
2753 END IF;
2754
2755 /*****************************************************************/
2756 /* Changes that only pertain to LPNs in which this LPN is packed */
2757 /* Update Parent LPNs */
2758 /*****************************************************************/
2759 IF ( l_old.parent_lpn_id = l_new.parent_lpn_id ) THEN
2760
2761 -- List of attributes that affect parent LPNs. Only if there is a change in
2762 -- these should we open cursor for parent LPNs
2763 -- bug5404902 added change in tare weight to condition
2764 IF ( NVL(l_change_in_gross_weight, 0) <> 0 OR
2765 NVL(l_change_in_tare_weight, 0) <> 0 OR
2766 NVL(l_change_in_volume, 0) <> 0 )
2767 THEN
2768
2769 -- If The LPN has a parent and there is a change in weight or volume, cycle through
2770 -- parent LPNs and update their weights and volumes as well
2771 FOR parent_lpn_rec IN nested_parent_lpn_cursor( NVL(l_old.parent_lpn_id, l_new.parent_lpn_id) ) LOOP
2772 IF (l_debug = 1) THEN
2773 mdebug('Got parent lpn lpnid='||parent_lpn_rec.lpn_id, G_INFO);
2774 END IF;
2775
2776 IF ( l_lpn_ids.exists(parent_lpn_rec.lpn_id) ) THEN
2777 l_progress := 'LPN attributes already exist in table';
2778 l_tmp_i := l_lpn_ids(parent_lpn_rec.lpn_id);
2779 l_tmp_old := l_lpns(l_tmp_i);
2780
2781 IF (l_debug = 1) THEN
2782 mdebug('LPN attributes already exist in table lpnid='||l_tmp_old.lpn_id||' gwuom='||l_tmp_old.gross_weight_uom_code||' gwt='||l_tmp_old.gross_weight||
2783 ' vuom='||l_tmp_old.content_volume_uom_code||' vol='||l_tmp_old.content_volume||' twuom='||l_tmp_old.tare_weight_uom_code||' twt='||l_tmp_old.tare_weight, G_INFO);
2784 END IF;
2785 ELSE
2786 l_progress := 'Does not already exist in table get from rec';
2787 l_tmp_i := l_lpns.last + 1;
2788 l_lpn_ids(parent_lpn_rec.lpn_id) := l_tmp_i;
2789
2790 -- Add attributes from rec type to table of lpns
2791 l_tmp_old.lpn_id := parent_lpn_rec.lpn_id;
2792 l_tmp_old.license_plate_number := parent_lpn_rec.license_plate_number;
2793 l_tmp_old.parent_lpn_id := parent_lpn_rec.parent_lpn_id;
2794 l_tmp_old.outermost_lpn_id := parent_lpn_rec.outermost_lpn_id;
2795 l_tmp_old.lpn_context := parent_lpn_rec.lpn_context;
2796
2797 l_tmp_old.organization_id := parent_lpn_rec.organization_id;
2798 l_tmp_old.subinventory_code := parent_lpn_rec.subinventory_code;
2799 l_tmp_old.locator_id := parent_lpn_rec.locator_id;
2800
2801 l_tmp_old.inventory_item_id := parent_lpn_rec.inventory_item_id;
2802 l_tmp_old.revision := parent_lpn_rec.revision;
2803 l_tmp_old.lot_number := parent_lpn_rec.lot_number;
2804 l_tmp_old.serial_number := parent_lpn_rec.serial_number;
2805 l_tmp_old.cost_group_id := parent_lpn_rec.cost_group_id;
2806
2807 l_tmp_old.tare_weight_uom_code := parent_lpn_rec.tare_weight_uom_code;
2808 l_tmp_old.tare_weight := parent_lpn_rec.tare_weight;
2809 l_tmp_old.gross_weight_uom_code := parent_lpn_rec.gross_weight_uom_code;
2810 l_tmp_old.gross_weight := parent_lpn_rec.gross_weight;
2811 l_tmp_old.container_volume_uom := parent_lpn_rec.container_volume_uom;
2812 l_tmp_old.container_volume := parent_lpn_rec.container_volume;
2813 l_tmp_old.content_volume_uom_code := parent_lpn_rec.content_volume_uom_code;
2814 l_tmp_old.content_volume := parent_lpn_rec.content_volume;
2815
2816 l_tmp_old.source_type_id := parent_lpn_rec.source_type_id;
2817 l_tmp_old.source_header_id := parent_lpn_rec.source_header_id;
2818 l_tmp_old.source_line_id := parent_lpn_rec.source_line_id;
2819 l_tmp_old.source_line_detail_id := parent_lpn_rec.source_line_detail_id;
2820 l_tmp_old.source_name := parent_lpn_rec.source_name;
2821
2822 l_tmp_old.attribute_category := parent_lpn_rec.attribute_category;
2823 l_tmp_old.attribute1 := parent_lpn_rec.attribute1;
2824 l_tmp_old.attribute2 := parent_lpn_rec.attribute2;
2825 l_tmp_old.attribute3 := parent_lpn_rec.attribute3;
2826 l_tmp_old.attribute4 := parent_lpn_rec.attribute4;
2827 l_tmp_old.attribute5 := parent_lpn_rec.attribute5;
2828 l_tmp_old.attribute6 := parent_lpn_rec.attribute6;
2829 l_tmp_old.attribute7 := parent_lpn_rec.attribute7;
2830 l_tmp_old.attribute8 := parent_lpn_rec.attribute8;
2831 l_tmp_old.attribute9 := parent_lpn_rec.attribute9;
2832 l_tmp_old.attribute10 := parent_lpn_rec.attribute10;
2833 l_tmp_old.attribute11 := parent_lpn_rec.attribute11;
2834 l_tmp_old.attribute12 := parent_lpn_rec.attribute12;
2835 l_tmp_old.attribute13 := parent_lpn_rec.attribute13;
2836 l_tmp_old.attribute14 := parent_lpn_rec.attribute14;
2837 l_tmp_old.attribute15 := parent_lpn_rec.attribute15;
2838
2839 IF (l_debug = 1) THEN
2840 mdebug('Retrieve attr from rec lpnid='||l_tmp_old.lpn_id||' gwuom='||l_tmp_old.gross_weight_uom_code||' gwt='||l_tmp_old.gross_weight||' twuom='||l_tmp_old.tare_weight_uom_code||' twt='||l_tmp_old.tare_weight, G_INFO);
2841 mdebug('cntvuom='||l_tmp_old.content_volume_uom_code||' cntvol='||l_tmp_old.content_volume||' ctrvuom='||l_tmp_old.container_volume_uom||' ctrvol='||l_tmp_old.container_volume, G_INFO);
2842 END IF;
2843 END IF;
2844
2845 -- Add all attibutes to new lpn record
2846 l_tmp_new := l_tmp_old;
2847
2848 -- Update parent lpns gross weight
2849 IF ( NVL(l_change_in_gross_weight, 0) <> 0 AND l_change_in_gross_weight_uom IS NOT NULL ) THEN
2850 l_progress := 'Update parent LPN gross weight';
2851
2852 IF ( NVL(l_tmp_new.gross_weight, 0) = 0 OR l_tmp_new.gross_weight_uom_code IS NULL ) THEN
2853 l_tmp_new.gross_weight := l_change_in_gross_weight;
2854 l_tmp_new.gross_weight_uom_code := l_change_in_gross_weight_uom;
2855 ELSIF ( l_tmp_new.gross_weight_uom_code = l_change_in_gross_weight_uom ) THEN
2856 l_tmp_new.gross_weight := l_tmp_new.gross_weight + l_change_in_gross_weight;
2857 ELSE
2858 -- Both are not null but with different UOMs need to convert
2859 l_change_in_gross_weight := Convert_UOM(l_tmp_new.inventory_item_id, l_change_in_gross_weight, l_change_in_gross_weight_uom, l_tmp_new.gross_weight_uom_code, G_NO_CONV_RETURN_ZERO);
2860 l_change_in_gross_weight_uom := l_tmp_new.gross_weight_uom_code;
2861 l_tmp_new.gross_weight := l_tmp_new.gross_weight + l_change_in_gross_weight;
2862 END IF;
2863
2864 IF ( l_tmp_new.gross_weight < 0 ) THEN
2865 l_tmp_new.gross_weight := 0;
2866 END IF;
2867 END IF;
2868
2869 -- bug5404902 add section just like above for tare weight
2870 -- Update parent lpns tare weight
2871 IF ( NVL(l_change_in_tare_weight, 0) <> 0 AND l_change_in_tare_weight_uom IS NOT NULL ) THEN
2872 l_progress := 'Update parent LPN tare weight';
2873
2874 IF ( NVL(l_tmp_new.tare_weight, 0) = 0 OR l_tmp_new.tare_weight_uom_code IS NULL ) THEN
2875 l_tmp_new.tare_weight := l_change_in_tare_weight;
2876 l_tmp_new.tare_weight_uom_code := l_change_in_tare_weight_uom;
2877 ELSIF ( l_tmp_new.tare_weight_uom_code = l_change_in_tare_weight_uom ) THEN
2878 l_tmp_new.tare_weight := l_tmp_new.tare_weight + l_change_in_tare_weight;
2879 ELSE
2880 -- Both are not null but with different UOMs need to convert
2881 l_change_in_tare_weight := Convert_UOM(l_tmp_new.inventory_item_id, l_change_in_tare_weight, l_change_in_tare_weight_uom, l_tmp_new.tare_weight_uom_code, G_NO_CONV_RETURN_ZERO);
2882 l_change_in_tare_weight_uom := l_tmp_new.tare_weight_uom_code;
2883 l_tmp_new.tare_weight := l_tmp_new.tare_weight + l_change_in_tare_weight;
2884 END IF;
2885
2886 IF ( l_tmp_new.tare_weight < 0 ) THEN
2887 l_tmp_new.tare_weight := 0;
2888 END IF;
2889 END IF;
2890
2891 IF ( NVL(l_change_in_volume, 0) <> 0 AND l_change_in_volume_uom IS NOT NULL ) THEN
2892 -- Update parent lpns content volume
2893 IF ( NVL(l_tmp_old.content_volume, 0) = 0 OR l_tmp_old.content_volume_uom_code IS NULL ) THEN
2894 l_tmp_new.content_volume := l_change_in_volume;
2895 l_tmp_new.content_volume_uom_code := l_change_in_volume_uom;
2896 ELSIF ( l_tmp_old.content_volume_uom_code = l_change_in_volume_uom ) THEN
2897 l_tmp_new.content_volume := l_tmp_new.content_volume + l_change_in_volume;
2898 ELSE
2899 -- Both are not null but with different UOMs need to convert
2900 l_change_in_volume := Convert_UOM(l_tmp_new.inventory_item_id, l_change_in_volume, l_change_in_volume_uom, l_tmp_old.content_volume_uom_code, G_NO_CONV_RETURN_ZERO);
2901 l_change_in_volume_uom := l_tmp_old.content_volume_uom_code;
2902 l_tmp_new.content_volume := l_tmp_old.content_volume + l_change_in_volume;
2903 END IF;
2904
2905 -- If this LPN is with within another LPN then need to recalculate the change in
2906 -- volume since content volume used to add to it's parent may be based on the
2907 -- container item, not the contents. If no container item is defined then no need
2908 -- recalculate.
2909 IF ( l_tmp_new.parent_lpn_id IS NOT NULL AND
2910 NVL(l_tmp_old.container_volume, 0) <> 0 AND l_tmp_old.container_volume_uom IS NOT NULL )
2911 THEN
2912 l_progress := 'Call helper procedure to calculate change in parent volume';
2913 Calc_Vol_Change (
2914 p_debug => l_debug
2915 , p_old_lpn => l_tmp_old
2916 , p_new_lpn => l_tmp_new
2917 , p_volume_change => l_change_in_volume
2918 , p_volume_uom_change => l_change_in_volume_uom );
2919 END IF;
2920
2921 IF ( l_tmp_new.content_volume < 0 ) THEN
2922 l_tmp_new.content_volume := 0;
2923 END IF;
2924 END IF;
2925
2926 -- Done calculating changes for this LPN
2927 l_lpns(l_tmp_i) := l_tmp_new;
2928
2929 IF (l_debug = 1) THEN
2930 mdebug('New values for parent LPN lpnid='||l_tmp_new.lpn_id||' gwuom='||l_tmp_new.gross_weight_uom_code||' gwt='||l_tmp_new.gross_weight||' twuom='||l_tmp_new.tare_weight_uom_code||' twt='||l_tmp_new.tare_weight, G_INFO);
2931 mdebug('cntvuom='||l_tmp_new.content_volume_uom_code||' cntvol='||l_tmp_new.content_volume||' ctrvuom='||l_tmp_new.container_volume_uom||' ctrvol='||l_tmp_new.container_volume, G_INFO);
2932 END IF;
2933
2934 IF ( l_tmp_new.lpn_context = LPN_CONTEXT_PICKED ) THEN
2935 -- Need to call shipping to update this LPNs wt and vol
2936 wsh_update_tbl(NVL(wsh_update_tbl.last, 0) + 1) := To_DeliveryDetailsRecType(l_tmp_new);
2937 END IF;
2938
2939 -- If there is no more change in weight of volume exit loop
2940 IF ( NVL(l_change_in_gross_weight, 0) = 0 AND NVL(l_change_in_volume, 0) = 0 ) THEN
2941 EXIT;
2942 END IF;
2943 END LOOP;
2944 l_progress := 'Done updating nest lpn wt/vol';
2945 END IF;
2946 -- Else this is the outermost lpn, no need recalculate change in volume
2947 END IF;
2948
2949 l_progress := 'Done updating based in lpn_id';
2950 l_lpns(l_lpn_tab_i) := l_new;
2951 END IF; -- End of section that pertains to the LPN itself
2952
2953 /************************************************************/
2954 /* Changes that only pertain to Update of entire heirarchy */
2955 /* Update or all lpns with same outermost LPN */
2956 /************************************************************/
2957 l_progress := 'Do updates that effect entire heirarcy';
2958 IF ( p_lpn_table(lpn_tbl_cnt).organization_id <> l_old.organization_id OR
2959 p_lpn_table(lpn_tbl_cnt).subinventory_code <> NVL(l_old.subinventory_code, G_NULL_CHAR) OR
2960 p_lpn_table(lpn_tbl_cnt).locator_id <> NVL(l_old.locator_id, G_NULL_NUM) OR
2961 p_lpn_table(lpn_tbl_cnt).lpn_context <> NVL(l_old.lpn_context, G_NULL_NUM) OR
2962 p_lpn_table(lpn_tbl_cnt).source_type_id <> NVL(l_old.source_type_id, G_NULL_NUM) OR
2963 p_lpn_table(lpn_tbl_cnt).source_header_id <> NVL(l_old.source_header_id, G_NULL_NUM) OR
2964 p_lpn_table(lpn_tbl_cnt).source_line_id <> NVL(l_old.source_line_id, G_NULL_NUM) OR
2965 p_lpn_table(lpn_tbl_cnt).source_line_detail_id <> NVL(l_old.source_line_detail_id , G_NULL_NUM)OR
2966 p_lpn_table(lpn_tbl_cnt).source_name <> NVL(l_old.source_name, G_NULL_CHAR) )
2967 THEN
2968 l_progress := 'Organization';
2969 IF ( p_lpn_table(lpn_tbl_cnt).organization_id = FND_API.G_MISS_NUM ) THEN
2970 l_progress := 'organization_id cannot be made null';
2971 fnd_message.set_name('WMS', 'WMS_UPDATE_LPN_ATTR_ERR');
2972 fnd_message.set_token('ATTR', 'organization_id');
2973 fnd_msg_pub.ADD;
2974 RAISE fnd_api.g_exc_error;
2975 ELSIF ( p_lpn_table(lpn_tbl_cnt).organization_id <> l_old.organization_id ) THEN
2976 l_new.organization_id := p_lpn_table(lpn_tbl_cnt).organization_id;
2977
2978 --Bug # 3516547
2979 --Added code to make sure that the Revision/Lot number/Serial Summary Entry are
2980 --updated from WLC in case of a transfer to an org that doesnt have those controls
2981 --for the item.
2982 FOR new_org IN lpn_item_control_cursor ( l_old.organization_id,
2983 l_new.organization_id,
2984 l_new.outermost_lpn_id )
2985 LOOP
2986 l_progress := 'Find the primary uom code for this item in the source org';
2987
2988 IF ( NOT inv_cache.set_item_rec(
2989 p_organization_id => l_old.organization_id
2990 , p_item_id => new_org.inventory_item_id ) )
2991 THEN
2992 l_progress := 'Error calling INV_CACHE.Set_Item_Rec for orgid='||l_old.organization_id||' item id='||new_org.inventory_item_id;
2993 fnd_message.set_name('WMS', 'WMS_CONT_INVALID_ITEM');
2994 fnd_msg_pub.ADD;
2995 RAISE fnd_api.g_exc_error;
2996 END IF;
2997
2998 IF (l_debug = 1) THEN
2999 mdebug('Got WLC for orgxfer itm='||new_org.inventory_item_id||' oldpuom='||inv_cache.item_rec.primary_uom_code||' newpuom='||new_org.primary_uom_code||
3000 ' sctl='||new_org.serial_number_control_code||' lctl='||new_org.lot_control_code||' rctl='||new_org.revision_qty_control_code, G_INFO);
3001 END IF;
3002
3003 UPDATE wms_lpn_contents wlc
3004 SET wlc.last_update_date = SYSDATE
3005 , wlc.last_updated_by = fnd_global.user_id
3006 , wlc.organization_id = l_new.organization_id
3007 , wlc.serial_summary_entry = DECODE (new_org.serial_number_control_code,1,2,6,2,wlc.serial_summary_entry)
3008 , wlc.serial_number = DECODE (new_org.serial_number_control_code,1,NULL,6,NULL,wlc.serial_number)
3009 , wlc.lot_number = DECODE (new_org.lot_control_code,1,NULL,wlc.lot_number)
3010 , wlc.revision = DECODE (new_org.revision_qty_control_code,1,NULL,wlc.revision)
3011 , wlc.primary_quantity = Convert_UOM(new_org.inventory_item_id, primary_quantity, inv_cache.item_rec.primary_uom_code, new_org.primary_uom_code)
3012 WHERE rowid = new_org.rowid;
3013 END LOOP;
3014 END IF;
3015
3016 l_progress := 'Subiventory';
3017 IF ( p_lpn_table(lpn_tbl_cnt).subinventory_code = FND_API.G_MISS_CHAR ) THEN
3018 l_new.subinventory_code := NULL;
3019 ELSIF ( p_lpn_table(lpn_tbl_cnt).subinventory_code IS NOT NULL ) THEN
3020 l_new.subinventory_code := p_lpn_table(lpn_tbl_cnt).subinventory_code;
3021 END IF;
3022
3023 l_progress := 'Locator';
3024 IF ( p_lpn_table(lpn_tbl_cnt).locator_id = FND_API.G_MISS_NUM ) THEN
3025 l_new.locator_id := NULL;
3026 ELSIF ( p_lpn_table(lpn_tbl_cnt).locator_id IS NOT NULL ) THEN
3027 l_new.locator_id := p_lpn_table(lpn_tbl_cnt).locator_id;
3028 END IF;
3029
3030 l_progress := 'source_type_id';
3031 IF ( p_lpn_table(lpn_tbl_cnt).source_type_id = FND_API.G_MISS_NUM ) THEN
3032 l_new.source_type_id := NULL;
3033 ELSIF ( p_lpn_table(lpn_tbl_cnt).source_type_id IS NOT NULL ) THEN
3034 l_new.source_type_id := p_lpn_table(lpn_tbl_cnt).source_type_id;
3035 END IF;
3036
3037 l_progress := 'source_header_id';
3038 IF ( p_lpn_table(lpn_tbl_cnt).source_header_id = FND_API.G_MISS_NUM ) THEN
3039 l_new.source_header_id := NULL;
3040 ELSIF ( p_lpn_table(lpn_tbl_cnt).source_header_id IS NOT NULL ) THEN
3041 l_new.source_header_id := p_lpn_table(lpn_tbl_cnt).source_header_id;
3042 END IF;
3043
3044 l_progress := 'source_line_id';
3045 IF ( p_lpn_table(lpn_tbl_cnt).source_line_id = FND_API.G_MISS_NUM ) THEN
3046 l_new.source_line_id := NULL;
3047 ELSIF ( p_lpn_table(lpn_tbl_cnt).source_line_id IS NOT NULL ) THEN
3048 l_new.source_line_id := p_lpn_table(lpn_tbl_cnt).source_line_id;
3049 END IF;
3050
3051 l_progress := 'source_line_detail_id';
3052 IF ( p_lpn_table(lpn_tbl_cnt).source_line_detail_id = FND_API.G_MISS_NUM ) THEN
3053 l_new.source_line_detail_id := NULL;
3054 ELSIF ( p_lpn_table(lpn_tbl_cnt).source_line_detail_id IS NOT NULL ) THEN
3055 l_new.source_line_detail_id := p_lpn_table(lpn_tbl_cnt).source_line_detail_id;
3056 END IF;
3057
3058 l_progress := 'source_name';
3059 IF ( p_lpn_table(lpn_tbl_cnt).source_name = FND_API.G_MISS_CHAR ) THEN
3060 l_new.source_name := NULL;
3061 ELSIF ( p_lpn_table(lpn_tbl_cnt).source_name IS NOT NULL ) THEN
3062 l_new.source_name := p_lpn_table(lpn_tbl_cnt).source_name;
3063 END IF;
3064
3065 l_progress := 'Context';
3066 -- Must to context after sub and loc!
3067 IF ( p_lpn_table(lpn_tbl_cnt).lpn_context = FND_API.G_MISS_NUM ) THEN
3068 l_progress := 'LPN context cannot be made null';
3069 fnd_message.set_name('WMS', 'WMS_UPDATE_LPN_ATTR_ERR');
3070 fnd_message.set_token('ATTR', 'lpn_context');
3071 fnd_msg_pub.ADD;
3072 RAISE fnd_api.g_exc_error;
3073 ELSIF ( p_lpn_table(lpn_tbl_cnt).lpn_context <> l_old.lpn_context ) THEN
3074 l_new.lpn_context := p_lpn_table(lpn_tbl_cnt).lpn_context;
3075
3076 l_progress := 'Call API to validate context change';
3077 IF ( NOT Valid_Context_Change(p_caller, l_old.lpn_context, l_new.lpn_context) ) THEN
3078 l_progress := 'Failed Valid_Context_Change check';
3079 RAISE fnd_api.g_exc_error;
3080 END IF;
3081
3082 IF ( l_new.lpn_context = LPN_CONTEXT_STORES OR
3083 l_new.lpn_context = LPN_CONTEXT_PREGENERATED OR
3084 l_new.lpn_context = LPN_CONTEXT_INTRANSIT )
3085 THEN
3086 -- LPNs not in warehouse, cannot have location
3087 l_new.subinventory_code := NULL;
3088 l_new.locator_id := NULL;
3089 END IF;
3090 END IF;
3091
3092 l_progress := 'Add new record to update outermost lpn table to be updated';
3093 IF ( l_outer_lpn_ids.exists(l_new.outermost_lpn_id) ) THEN
3094 l_tmp_i := l_outer_lpn_ids(l_new.outermost_lpn_id);
3095 IF (l_debug = 1) THEN
3096 mdebug('LPN new outer already exist in table l_tmp_i='||l_tmp_i, G_INFO);
3097 END IF;
3098 ELSE
3099 l_tmp_i := NVL(l_outer_lpns.last, 0) + 1;
3100 l_outer_lpn_ids(l_new.outermost_lpn_id) := l_tmp_i;
3101 l_outer_lpns(l_tmp_i).reference_id := l_new.outermost_lpn_id;
3102
3103 IF (l_debug = 1) THEN
3104 mdebug('Create new outer entry in outer table l_tmp_i='||l_tmp_i, G_INFO);
3105 END IF;
3106 END IF;
3107
3108 l_outer_lpns(l_tmp_i).outermost_lpn_id := l_new.outermost_lpn_id;
3109 l_outer_lpns(l_tmp_i).organization_id := l_new.organization_id;
3110 l_outer_lpns(l_tmp_i).subinventory_code := l_new.subinventory_code;
3111 l_outer_lpns(l_tmp_i).locator_id := l_new.locator_id;
3112 l_outer_lpns(l_tmp_i).lpn_context := l_new.lpn_context;
3113 l_outer_lpns(l_tmp_i).source_type_id := l_new.source_type_id;
3114 l_outer_lpns(l_tmp_i).source_header_id := l_new.source_header_id;
3115 l_outer_lpns(l_tmp_i).source_line_id := l_new.source_line_id;
3116 l_outer_lpns(l_tmp_i).source_line_detail_id := l_new.source_line_detail_id;
3117 l_outer_lpns(l_tmp_i).source_name := l_new.source_name;
3118 END IF;
3119
3120 IF (l_debug = 1) THEN
3121 mdebug('New values from LPN updated l_lpn_tab_i='||l_lpn_tab_i||' lpn_tbl_cnt='||lpn_tbl_cnt, G_INFO);
3122 mdebug('lpnid='||l_new.lpn_id||' lpn='||l_new.license_plate_number||' ctx='||l_new.lpn_context||' plpn='||l_new.parent_lpn_id||' olpn='||l_new.outermost_lpn_id||' itm='||l_new.inventory_item_id||' rev='||l_new.revision, G_INFO);
3123 mdebug('lot='||l_new.lot_number||' sn='||l_new.serial_number||' cg='||l_new.cost_group_id||' org='||l_new.organization_id||' sub='||l_new.subinventory_code||' loc='||l_new.locator_id, G_INFO);
3124 mdebug('twt='||l_new.tare_weight||' twuom='||l_new.tare_weight_uom_code||' gwt='||l_new.gross_weight||' gwuom='||l_new.gross_weight_uom_code||
3125 ' ctrvol='||l_new.container_volume||' ctrvoluom='||l_new.container_volume_uom||' ctnvol='||l_new.content_volume||' ctvuom='||l_new.content_volume_uom_code, G_INFO);
3126 mdebug('stype='||l_new.source_type_id||' shdr='||l_new.source_header_id||' srcln='||l_new.source_line_id||' srclndt='||l_new.source_line_detail_id||' srcnm='||l_new.source_name, G_INFO);
3127 --mdebug('reuse='||l_new.lpn_reusability||' hom='||l_new.homogeneous_container||' stat='||l_new.status_id ||' seal='||l_new.sealed_status, G_INFO);
3128 mdebug('acat='||l_new.attribute_category||' a1='||l_new.attribute1||' a2='||l_new.attribute2||' a3='||l_new.attribute3||' a4='||l_new.attribute4||' a5='||l_new.attribute5||' a6='||l_new.attribute6||' a7='||l_new.attribute7, G_INFO);
3129 mdebug('a8='||l_new.attribute8||' a9='||l_new.attribute9||' a10='||l_new.attribute10||' a11='||l_new.attribute11||' a12='||l_new.attribute12||' a13='||l_new.attribute13||' a14='||l_new.attribute14||' a15='||l_new.attribute15, G_INFO);
3130 END IF;
3131
3132 -- Bug 5639121
3133 -- Check to find whether flow is for Internal Order
3134 -- LPN Context changes from 'Loaded to Truck' to "defined but not used'
3135 -- for Internal Orders only
3136 IF ( l_old.lpn_context = LPN_LOADED_FOR_SHIPMENT and l_new.lpn_context = LPN_CONTEXT_PREGENERATED ) THEN
3137 l_internal_order_flag := 1;
3138 END IF;
3139
3140 -- Bug 5246192
3141 -- when shipping a LPN for an internal requisition with direct routing,
3142 -- the .LPN's context is changed from Picked to Resides in Inventory in a different org
3143 -- In that case, the LPN should not be removed from WDD in the source org
3144 -- Add addition where clause that only when context is changed in the same org,
3145 -- then remove LPN from the WDD.
3146 -- Bug 7119011
3147
3148 BEGIN
3149
3150 select nvl(wda.delivery_id,999) into l_delivery_id
3151 from wsh_delivery_details wdd, wsh_delivery_assignments wda
3152 WHERE wda.delivery_detail_id(+) = wdd.delivery_detail_id AND ROWNUM < 2
3153 AND wdd.lpn_id IN
3154 ( select wlpn.lpn_id
3155 from wms_license_plate_numbers wlpn
3156 where wlpn.outermost_lpn_id = p_lpn_table(1).lpn_id);
3157
3158 IF (l_delivery_id <> 999) THEN
3159
3160 WSH_UTIL_CORE.GET_DELIVERY_STATUS(
3161 p_entity_type => 'DELIVERY'
3162 ,p_entity_id => l_delivery_id
3163 ,x_status_code => l_status_code
3164 ,x_return_status => l_return_status);
3165
3166 END IF ;
3167
3168 EXCEPTION
3169 WHEN NO_DATA_FOUND THEN
3170 IF ( l_debug = 1 ) THEN
3171 mdebug('There are no deliveries ', G_ERROR);
3172 END IF;
3173 END;
3174
3175 IF ( (l_old.lpn_context = LPN_CONTEXT_PICKED OR l_old.lpn_context = LPN_LOADED_FOR_SHIPMENT) AND
3176 (l_new.lpn_context = LPN_CONTEXT_INV OR l_new.lpn_context = LPN_CONTEXT_PREGENERATED) AND
3177 (l_old.organization_id = l_new.organization_id) -- Bug 5246192
3178 AND (l_internal_order_flag = 0) AND (NVL(l_status_code,'OP') <>'CL')) -- Bug 7603755
3179 THEN
3180 IF ( l_old.parent_lpn_id IS NOT NULL ) THEN
3181 -- Add this LPN to table so that it can be unpacked in WDD before deletion
3182 -- No need to specify parent LPN, shipping will derrive this
3183 l_wsh_unpack_lpn_id_tbl(NVL(l_wsh_unpack_lpn_id_tbl.last, 0) + 1) := l_old.lpn_id;
3184 END IF;
3185
3186 -- Add this LPN to table so that it can be deleted from WDD
3187 -- No need to specify parent LPN, shipping will derrive this
3188 l_wsh_delete_lpn_id_tbl(NVL(l_wsh_delete_lpn_id_tbl.last, 0) + 1) := l_old.lpn_id;
3189
3190 ELSIF ( l_old.lpn_context = LPN_CONTEXT_PICKED AND l_new.lpn_context = LPN_CONTEXT_PICKED) THEN
3191 IF ( NVL(l_old.inventory_item_id, G_NULL_NUM) <> NVL(l_new.inventory_item_id, G_NULL_NUM) OR
3192 NVL(l_old.tare_weight, G_NULL_NUM) <> NVL(l_new.tare_weight, G_NULL_NUM) OR
3193 NVL(l_old.tare_weight_uom_code, G_NULL_CHAR) <> NVL(l_new.tare_weight_uom_code, G_NULL_CHAR) OR
3194 NVL(l_old.gross_weight, G_NULL_NUM) <> NVL(l_new.gross_weight, G_NULL_NUM) OR
3195 NVL(l_old.gross_weight_uom_code, G_NULL_CHAR) <> NVL(l_new.gross_weight_uom_code, G_NULL_CHAR) OR
3196 NVL(l_old.container_volume, G_NULL_NUM) <> NVL(l_new.container_volume, G_NULL_NUM) OR
3197 NVL(l_old.container_volume_uom, G_NULL_CHAR) <> NVL(l_new.container_volume_uom, G_NULL_CHAR) OR
3198 NVL(l_old.content_volume, G_NULL_NUM) <> NVL(l_new.content_volume, G_NULL_NUM) OR
3199 NVL(l_old.content_volume_uom_code, G_NULL_CHAR) <> NVL(l_new.content_volume_uom_code, G_NULL_CHAR) )
3200 THEN
3201 -- If some attribute that shipping cares about has been changed
3202 -- Need to call shipping to update this LPNs attributes
3203 wsh_update_tbl(NVL(wsh_update_tbl.last, 0) + 1) := To_DeliveryDetailsRecType(l_new);
3204 ELSIF ( NVL(l_old.subinventory_code, G_NULL_CHAR) <> NVL(l_new.subinventory_code, G_NULL_CHAR) OR
3205 NVL(l_old.locator_id, G_NULL_NUM) <> NVL(l_new.locator_id, G_NULL_NUM) )
3206 THEN
3207 -- If any of the following attributes were changed need to inform shipping
3208 -- add record to call WSH_WMS_LPN_GRP.create_update_containers
3209 l_tmp_i := NVL(wsh_update_tbl.last, 0) + 1;
3210
3211 wsh_update_tbl(l_tmp_i).organization_id := l_new.organization_id;
3212 wsh_update_tbl(l_tmp_i).lpn_id := l_new.outermost_lpn_id;
3213 wsh_update_tbl(l_tmp_i).container_name := l_new.license_plate_number;
3214 wsh_update_tbl(l_tmp_i).subinventory := l_new.subinventory_code;
3215 wsh_update_tbl(l_tmp_i).locator_id := l_new.locator_id;
3216 END IF;
3217 ELSIF ( l_old.lpn_context <> LPN_CONTEXT_PICKED AND l_new.lpn_context = LPN_CONTEXT_PICKED ) THEN
3218 -- Need to call shipping to create this record
3219 wsh_create_tbl(NVL(wsh_create_tbl.last, 0) + 1) := To_DeliveryDetailsRecType(l_new);
3220 END IF;
3221
3222
3223 IF ( wsh_create_tbl.last > 0 ) THEN
3224 IF (l_debug = 1) THEN
3225 mdebug('Calling WSH API to create WDD count='||wsh_create_tbl.last, G_INFO);
3226 END IF;
3227
3228 l_IN_rec.caller := 'WMS';
3229 l_IN_rec.action_code := 'CREATE';
3230
3231 WSH_WMS_LPN_GRP.Create_Update_Containers (
3232 p_api_version => 1.0
3233 , p_init_msg_list => fnd_api.g_false
3234 , p_commit => fnd_api.g_false
3235 , x_return_status => x_return_status
3236 , x_msg_count => x_msg_count
3237 , x_msg_data => x_msg_data
3238 , p_detail_info_tab => wsh_create_tbl
3239 , p_IN_rec => l_IN_rec
3240 , x_OUT_rec => l_OUT_rec );
3241
3242 IF ( x_return_status <> fnd_api.g_ret_sts_success ) THEN
3243 IF (l_debug = 1) THEN
3244 mdebug('Create_Update_Containers Failed, May alreade exist in WDD, Try update instead', G_ERROR);
3245 FOR i in 1..x_msg_count LOOP
3246 l_msgdata := substr(l_msgdata||' | '||substr(fnd_msg_pub.get(x_msg_count-i+1, 'F'), 0, 200),1,2000);
3247 END LOOP;
3248 mdebug('msg: '||l_msgdata, G_ERROR);
3249 END IF;
3250 l_IN_rec.action_code := 'UPDATE';
3251
3252 WSH_WMS_LPN_GRP.Create_Update_Containers (
3253 p_api_version => 1.0
3254 , p_init_msg_list => fnd_api.g_false
3255 , p_commit => fnd_api.g_false
3256 , x_return_status => x_return_status
3257 , x_msg_count => x_msg_count
3258 , x_msg_data => x_msg_data
3259 , p_detail_info_tab => wsh_create_tbl
3260 , p_IN_rec => l_IN_rec
3261 , x_OUT_rec => l_OUT_rec );
3262 END IF;
3263
3264 IF ( x_return_status <> fnd_api.g_ret_sts_success ) THEN
3265 IF (l_debug = 1) THEN
3266 mdebug('WSH Create Containers Failed', G_ERROR);
3267 END IF;
3268 RAISE fnd_api.g_exc_error;
3269 ELSIF ( l_debug = 1 ) THEN
3270 mdebug('Done with Create_Update_Containers', G_INFO);
3271 END IF;
3272
3273 -- Once Create is done need to clear table
3274 wsh_create_tbl.delete;
3275 END IF;
3276
3277 -- Call Update shipping on an per record basis
3278 IF ( wsh_update_tbl.last > 0 ) THEN
3279 IF (l_debug = 1) THEN
3280 mdebug('Calling WSH API to update WDD count='||wsh_update_tbl.last, G_INFO);
3281 END IF;
3282
3283 l_IN_rec.caller := 'WMS';
3284 l_IN_rec.action_code := 'UPDATE';
3285
3286 WSH_WMS_LPN_GRP.Create_Update_Containers (
3287 p_api_version => 1.0
3288 , p_init_msg_list => fnd_api.g_false
3289 , p_commit => fnd_api.g_false
3290 , x_return_status => x_return_status
3291 , x_msg_count => x_msg_count
3292 , x_msg_data => x_msg_data
3293 , p_detail_info_tab => wsh_update_tbl
3294 , p_IN_rec => l_IN_rec
3295 , x_OUT_rec => l_OUT_rec );
3296
3297 IF ( x_return_status <> fnd_api.g_ret_sts_success ) THEN
3298 IF (l_debug = 1) THEN
3299 mdebug('Create_Update_Containers Failed, Might not yet exist in WDD, Try create instead', G_ERROR);
3300 FOR i in 1..x_msg_count LOOP
3301 l_msgdata := substr(l_msgdata||' | '||substr(fnd_msg_pub.get(x_msg_count-i+1, 'F'), 0, 200),1,2000);
3302 END LOOP;
3303 mdebug('msg: '||l_msgdata, G_ERROR);
3304 END IF;
3305 l_IN_rec.action_code := 'CREATE';
3306
3307 WSH_WMS_LPN_GRP.Create_Update_Containers (
3308 p_api_version => 1.0
3309 , p_init_msg_list => fnd_api.g_false
3310 , p_commit => fnd_api.g_false
3311 , x_return_status => x_return_status
3312 , x_msg_count => x_msg_count
3313 , x_msg_data => x_msg_data
3314 , p_detail_info_tab => wsh_update_tbl
3315 , p_IN_rec => l_IN_rec
3316 , x_OUT_rec => l_OUT_rec );
3317 END IF;
3318
3319 IF ( x_return_status <> fnd_api.g_ret_sts_success ) THEN
3320 IF (l_debug = 1) THEN
3321 mdebug('WSH Update Containers Failed', G_ERROR);
3322 END IF;
3323 RAISE fnd_api.g_exc_error;
3324 ELSIF ( l_debug = 1 ) THEN
3325 mdebug('Done with Create_Update_Containers', G_INFO);
3326 END IF;
3327
3328 -- Once update is done need to clear table
3329 wsh_update_tbl.delete;
3330 END IF;
3331
3332 IF (l_debug = 1) THEN
3333 mdebug('Done processing lpn_id='||l_old.lpn_id, G_INFO);
3334 END IF;
3335 END LOOP;
3336
3337 l_progress := 'Done with data handling, transfer to LPN bulk record of tables';
3338
3339 IF ( l_wsh_unpack_lpn_id_tbl.last > 0 ) THEN
3340 IF (l_debug = 1) THEN
3341 mdebug('Call to WSH Delivery_Detail_Action unpack LPNs before becoming pregenerated: '||l_wsh_unpack_lpn_id_tbl.first||'-'||l_wsh_unpack_lpn_id_tbl.last, G_INFO);
3342 END IF;
3343
3344 l_wsh_action_prms.caller := 'WMS';
3345 l_wsh_action_prms.action_code := 'UNPACK';
3346
3347 WSH_WMS_LPN_GRP.Delivery_Detail_Action (
3348 p_api_version_number => 1.0
3349 , p_init_msg_list => fnd_api.g_false
3350 , p_commit => fnd_api.g_false
3351 , x_return_status => x_return_status
3352 , x_msg_count => x_msg_count
3353 , x_msg_data => x_msg_data
3354 , p_lpn_id_tbl => l_wsh_unpack_lpn_id_tbl
3355 , p_del_det_id_tbl => l_wsh_del_det_id_tbl
3356 , p_action_prms => l_wsh_action_prms
3357 , x_defaults => l_wsh_defaults
3358 , x_action_out_rec => l_wsh_action_out_rec );
3359
3360 IF (x_return_status <> fnd_api.g_ret_sts_success) THEN
3361 l_progress := 'Delivery_Detail_Action failed';
3362 --RAISE fnd_api.g_exc_error;
3363
3364 IF ( x_return_status = fnd_api.g_ret_sts_error ) THEN
3365 RAISE fnd_api.g_exc_error;
3366 ELSIF ( l_debug = 1 ) THEN
3367 mdebug('x_return_status='||x_return_status, G_INFO);
3368 END IF;
3369 ELSIF (l_debug = 1) THEN
3370 mdebug('Done with call to WSH Create_Update_Containers', G_INFO);
3371 END IF;
3372
3373 -- Clear used parameters for completeness
3374 l_wsh_action_prms.caller := NULL;
3375 l_wsh_action_prms.action_code := NULL;
3376 l_wsh_unpack_lpn_id_tbl.delete;
3377 END IF;
3378
3379 IF ( l_wsh_delete_lpn_id_tbl.last > 0 ) THEN
3380 IF (l_debug = 1) THEN
3381 mdebug('Calling WSH API to remove LPN from WDD: '||l_wsh_delete_lpn_id_tbl.first||'-'||l_wsh_delete_lpn_id_tbl.last, G_INFO);
3382 END IF;
3383
3384 l_wsh_action_prms.caller := 'WMS';
3385 l_wsh_action_prms.action_code := 'DELETE';
3386
3387 WSH_WMS_LPN_GRP.Delivery_Detail_Action (
3388 p_api_version_number => 1.0
3389 , p_init_msg_list => fnd_api.g_false
3390 , p_commit => fnd_api.g_false
3391 , x_return_status => x_return_status
3392 , x_msg_count => x_msg_count
3393 , x_msg_data => x_msg_data
3394 , p_lpn_id_tbl => l_wsh_delete_lpn_id_tbl
3395 , p_del_det_id_tbl => l_wsh_del_det_id_tbl
3396 , p_action_prms => l_wsh_action_prms
3397 , x_defaults => l_wsh_defaults
3398 , x_action_out_rec => l_wsh_action_out_rec );
3399
3400 IF ( x_return_status <> fnd_api.g_ret_sts_success ) THEN
3401 IF (l_debug = 1) THEN
3402 mdebug('Delivery_Detail_Action Not Successful', G_ERROR);
3403 END IF;
3404
3405 IF ( x_return_status = fnd_api.g_ret_sts_error ) THEN
3406 RAISE fnd_api.g_exc_error;
3407 ELSIF ( l_debug = 1 ) THEN
3408 mdebug('x_return_status='||x_return_status, G_INFO);
3409 END IF;
3410 ELSIF ( l_debug = 1 ) THEN
3411 mdebug('Done with Delivery_Detail_Action', G_INFO);
3412 END IF;
3413
3414 -- Clear parameters used
3415 l_wsh_action_prms.caller := NULL;
3416 l_wsh_action_prms.action_code := NULL;
3417 l_wsh_delete_lpn_id_tbl.delete;
3418 END IF;
3419
3420 IF ( l_lpns.last > 0 ) THEN
3421 l_progress := 'Update LPNs last='||l_outer_lpns.last;
3422 l_lpn_bulk_rec := To_LPNBulkRecType(l_lpns);
3423
3424 IF (l_debug = 1) THEN
3425 mdebug('Bulk Update LPNs in WLPN: '||l_lpn_bulk_rec.lpn_id.first||'-'||l_lpn_bulk_rec.lpn_id.last, G_INFO);
3426
3427 /*(FOR bulk_i IN l_lpn_bulk_rec.outermost_lpn_id.first .. l_lpn_bulk_rec.outermost_lpn_id.last LOOP
3428 mdebug('lpn_id='|| l_lpn_bulk_rec.lpn_id(bulk_i));
3429 END LOOP;*/
3430 END IF;
3431
3432 BEGIN
3433 FORALL bulk_i IN l_lpn_bulk_rec.lpn_id.first .. l_lpn_bulk_rec.lpn_id.last
3434 UPDATE wms_license_plate_numbers wlpn
3435 SET last_update_date = SYSDATE
3436 , last_updated_by = fnd_global.user_id
3437 , organization_id = l_lpn_bulk_rec.organization_id(bulk_i)
3438 , license_plate_number = l_lpn_bulk_rec.license_plate_number(bulk_i)
3439 , parent_lpn_id = l_lpn_bulk_rec.parent_lpn_id(bulk_i)
3440 , outermost_lpn_id = l_lpn_bulk_rec.outermost_lpn_id(bulk_i)
3441 , inventory_item_id = l_lpn_bulk_rec.inventory_item_id(bulk_i)
3442 , subinventory_code = l_lpn_bulk_rec.subinventory_code(bulk_i)
3443 , locator_id = l_lpn_bulk_rec.locator_id(bulk_i)
3444 , tare_weight = l_lpn_bulk_rec.tare_weight(bulk_i)
3445 , tare_weight_uom_code = l_lpn_bulk_rec.tare_weight_uom_code(bulk_i)
3446 , gross_weight_uom_code = l_lpn_bulk_rec.gross_weight_uom_code(bulk_i)
3447 , gross_weight = l_lpn_bulk_rec.gross_weight(bulk_i)
3448 , container_volume = l_lpn_bulk_rec.container_volume(bulk_i)
3449 , container_volume_uom = l_lpn_bulk_rec.container_volume_uom(bulk_i)
3450 , content_volume_uom_code = l_lpn_bulk_rec.content_volume_uom_code(bulk_i)
3451 , content_volume = l_lpn_bulk_rec.content_volume(bulk_i)
3452 --, status_id = l_lpn_bulk_rec.status_id(bulk_i)
3453 , lpn_context = l_lpn_bulk_rec.lpn_context(bulk_i)
3454 --, sealed_status = l_lpn_bulk_rec.sealed_status(bulk_i)
3455 , attribute_category = l_lpn_bulk_rec.attribute_category(bulk_i)
3456 , attribute1 = l_lpn_bulk_rec.attribute1(bulk_i)
3457 , attribute2 = l_lpn_bulk_rec.attribute2(bulk_i)
3458 , attribute3 = l_lpn_bulk_rec.attribute3(bulk_i)
3459 , attribute4 = l_lpn_bulk_rec.attribute4(bulk_i)
3460 , attribute5 = l_lpn_bulk_rec.attribute5(bulk_i)
3461 , attribute6 = l_lpn_bulk_rec.attribute6(bulk_i)
3462 , attribute7 = l_lpn_bulk_rec.attribute7(bulk_i)
3463 , attribute8 = l_lpn_bulk_rec.attribute8(bulk_i)
3464 , attribute9 = l_lpn_bulk_rec.attribute9(bulk_i)
3465 , attribute10 = l_lpn_bulk_rec.attribute10(bulk_i)
3466 , attribute11 = l_lpn_bulk_rec.attribute11(bulk_i)
3467 , attribute12 = l_lpn_bulk_rec.attribute12(bulk_i)
3468 , attribute13 = l_lpn_bulk_rec.attribute13(bulk_i)
3469 , attribute14 = l_lpn_bulk_rec.attribute14(bulk_i)
3470 , attribute15 = l_lpn_bulk_rec.attribute15(bulk_i)
3471 , source_type_id = l_lpn_bulk_rec.source_type_id(bulk_i)
3472 , source_header_id = l_lpn_bulk_rec.source_header_id(bulk_i)
3473 , source_line_id = l_lpn_bulk_rec.source_line_id(bulk_i)
3474 , source_line_detail_id = l_lpn_bulk_rec.source_line_detail_id(bulk_i)
3475 , source_name = l_lpn_bulk_rec.source_name(bulk_i)
3476 WHERE lpn_id = l_lpn_bulk_rec.lpn_id(bulk_i);
3477 EXCEPTION
3478 WHEN DUP_VAL_ON_INDEX THEN
3479 IF ( l_debug = 1 ) THEN
3480 mdebug('Bulk Update WLPN failed uniqueness constraint', G_ERROR);
3481 END IF;
3482
3483 FOR bulk_i IN l_lpn_bulk_rec.lpn_id.first..l_lpn_bulk_rec.lpn_id.last LOOP
3484 BEGIN
3485 SELECT 1 INTO l_dummy_num
3486 FROM wms_license_plate_numbers
3487 WHERE license_plate_number = l_lpn_bulk_rec.license_plate_number(bulk_i);
3488
3489 IF ( l_debug = 1 ) THEN
3490 mdebug('LPN '||l_lpn_bulk_rec.license_plate_number(bulk_i)||' already exists, cannot update another LPN with this name', G_ERROR);
3491 END IF;
3492 fnd_message.set_name('WMS', 'WMS_CONT_DUPLICATE_LPN');
3493 fnd_message.set_token('LPN', l_lpn_bulk_rec.license_plate_number(bulk_i));
3494 fnd_msg_pub.ADD;
3495 RAISE fnd_api.g_exc_error;
3496 EXCEPTION
3497 WHEN NO_DATA_FOUND THEN
3498 NULL;
3499 END;
3500 END LOOP;
3501 END;
3502
3503 IF (l_debug = 1) THEN
3504 mdebug('Bulk Updated WLPN count='||SQL%ROWCOUNT, G_INFO);
3505 END IF;
3506 END IF;
3507
3508 IF ( l_outer_lpns.last > 0 ) THEN
3509 l_progress := 'Update outermost LPNs last='||l_outer_lpns.last;
3510 l_lpn_bulk_rec := To_LPNBulkRecType(l_outer_lpns);
3511
3512 IF (l_debug = 1) THEN
3513 mdebug('Bulk Update outermost LPNs in WLPN: '||l_lpn_bulk_rec.lpn_id.first||'-'||l_lpn_bulk_rec.lpn_id.last, G_INFO);
3514
3515 /*FOR bulk_i IN l_lpn_bulk_rec.outermost_lpn_id.first .. l_lpn_bulk_rec.outermost_lpn_id.last LOOP
3516 mdebug('reference_id ='|| l_lpn_bulk_rec.reference_id(bulk_i));
3517 END LOOP;*/
3518 END IF;
3519
3520 FORALL bulk_i IN l_lpn_bulk_rec.outermost_lpn_id.first .. l_lpn_bulk_rec.outermost_lpn_id.last
3521 UPDATE wms_license_plate_numbers wlpn
3522 SET last_update_date = SYSDATE
3523 , last_updated_by = fnd_global.user_id
3524 , outermost_lpn_id = l_lpn_bulk_rec.outermost_lpn_id(bulk_i)
3525 , organization_id = l_lpn_bulk_rec.organization_id(bulk_i)
3526 , subinventory_code = l_lpn_bulk_rec.subinventory_code(bulk_i)
3527 , locator_id = l_lpn_bulk_rec.locator_id(bulk_i)
3528 , lpn_context = l_lpn_bulk_rec.lpn_context(bulk_i)
3529 , source_type_id = l_lpn_bulk_rec.source_type_id(bulk_i)
3530 , source_header_id = l_lpn_bulk_rec.source_header_id(bulk_i)
3531 , source_line_id = l_lpn_bulk_rec.source_line_id(bulk_i)
3532 , source_line_detail_id = l_lpn_bulk_rec.source_line_detail_id(bulk_i)
3533 , source_name = l_lpn_bulk_rec.source_name(bulk_i)
3534 WHERE outermost_lpn_id = l_lpn_bulk_rec.reference_id(bulk_i);
3535
3536 IF (l_debug = 1) THEN
3537 mdebug('Bulk Updated outermost WLPN count='||SQL%ROWCOUNT, G_INFO);
3538 END IF;
3539 END IF;
3540
3541 -- Standard check of p_commit.
3542 IF fnd_api.to_boolean(p_commit) THEN
3543 COMMIT WORK;
3544 END IF;
3545
3546 -- Standard call to get message count and data
3547 fnd_msg_pub.count_and_get(p_count => x_msg_count, p_data => x_msg_data);
3548 EXCEPTION
3549 WHEN FND_API.G_EXC_ERROR THEN
3550 x_return_status := fnd_api.g_ret_sts_error;
3551 FND_MSG_PUB.Count_And_Get(p_count => x_msg_count, p_data => x_msg_data);
3552 IF (l_debug = 1) THEN
3553 FOR i in 1..x_msg_count LOOP
3554 l_msgdata := substr(l_msgdata||' | '||substr(fnd_msg_pub.get(x_msg_count-i+1, 'F'), 0, 200),1,2000);
3555 END LOOP;
3556 mdebug(l_api_name ||' Error progress='||l_progress||' SQL error: '|| SQLERRM(SQLCODE), G_ERROR);
3557 mdebug('msg: '||l_msgdata, G_ERROR);
3558 END IF;
3559 ROLLBACK TO MODIFY_LPNS_PVT;
3560 --WHEN NOWAIT THEN
3561 -- x_return_status := fnd_api.g_ret_sts_unexp_error;
3562 WHEN OTHERS THEN
3563 x_return_status := fnd_api.g_ret_sts_unexp_error;
3564 fnd_message.set_name('WMS', 'WMS_UPDATE_LPN_FAILED');
3565 fnd_msg_pub.ADD;
3566 FND_MSG_PUB.Count_And_Get(p_count => x_msg_count, p_data => x_msg_data);
3567 IF (l_debug = 1) THEN
3568 mdebug(l_api_name ||' Error progress='||l_progress||' SQL error: '|| SQLERRM(SQLCODE), G_ERROR);
3569 END IF;
3570 ROLLBACK TO MODIFY_LPNS_PVT;
3571 END Modify_LPNs;
3572
3573 -- ----------------------------------------------------------------------------------
3574 -- ----------------------------------------------------------------------------------
3575
3576 PROCEDURE Generate_LPN_CP (
3577 errbuf OUT NOCOPY VARCHAR2
3578 , retcode OUT NOCOPY NUMBER
3579 , p_api_version IN NUMBER
3580 , p_organization_id IN NUMBER
3581 , p_container_item_id IN NUMBER := NULL
3582 , p_revision IN VARCHAR2 := NULL
3583 , p_lot_number IN VARCHAR2 := NULL
3584 , p_from_serial_number IN VARCHAR2 := NULL
3585 , p_to_serial_number IN VARCHAR2 := NULL
3586 , p_subinventory IN VARCHAR2 := NULL
3587 , p_locator_id IN NUMBER := NULL
3588 , p_org_parameters IN NUMBER
3589 , p_parm_dummy_1 IN VARCHAR2
3590 , p_total_length IN NUMBER
3591 , p_lpn_prefix IN VARCHAR2 := NULL
3592 , p_starting_num IN NUMBER := NULL
3593 , p_ucc_128_suffix_flag IN NUMBER
3594 , p_parm_dummy_2 IN VARCHAR2
3595 , p_lpn_suffix IN VARCHAR2 := NULL
3596 , p_quantity IN NUMBER := 1
3597 , p_source IN NUMBER := LPN_CONTEXT_PREGENERATED
3598 , p_cost_group_id IN NUMBER := NULL
3599 ) IS
3600 l_debug number := NVL(FND_PROFILE.VALUE('INV_DEBUG_TRACE'),0);
3601 x_return_status VARCHAR2(4);
3602 x_msg_count NUMBER;
3603 x_msg_data VARCHAR2(300);
3604 ret BOOLEAN;
3605
3606 l_ucc_128_suffix_flag VARCHAR2(1);
3607 l_lpn_prefix VARCHAR2(50);
3608 l_lpn_suffix VARCHAR2(50);
3609 l_wms_org_flag BOOLEAN;
3610
3611 l_lpn_att_rec WMS_Data_Type_Definitions_PUB.LPNRecordType;
3612 l_serial_tbl WMS_Data_Type_Definitions_PUB.SerialRangeTableType;
3613 l_gen_lpn_tbl WMS_Data_Type_Definitions_PUB.LPNTableType;
3614
3615 BEGIN
3616 IF (l_debug = 1) THEN
3617 mdebug('Generate_LPN_CP Entered '|| g_pkg_version, 1);
3618 mdebug('orgid=' ||p_organization_id||' sub='||p_subinventory||' loc='||p_locator_id||' orgparam='||p_org_parameters||' src=' ||p_source, G_INFO);
3619 mdebug('cntitemid=' ||p_container_item_id|| ' rev=' ||p_revision||' lot='||p_lot_number||' fmsn='||p_from_serial_number||' tosn='||p_to_serial_number||' cg='||p_cost_group_id, G_INFO);
3620 mdebug('prefix='||p_lpn_prefix||' suffix='|| p_lpn_suffix ||' strtnum='||p_starting_num ||' qty='||p_quantity||' lgth='||p_total_length||' ucc='||p_ucc_128_suffix_flag, G_INFO);
3621 END IF;
3622
3623 -- Bug 5144565 Check if the organization is a WMS organization
3624 l_wms_org_flag := wms_install.check_install (
3625 x_return_status => x_return_status
3626 , x_msg_count => x_msg_count
3627 , x_msg_data => x_msg_data
3628 , p_organization_id => p_organization_id );
3629 IF ( x_return_status <> fnd_api.g_ret_sts_success ) THEN
3630 IF ( l_debug = 1 ) THEN
3631 mdebug('Call to wms_install.check_install failed:' ||x_msg_data, 1);
3632 END IF;
3633 RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
3634 END IF;
3635
3636 IF ( NOT l_wms_org_flag ) THEN
3637 IF ( l_debug = 1 ) THEN
3638 mdebug('Generate License Plate concurrent program is only available for WMS enabled organizations', 1);
3639 END IF;
3640 fnd_message.set_name('WMS', 'WMS_ONLY_FUNCTIONALITY');
3641 fnd_msg_pub.ADD;
3642 RAISE fnd_api.g_exc_error;
3643 END IF;
3644
3645 --7270863 the condition IF ( l_ucc_128_suffix_flag IS NULL ) will be successful now if l_ucc_128_suffix_flag value is null in Auto_Create_LPNs
3646 --'N' will be passed only if it is having some values(2) other than 1
3647 IF ( p_ucc_128_suffix_flag = 1 ) THEN
3648 l_ucc_128_suffix_flag := 'Y';
3649 ELSIF p_ucc_128_suffix_flag is NOT NULL THEN --7270863
3650 l_ucc_128_suffix_flag := 'N';
3651 END IF;
3652
3653 -- Bug 4691144 If the default from org parameters is set to 'no'
3654 -- Set prefix and suffix to NULL.
3655 IF ( p_org_parameters = 2 ) THEN
3656 IF ( p_lpn_prefix IS NULL ) THEN
3657 l_lpn_prefix := FND_API.G_MISS_CHAR;
3658 ELSE
3659 l_lpn_prefix := p_lpn_prefix;
3660 END IF;
3661
3662 IF ( p_lpn_suffix IS NULL ) THEN
3663 l_lpn_suffix := FND_API.G_MISS_CHAR;
3664 ELSE
3665 l_lpn_suffix := p_lpn_suffix;
3666 END IF;
3667 END IF;
3668
3669 l_lpn_att_rec.lpn_context := p_source;
3670 l_lpn_att_rec.organization_id := p_organization_id;
3671 l_lpn_att_rec.subinventory_code := p_subinventory;
3672 l_lpn_att_rec.locator_id := p_locator_id;
3673 l_lpn_att_rec.inventory_item_id := p_container_item_id;
3674 l_lpn_att_rec.revision := p_revision;
3675 l_lpn_att_rec.lot_number := p_lot_number;
3676 l_lpn_att_rec.cost_group_id := p_cost_group_id;
3677
3678 l_serial_tbl(1).fm_serial_number := p_from_serial_number;
3679 l_serial_tbl(1).to_serial_number := p_to_serial_number;
3680
3681 Auto_Create_LPNs (
3682 p_api_version => p_api_version
3683 , p_init_msg_list => fnd_api.g_false
3684 , p_commit => fnd_api.g_false
3685 , x_return_status => x_return_status
3686 , x_msg_count => x_msg_count
3687 , x_msg_data => x_msg_data
3688 , p_caller => 'WMS_Generate_LPN_CP'
3689 , p_quantity => p_quantity
3690 , p_lpn_prefix => l_lpn_prefix
3691 , p_lpn_suffix => l_lpn_suffix
3692 , p_starting_number => p_starting_num
3693 , p_total_lpn_length => p_total_length
3694 , p_ucc_128_suffix_flag => l_ucc_128_suffix_flag
3695 , p_lpn_attributes => l_lpn_att_rec
3696 , p_serial_ranges => l_serial_tbl
3697 , x_created_lpns => l_gen_lpn_tbl );
3698
3699 IF (x_return_status = fnd_api.g_ret_sts_success) THEN
3700 ret := fnd_concurrent.set_completion_status('NORMAL', x_msg_data);
3701 retcode := 0;
3702 ELSE
3703 ret := fnd_concurrent.set_completion_status('ERROR', x_msg_data);
3704 retcode := 2;
3705 errbuf := x_msg_data;
3706 END IF;
3707 END;
3708
3709
3710 /*********************************************************************************
3711 * Generate_LPN()
3712 *
3713 *********************************************************************************/
3714 PROCEDURE Generate_LPN (
3715 p_api_version IN NUMBER
3716 , p_init_msg_list IN VARCHAR2 := fnd_api.g_false
3717 , p_commit IN VARCHAR2 := fnd_api.g_false
3718 , p_validation_level IN NUMBER := fnd_api.g_valid_level_full
3719 , x_return_status OUT NOCOPY VARCHAR2
3720 , x_msg_count OUT NOCOPY NUMBER
3721 , x_msg_data OUT NOCOPY VARCHAR2
3722 , p_organization_id IN NUMBER
3723 , p_container_item_id IN NUMBER := NULL
3724 , p_revision IN VARCHAR2 := NULL
3725 , p_lot_number IN VARCHAR2 := NULL
3726 , p_from_serial_number IN VARCHAR2 := NULL
3727 , p_to_serial_number IN VARCHAR2 := NULL
3728 , p_subinventory IN VARCHAR2 := NULL
3729 , p_locator_id IN NUMBER := NULL
3730 , p_lpn_prefix IN VARCHAR2 := NULL
3731 , p_lpn_suffix IN VARCHAR2 := NULL
3732 , p_starting_num IN NUMBER := NULL
3733 , p_quantity IN NUMBER := 1
3734 , p_source IN NUMBER := LPN_CONTEXT_PREGENERATED
3735 , p_cost_group_id IN NUMBER := NULL
3736 , p_source_type_id IN NUMBER := NULL
3737 , p_source_header_id IN NUMBER := NULL
3738 , p_source_name IN VARCHAR2 := NULL
3739 , p_source_line_id IN NUMBER := NULL
3740 , p_source_line_detail_id IN NUMBER := NULL
3741 , p_lpn_id_out OUT NOCOPY NUMBER
3742 , p_lpn_out OUT NOCOPY VARCHAR2
3743 , p_process_id OUT NOCOPY NUMBER
3744 , p_total_length IN NUMBER := NULL
3745 , p_ucc_128_suffix_flag IN NUMBER := 2
3746 ) IS
3747 l_api_name CONSTANT VARCHAR2(30) := 'Generate_LPN';
3748 l_api_version CONSTANT NUMBER := 1.0;
3749 l_debug NUMBER := NVL(FND_PROFILE.VALUE('INV_DEBUG_TRACE'),0);
3750 l_progress VARCHAR2(10) := '0';
3751
3752 l_ucc_128_suffix_flag VARCHAR2(1);
3753 l_lpn_att_rec WMS_Data_Type_Definitions_PUB.LPNRecordType;
3754 l_serial_tbl WMS_Data_Type_Definitions_PUB.SerialRangeTableType;
3755 l_gen_lpn_tbl WMS_Data_Type_Definitions_PUB.LPNTableType;
3756 l_lpn_bulk_rec LPNBulkRecType;
3757
3758 BEGIN
3759 SAVEPOINT GENERATE_LPN_PVT;
3760
3761 IF (l_debug = 1) THEN
3762 mdebug(l_api_name|| ' Entered '|| g_pkg_version, 1);
3763 mdebug('orgid=' ||p_organization_id|| ' sub=' ||p_subinventory|| ' loc=' ||p_locator_id|| ' src=' ||p_source, G_INFO);
3764 mdebug('cntitemid=' ||p_container_item_id|| ' rev=' ||p_revision|| ' lot=' ||p_lot_number|| ' fmsn=' ||p_from_serial_number|| ' tosn=' ||p_to_serial_number|| ' cstgrp=' ||p_cost_group_id, G_INFO);
3765 mdebug('prefix=' ||p_lpn_prefix|| ' suffix=' || p_lpn_suffix || ' strtnum=' ||p_starting_num || ' qty=' ||p_quantity);
3766 --mdebug('scrtype=' ||p_source_type_id|| ' srchdr=' ||p_source_header_id|| ' srcname=' ||p_source_name|| ' srcln=' ||p_source_line_id||' srclndet='||p_source_line_detail_id, G_INFO);
3767 --mdebug('p_total_length='||p_total_length||', p_ucc_128_suf='||p_ucc_128_suffix_flag);
3768 END IF;
3769
3770 -- Standard call to check for call compatibility.
3771 IF NOT fnd_api.compatible_api_call(l_api_version, p_api_version, l_api_name, g_pkg_name) THEN
3772 fnd_message.set_name('WMS', 'WMS_CONT_INCOMPATIBLE_API_CALL');
3773 fnd_msg_pub.ADD;
3774 RAISE fnd_api.g_exc_unexpected_error;
3775 END IF;
3776
3777 -- Initialize message list if p_init_msg_list is set to TRUE.
3778 IF fnd_api.to_boolean(p_init_msg_list) THEN
3779 fnd_msg_pub.initialize;
3780 END IF;
3781
3782 -- Initialize API return status to success
3783 x_return_status := fnd_api.g_ret_sts_success;
3784
3785 l_lpn_att_rec.lpn_context := p_source;
3786 l_lpn_att_rec.organization_id := p_organization_id;
3787 l_lpn_att_rec.subinventory_code := p_subinventory;
3788 l_lpn_att_rec.locator_id := p_locator_id;
3789 l_lpn_att_rec.inventory_item_id := p_container_item_id;
3790 l_lpn_att_rec.revision := p_revision;
3791 l_lpn_att_rec.lot_number := p_lot_number;
3792 l_lpn_att_rec.cost_group_id := p_cost_group_id;
3793 l_lpn_att_rec.source_type_id := p_source_type_id;
3794 l_lpn_att_rec.source_header_id := p_source_header_id;
3795 l_lpn_att_rec.source_name := p_source_name;
3796 l_lpn_att_rec.source_line_id := p_source_line_id;
3797 l_lpn_att_rec.source_line_detail_id := p_source_line_detail_id;
3798
3799 l_serial_tbl(1).fm_serial_number := p_from_serial_number;
3800 l_serial_tbl(1).to_serial_number := p_to_serial_number;
3801
3802 Auto_Create_LPNs (
3803 p_api_version => p_api_version
3804 , p_init_msg_list => fnd_api.g_false
3805 , p_commit => fnd_api.g_false
3806 , x_return_status => x_return_status
3807 , x_msg_count => x_msg_count
3808 , x_msg_data => x_msg_data
3809 , p_caller => 'Generate_LPN'
3810 , p_quantity => p_quantity
3811 , p_lpn_prefix => p_lpn_prefix
3812 , p_lpn_suffix => p_lpn_suffix
3813 , p_starting_number => p_starting_num
3814 , p_total_lpn_length => p_total_length
3815 , p_ucc_128_suffix_flag => l_ucc_128_suffix_flag
3816 , p_lpn_attributes => l_lpn_att_rec
3817 , p_serial_ranges => l_serial_tbl
3818 , x_created_lpns => l_gen_lpn_tbl );
3819
3820 IF ( x_return_status = fnd_api.g_ret_sts_success ) THEN
3821 IF ( p_quantity = 1 ) THEN
3822 p_lpn_id_out := l_gen_lpn_tbl(1).lpn_id;
3823 p_lpn_out := l_gen_lpn_tbl(1).license_plate_number;
3824 ELSE
3825 -- More than one LPN was requested to be generated
3826 -- Generate a process ID number to tell which LPN's were generated
3827 SELECT wms_lpn_process_temp_s.NEXTVAL
3828 INTO p_process_id
3829 FROM DUAL;
3830
3831 -- transfer to LPN bulk record of tables
3832 l_lpn_bulk_rec := To_LPNBulkRecType(l_gen_lpn_tbl);
3833
3834 IF ( l_debug = 1 ) THEN
3835 mdebug('Inser into the WMS_LPN_PROCESS_TEMP procid='||p_process_id||' '||l_lpn_bulk_rec.lpn_id.first||'-'||l_lpn_bulk_rec.lpn_id.last , G_INFO);
3836 END IF;
3837
3838 FORALL i in l_lpn_bulk_rec.lpn_id.first .. l_lpn_bulk_rec.lpn_id.last
3839 INSERT INTO wms_lpn_process_temp (
3840 process_id
3841 , lpn_id )
3842 VALUES (
3843 p_process_id
3844 , l_lpn_bulk_rec.lpn_id(i) );
3845 END IF;
3846 ELSE
3847 RAISE fnd_api.g_exc_error;
3848 END IF;
3849
3850 -- Standard check of p_commit.
3851 IF fnd_api.to_boolean(p_commit) THEN
3852 COMMIT WORK;
3853 END IF;
3854
3855 -- Standard call to get message count and if count is 1,
3856 -- get message info.
3857 fnd_msg_pub.count_and_get(p_count => x_msg_count, p_data => x_msg_data);
3858 EXCEPTION
3859 WHEN fnd_api.g_exc_error THEN
3860 --fnd_message.set_name('WMS', 'WMS_LPN_GENERATION_FAIL');
3861 --fnd_msg_pub.ADD;
3862 ROLLBACK TO GENERATE_LPN_PVT;
3863 x_return_status := fnd_api.g_ret_sts_error;
3864 fnd_msg_pub.count_and_get(p_count => x_msg_count, p_data => x_msg_data);
3865 WHEN fnd_api.g_exc_unexpected_error THEN
3866 fnd_message.set_name('WMS', 'WMS_LPN_GENERATION_FAIL');
3867 fnd_msg_pub.ADD;
3868 ROLLBACK TO GENERATE_LPN_PVT;
3869 x_return_status := fnd_api.g_ret_sts_unexp_error;
3870 fnd_msg_pub.count_and_get(p_count => x_msg_count, p_data => x_msg_data);
3871 WHEN OTHERS THEN
3872 fnd_message.set_name('WMS', 'WMS_LPN_GENERATION_FAIL');
3873 fnd_msg_pub.ADD;
3874 ROLLBACK TO GENERATE_LPN_PVT;
3875 x_return_status := fnd_api.g_ret_sts_unexp_error;
3876
3877 IF fnd_msg_pub.check_msg_level(fnd_msg_pub.g_msg_lvl_unexp_error) THEN
3878 fnd_msg_pub.add_exc_msg(g_pkg_name, l_api_name);
3879 END IF;
3880
3881 fnd_msg_pub.count_and_get(p_count => x_msg_count, p_data => x_msg_data);
3882 END Generate_LPN;
3883
3884
3885 -- ----------------------------------------------------------------------------------
3886 -- ----------------------------------------------------------------------------------
3887 PROCEDURE associate_lpn(
3888 p_api_version IN NUMBER,
3889 p_init_msg_list IN VARCHAR2 := fnd_api.g_false,
3890 p_commit IN VARCHAR2 := fnd_api.g_false,
3891 p_validation_level IN NUMBER := fnd_api.g_valid_level_full,
3892 x_return_status OUT NOCOPY VARCHAR2,
3893 x_msg_count OUT NOCOPY NUMBER,
3894 x_msg_data OUT NOCOPY VARCHAR2,
3895 p_lpn_id IN NUMBER,
3896 p_container_item_id IN NUMBER,
3897 p_lot_number IN VARCHAR2 := NULL,
3898 p_revision IN VARCHAR2 := NULL,
3899 p_serial_number IN VARCHAR2 := NULL,
3900 p_organization_id IN NUMBER,
3901 p_subinventory IN VARCHAR2 := NULL,
3902 p_locator_id IN NUMBER := NULL,
3903 p_cost_group_id IN NUMBER := NULL,
3904 p_source_type_id IN NUMBER := NULL,
3905 p_source_header_id IN NUMBER := NULL,
3906 p_source_name IN VARCHAR2 := NULL,
3907 p_source_line_id IN NUMBER := NULL,
3908 p_source_line_detail_id IN NUMBER := NULL
3909 ) IS
3910 l_api_name CONSTANT VARCHAR2(30) := 'Associate_LPN';
3911 l_api_version CONSTANT NUMBER := 1.0;
3912 l_debug NUMBER := NVL(FND_PROFILE.VALUE('INV_DEBUG_TRACE'),0);
3913
3914 l_lpn_tbl WMS_Data_Type_Definitions_PUB.LPNTableType;
3915 BEGIN
3916 -- Standard Start of API savepoint
3917 SAVEPOINT ASSOCIATE_LPN_PVT;
3918
3919 -- Standard call to check for call compatibility.
3920 IF NOT fnd_api.compatible_api_call(l_api_version, p_api_version, l_api_name, g_pkg_name) THEN
3921 fnd_message.set_name('WMS', 'WMS_CONT_INCOMPATIBLE_API_CALL');
3922 fnd_msg_pub.ADD;
3923 RAISE fnd_api.g_exc_unexpected_error;
3924 END IF;
3925
3926 -- Initialize message list if p_init_msg_list is set to TRUE.
3927 IF fnd_api.to_boolean(p_init_msg_list) THEN
3928 fnd_msg_pub.initialize;
3929 END IF;
3930
3931 -- Initialize API return status to success
3932 x_return_status := fnd_api.g_ret_sts_success;
3933
3934 -- API body
3935 IF (l_debug = 1) THEN
3936 mdebug(l_api_name || ' Entered ' || g_pkg_version, 1);
3937 mdebug('orgid=' ||p_organization_id|| ' sub=' ||p_subinventory|| ' loc=' ||p_locator_id|| ' lpnid=' ||p_lpn_id, G_INFO);
3938 mdebug('itemid=' ||p_container_item_id|| ' rev=' ||p_revision|| ' lot=' ||p_lot_number|| ' sn=' ||p_serial_number, G_INFO);
3939 mdebug('cg=' ||p_cost_group_id|| ' srctype=' ||p_source_type_id||' srchdr='||p_source_header_id||' srcln='||p_source_line_id, G_INFO);
3940 END IF;
3941
3942 l_lpn_tbl(1).lpn_id := p_lpn_id;
3943 l_lpn_tbl(1).organization_id := p_organization_id;
3944 l_lpn_tbl(1).subinventory_code := p_subinventory;
3945 l_lpn_tbl(1).locator_id := p_locator_id;
3946
3947 l_lpn_tbl(1).inventory_item_id := p_container_item_id;
3948 l_lpn_tbl(1).lot_number := p_lot_number;
3949 l_lpn_tbl(1).revision := p_revision;
3950 l_lpn_tbl(1).serial_number := p_serial_number;
3951 l_lpn_tbl(1).cost_group_id := p_cost_group_id;
3952
3953 l_lpn_tbl(1).source_type_id := p_source_type_id;
3954 l_lpn_tbl(1).source_header_id := p_source_header_id;
3955 l_lpn_tbl(1).source_name := p_source_name;
3956 l_lpn_tbl(1).source_line_id := p_source_line_id;
3957 l_lpn_tbl(1).source_line_detail_id := p_source_line_detail_id;
3958
3959 Modify_LPNs (
3960 p_api_version => 1.0
3961 , p_init_msg_list => fnd_api.g_false
3962 , p_commit => fnd_api.g_false
3963 , x_return_status => x_return_status
3964 , x_msg_count => x_msg_count
3965 , x_msg_data => x_msg_data
3966 , p_caller => l_api_name
3967 , p_lpn_table => l_lpn_tbl );
3968
3969 IF (x_return_status <> fnd_api.g_ret_sts_success) THEN
3970 IF ( l_debug = 1 ) THEN
3971 mdebug('Modify_LPNs failed', G_ERROR);
3972 END IF;
3973 RAISE fnd_api.g_exc_error;
3974 END IF;
3975
3976 -- End of API body
3977
3978 -- Standard check of p_commit.
3979 IF fnd_api.to_boolean(p_commit) THEN
3980 COMMIT WORK;
3981 END IF;
3982
3983 -- Standard call to get message count and if count is 1,
3984 -- get message info.
3985 fnd_msg_pub.count_and_get(p_count => x_msg_count, p_data => x_msg_data);
3986 EXCEPTION
3987 WHEN fnd_api.g_exc_error THEN
3988 ROLLBACK TO ASSOCIATE_LPN_PVT;
3989 x_return_status := fnd_api.g_ret_sts_error;
3990 fnd_msg_pub.count_and_get(p_count => x_msg_count, p_data => x_msg_data);
3991 WHEN fnd_api.g_exc_unexpected_error THEN
3992 ROLLBACK TO ASSOCIATE_LPN_PVT;
3993 x_return_status := fnd_api.g_ret_sts_unexp_error;
3994 fnd_msg_pub.count_and_get(p_count => x_msg_count, p_data => x_msg_data);
3995 WHEN OTHERS THEN
3996 ROLLBACK TO ASSOCIATE_LPN_PVT;
3997 x_return_status := fnd_api.g_ret_sts_unexp_error;
3998
3999 IF fnd_msg_pub.check_msg_level(fnd_msg_pub.g_msg_lvl_unexp_error) THEN
4000 fnd_msg_pub.add_exc_msg(g_pkg_name, l_api_name);
4001 END IF;
4002
4003 fnd_msg_pub.count_and_get(p_count => x_msg_count, p_data => x_msg_data);
4004 END associate_lpn;
4005
4006 -- ----------------------------------------------------------------------------------
4007 -- ----------------------------------------------------------------------------------
4008
4009 PROCEDURE Create_LPN (
4010 p_api_version IN NUMBER
4011 , p_init_msg_list IN VARCHAR2 := fnd_api.g_false
4012 , p_commit IN VARCHAR2 := fnd_api.g_false
4013 , p_validation_level IN NUMBER := fnd_api.g_valid_level_full
4014 , x_return_status OUT NOCOPY VARCHAR2
4015 , x_msg_count OUT NOCOPY NUMBER
4016 , x_msg_data OUT NOCOPY VARCHAR2
4017 , p_lpn IN VARCHAR2
4018 , p_organization_id IN NUMBER
4019 , p_container_item_id IN NUMBER := NULL
4020 , p_lot_number IN VARCHAR2 := NULL
4021 , p_revision IN VARCHAR2 := NULL
4022 , p_serial_number IN VARCHAR2 := NULL
4023 , p_subinventory IN VARCHAR2 := NULL
4024 , p_locator_id IN NUMBER := NULL
4025 , p_source IN NUMBER := LPN_CONTEXT_PREGENERATED
4026 , p_cost_group_id IN NUMBER := NULL
4027 , p_parent_lpn_id IN NUMBER := NULL
4028 , p_source_type_id IN NUMBER := NULL
4029 , p_source_header_id IN NUMBER := NULL
4030 , p_source_name IN VARCHAR2 := NULL
4031 , p_source_line_id IN NUMBER := NULL
4032 , p_source_line_detail_id IN NUMBER := NULL
4033 , x_lpn_id OUT NOCOPY NUMBER
4034 ) IS
4035 l_api_name CONSTANT VARCHAR2(30) := 'Create_LPN';
4036 l_api_version CONSTANT NUMBER := 1.0;
4037 l_debug NUMBER := NVL(FND_PROFILE.VALUE('INV_DEBUG_TRACE'),0);
4038 l_progress VARCHAR2(10) := '0';
4039 l_msgdata VARCHAR2(1000);
4040
4041 l_lpn_tbl WMS_Data_Type_Definitions_PUB.LPNTableType;
4042
4043 BEGIN
4044 -- Standard Start of API savepoint
4045 SAVEPOINT CREATE_LPN_PVT;
4046
4047 -- Standard call to check for call compatibility.
4048 IF NOT fnd_api.compatible_api_call(l_api_version, p_api_version, l_api_name, g_pkg_name) THEN
4049 fnd_message.set_name('WMS', 'WMS_CONT_INCOMPATIBLE_API_CALL');
4050 fnd_msg_pub.ADD;
4051 RAISE fnd_api.g_exc_unexpected_error;
4052 END IF;
4053
4054 -- Initialize message list if p_init_msg_list is set to TRUE.
4055 IF fnd_api.to_boolean(p_init_msg_list) THEN
4056 fnd_msg_pub.initialize;
4057 END IF;
4058
4059 -- Initialize API return status to success
4060 x_return_status := fnd_api.g_ret_sts_success;
4061
4062 -- API body
4063 IF (l_debug = 1) THEN
4064 mdebug(l_api_name || ' Entered ' || g_pkg_version, 1);
4065 mdebug('orgid=' ||p_organization_id|| ' sub=' ||p_subinventory|| ' loc=' ||p_locator_id|| ' lpn=' ||p_lpn|| ' src=' ||p_source, G_INFO);
4066 mdebug('cntitemid=' ||p_container_item_id|| ' rev=' ||p_revision|| ' lot=' ||p_lot_number|| ' sn=' ||p_serial_number|| ' cstgrp=' ||p_cost_group_id, G_INFO);
4067 mdebug('prntlpnid=' ||p_parent_lpn_id|| ' scrtype=' ||p_source_type_id|| ' srchdr=' ||p_source_header_id|| ' srcname=' ||p_source_name|| ' srcln=' ||p_source_line_id||' srclndet='||p_source_line_detail_id, G_INFO);
4068 END IF;
4069
4070 l_lpn_tbl(1).license_plate_number := p_lpn;
4071 l_lpn_tbl(1).organization_id := p_organization_id;
4072 l_lpn_tbl(1).inventory_item_id := p_container_item_id;
4073 l_lpn_tbl(1).lot_number := p_lot_number;
4074 l_lpn_tbl(1).revision := p_revision;
4075 l_lpn_tbl(1).serial_number := p_serial_number;
4076 l_lpn_tbl(1).subinventory_code := p_subinventory;
4077 l_lpn_tbl(1).locator_id := p_locator_id;
4078 l_lpn_tbl(1).lpn_context := p_source;
4079 l_lpn_tbl(1).cost_group_id := p_cost_group_id;
4080 --l_lpn_tbl(1).parent_lpn_id := p_parent_lpn_id;
4081 l_lpn_tbl(1).source_type_id := p_source_type_id;
4082 l_lpn_tbl(1).source_header_id := p_source_header_id;
4083 l_lpn_tbl(1).source_name := p_source_name;
4084 l_lpn_tbl(1).source_line_id := p_source_line_id;
4085 l_lpn_tbl(1).source_line_detail_id := p_source_line_detail_id;
4086
4087 Create_LPNs (
4088 p_api_version => p_api_version
4089 , p_init_msg_list => fnd_api.g_false
4090 , p_commit => fnd_api.g_false
4091 , x_return_status => x_return_status
4092 , x_msg_count => x_msg_count
4093 , x_msg_data => x_msg_data
4094 , p_caller => l_api_name
4095 , p_lpn_table => l_lpn_tbl );
4096
4097 IF ( x_return_status = fnd_api.g_ret_sts_success ) THEN
4098 x_lpn_id := l_lpn_tbl(1).lpn_id;
4099 ELSE
4100 RAISE fnd_api.g_exc_error;
4101 END IF;
4102
4103 -- Standard check of p_commit.
4104 IF fnd_api.to_boolean(p_commit) THEN
4105 COMMIT WORK;
4106 END IF;
4107
4108 -- Standard call to get message count and if count is 1,
4109 -- get message info.
4110 fnd_msg_pub.count_and_get(p_count => x_msg_count, p_data => x_msg_data);
4111 EXCEPTION
4112 WHEN FND_API.G_EXC_ERROR THEN
4113 x_return_status := fnd_api.g_ret_sts_error;
4114 FND_MSG_PUB.Count_And_Get(p_count => x_msg_count, p_data => x_msg_data);
4115 IF (l_debug = 1) THEN
4116 FOR i in 1..x_msg_count LOOP
4117 l_msgdata := substr(l_msgdata||' | '||substr(fnd_msg_pub.get(x_msg_count-i+1, 'F'), 0, 200),1,2000);
4118 END LOOP;
4119 mdebug(l_api_name ||' Error progress= '||l_progress||'SQL error: '|| SQLERRM(SQLCODE), G_ERROR);
4120 mdebug('msg: '||l_msgdata, G_ERROR);
4121 END IF;
4122 ROLLBACK TO CREATE_LPN_PVT;
4123 WHEN OTHERS THEN
4124 x_return_status := fnd_api.g_ret_sts_unexp_error;
4125 FND_MSG_PUB.Count_And_Get(p_count => x_msg_count, p_data => x_msg_data);
4126 IF (l_debug = 1) THEN
4127 mdebug(l_api_name ||' Error progress= '||l_progress||'SQL error: '|| SQLERRM(SQLCODE), G_ERROR);
4128 END IF;
4129 ROLLBACK TO CREATE_LPN_PVT;
4130 END Create_LPN;
4131
4132 -- ----------------------------------------------------------------------------------
4133 -- ----------------------------------------------------------------------------------
4134
4135 PROCEDURE PackUnpack_Container(
4136 p_api_version IN NUMBER
4137 , p_init_msg_list IN VARCHAR2 := fnd_api.g_false
4138 , p_commit IN VARCHAR2 := fnd_api.g_false
4139 , p_validation_level IN NUMBER := fnd_api.g_valid_level_full
4140 , x_return_status OUT NOCOPY VARCHAR2
4141 , x_msg_count OUT NOCOPY NUMBER
4142 , x_msg_data OUT NOCOPY VARCHAR2
4143 , p_lpn_id IN NUMBER
4144 , p_content_lpn_id IN NUMBER := NULL
4145 , p_content_item_id IN NUMBER := NULL
4146 , p_content_item_desc IN VARCHAR2 := NULL
4147 , p_revision IN VARCHAR2 := NULL
4148 , p_lot_number IN VARCHAR2 := NULL
4149 , p_from_serial_number IN VARCHAR2 := NULL
4150 , p_to_serial_number IN VARCHAR2 := NULL
4151 , p_quantity IN NUMBER := 1
4152 , p_uom IN VARCHAR2 := NULL
4153 , p_sec_quantity IN NUMBER := NULL -- INVCONV kkillams
4154 , p_sec_uom IN VARCHAR2 := NULL -- INVCONV kkillams
4155 , p_organization_id IN NUMBER
4156 , p_subinventory IN VARCHAR2 := NULL
4157 , p_locator_id IN NUMBER := NULL
4158 , p_enforce_wv_constraints IN NUMBER := 2
4159 , p_operation IN NUMBER
4160 , p_cost_group_id IN NUMBER := NULL
4161 , p_source_type_id IN NUMBER := NULL
4162 , p_source_header_id IN NUMBER := NULL
4163 , p_source_name IN VARCHAR2 := NULL
4164 , p_source_line_id IN NUMBER := NULL
4165 , p_source_line_detail_id IN NUMBER := NULL
4166 , p_unpack_all IN NUMBER := 2
4167 , p_auto_unnest_empty_lpns IN NUMBER := 1
4168 , p_ignore_item_controls IN NUMBER := 2
4169 , p_primary_quantity IN NUMBER := NULL
4170 , p_caller IN VARCHAR2 := NULL
4171 , p_source_transaction_id IN NUMBER := NULL
4172 ) IS
4173 l_api_name CONSTANT VARCHAR2(30) := 'PackUnpack_Container';
4174 l_api_version CONSTANT NUMBER := 1.0;
4175 l_debug NUMBER := NVL(FND_PROFILE.VALUE('INV_DEBUG_TRACE'),0);
4176 l_request_id NUMBER := FND_PROFILE.value('CONC_REQUEST_ID');
4177 l_progress VARCHAR2(100) := '0';
4178 l_msgdata VARCHAR2(1000);
4179
4180 -- Constants defined for transaction types
4181 L_PACK CONSTANT NUMBER := 1;
4182 L_UNPACK CONSTANT NUMBER := 2;
4183 L_CORRECT CONSTANT NUMBER := 3;
4184 L_UNPACK_ALL CONSTANT NUMBER := 4;
4185
4186 -- Types needed for WSH_WMS_LPN_GRP.Delivery_Detail_Action
4187 l_wsh_lpn_id_tbl wsh_util_core.id_tab_type;
4188 l_wsh_del_det_id_tbl wsh_util_core.id_tab_type;
4189 l_wsh_action_prms WSH_GLBL_VAR_STRCT_GRP.dd_action_parameters_rec_type;
4190 l_wsh_defaults WSH_GLBL_VAR_STRCT_GRP.dd_default_parameters_rec_type;
4191 l_wsh_action_out_rec WSH_GLBL_VAR_STRCT_GRP.dd_action_out_rec_type;
4192
4193 l_lpn_tbl WMS_Data_Type_Definitions_PUB.LPNTableType;
4194 l_new WMS_Data_Type_Definitions_PUB.LPNRecordType;
4195 l_cont_new WMS_Data_Type_Definitions_PUB.LPNRecordType;
4196
4197 l_tmp_bulk_lpns LPNBulkRecType;
4198 l_tmp_i NUMBER;
4199
4200 l_lpn WMS_CONTAINER_PUB.LPN;
4201 l_content_lpn WMS_CONTAINER_PUB.LPN;
4202 l_wt_vol_new WMS_CONTAINER_PUB.LPN;
4203
4204 l_result NUMBER;
4205 l_serial_summary_entry NUMBER := 2;
4206
4207 l_subinventory VARCHAR(30);
4208 l_locator_id NUMBER;
4209
4210 l_prefix VARCHAR2(30);
4211 l_from_number NUMBER;
4212 l_to_number NUMBER;
4213 l_errorcode NUMBER;
4214
4215 l_converted_quantity NUMBER;
4216 l_sec_converted_quantity NUMBER; --INVCONV kkillams
4217 l_lpn_is_empty NUMBER := 0;
4218
4219 l_operation_mode NUMBER;
4220 l_quantity NUMBER;
4221 l_primary_quantity NUMBER;
4222 l_item_quantity NUMBER;
4223 l_serial_quantity NUMBER;
4224 l_uom_priority VARCHAR2(3);
4225
4226 l_change_in_gross_weight NUMBER;
4227 l_change_in_gross_weight_uom VARCHAR2(3);
4228 l_change_in_tare_weight NUMBER;
4229 l_change_in_tare_weight_uom VARCHAR(3);
4230 l_change_in_volume NUMBER;
4231 l_change_in_volume_uom VARCHAR2(3);
4232
4233 CURSOR nested_children_cursor(p_outer_lpn_id NUMBER) IS
4234 SELECT lpn_id
4235 FROM wms_license_plate_numbers
4236 START WITH lpn_id = p_outer_lpn_id
4237 CONNECT BY parent_lpn_id = PRIOR lpn_id;
4238
4239 CURSOR nested_parent_cursor(p_child_lpn_id NUMBER) IS
4240 SELECT organization_id, parent_lpn_id, lpn_id, inventory_item_id,
4241 tare_weight, tare_weight_uom_code, gross_weight, gross_weight_uom_code,
4242 container_volume, container_volume_uom, content_volume, content_volume_uom_code
4243 FROM wms_license_plate_numbers
4244 START WITH lpn_id = p_child_lpn_id
4245 CONNECT BY lpn_id = PRIOR parent_lpn_id;
4246
4247 empty_lpn_rec nested_parent_cursor%ROWTYPE;
4248
4249 CURSOR existing_record_cursor( p_context NUMBER, p_serial_summary_entry NUMBER ) IS
4250 SELECT wlc.rowid
4251 , wlc.primary_quantity
4252 , wlc.quantity
4253 , wlc.uom_code
4254 , wlc.cost_group_id
4255 , wlc.secondary_quantity --INVCONV kkillams
4256 , wlc.secondary_uom_code --INVCONV kkillams
4257 FROM wms_lpn_contents wlc
4258 WHERE wlc.parent_lpn_id = p_lpn_id
4259 AND wlc.organization_id = p_organization_id
4260 AND wlc.uom_code = p_uom
4261 AND wlc.inventory_item_id = p_content_item_id
4262 AND NVL(wlc.revision, G_NULL_CHAR) = NVL(p_revision, G_NULL_CHAR)
4263 AND NVL(wlc.lot_number, G_NULL_CHAR) = NVL(p_lot_number, G_NULL_CHAR)
4264 AND NVL(wlc.source_type_id, G_NULL_NUM) = NVL(p_source_type_id, G_NULL_NUM)
4265 AND NVL(wlc.source_header_id, G_NULL_NUM) = NVL(p_source_header_id, G_NULL_NUM)
4266 AND NVL(wlc.source_line_id, G_NULL_NUM) = NVL(p_source_line_id, G_NULL_NUM)
4267 AND NVL(wlc.source_line_detail_id, G_NULL_NUM) = NVL(p_source_line_detail_id, G_NULL_NUM)
4268 AND NVL(wlc.source_name, G_NULL_CHAR) = NVL(p_source_name, G_NULL_CHAR)
4269 AND NVL(wlc.serial_summary_entry, 2) = p_serial_summary_entry;
4270
4271 l_existing_record_cursor existing_record_cursor%ROWTYPE;
4272
4273 CURSOR existing_unpack_record_cursor( p_serial_summary_entry NUMBER, p_uom_code VARCHAR2 ) IS
4274 SELECT wlc.rowid
4275 , wlc.primary_quantity
4276 , wlc.quantity
4277 , wlc.uom_code
4278 , wlc.lot_number
4279 , wlc.serial_summary_entry
4280 , wlc.secondary_quantity --INVCONV kkillams
4281 , wlc.secondary_uom_code --INVCONV kkillams
4282 FROM wms_lpn_contents wlc
4283 WHERE wlc.parent_lpn_id = p_lpn_id
4284 AND wlc.organization_id = p_organization_id
4285 AND wlc.inventory_item_id = p_content_item_id
4286 AND wlc.uom_code = NVL(p_uom_code, wlc.uom_code)
4287 AND NVL(wlc.revision, G_NULL_CHAR) = NVL(p_revision, G_NULL_CHAR)
4288 AND NVL(wlc.lot_number, G_NULL_CHAR) = NVL(DECODE(p_serial_summary_entry, NULL, wlc.lot_number, p_lot_number), G_NULL_CHAR)
4289 AND NVL(wlc.source_type_id, G_NULL_NUM) = NVL(p_source_type_id, NVL(wlc.source_type_id, G_NULL_NUM))
4290 AND NVL(wlc.source_header_id, G_NULL_NUM) = NVL(p_source_header_id, NVL(wlc.source_header_id, G_NULL_NUM))
4291 AND NVL(wlc.source_line_id, G_NULL_NUM) = NVL(p_source_line_id, NVL(wlc.source_line_id, G_NULL_NUM))
4292 AND NVL(wlc.source_line_detail_id, G_NULL_NUM) = NVL(p_source_line_detail_id, NVL(wlc.source_line_detail_id, G_NULL_NUM))
4293 AND NVL(wlc.source_name, G_NULL_CHAR) = NVL(p_source_name, NVL(wlc.source_name, G_NULL_CHAR))
4294 AND NVL(wlc.serial_summary_entry, 2) = NVL(p_serial_summary_entry, NVL(wlc.serial_summary_entry, 2))
4295 AND (NVL(wlc.source_name, G_NULL_CHAR) NOT IN ('RETURN TO VENDOR', 'RETURN TO RECEIVING', 'RETURN TO CUSTOMER')
4296 OR NVL(p_source_name, G_NULL_CHAR) IN ('RETURN TO VENDOR', 'RETURN TO RECEIVING', 'RETURN TO CUSTOMER')
4297 )
4298 ORDER BY wlc.lot_number, wlc.source_type_id DESC, wlc.source_header_id DESC, wlc.source_line_id DESC, wlc.source_line_detail_id DESC, wlc.source_name DESC;
4299
4300 l_temp_record existing_unpack_record_cursor%ROWTYPE;
4301
4302 CURSOR one_time_item_cursor IS
4303 SELECT rowid
4304 , primary_quantity
4305 , quantity
4306 , secondary_quantity --INVCONV kkillams
4307 FROM wms_lpn_contents
4308 WHERE parent_lpn_id = p_lpn_id
4309 AND organization_id = p_organization_id
4310 AND item_description = p_content_item_desc
4311 AND NVL(cost_group_id, G_NULL_NUM) = NVL(p_cost_group_id, G_NULL_NUM)
4312 AND NVL(serial_summary_entry, 2) = l_serial_summary_entry;
4313
4314 l_one_time_item_rec one_time_item_cursor%ROWTYPE;
4315
4316 CURSOR nested_container_cursor IS
4317 SELECT rowid
4318 , lpn_id
4319 , organization_id
4320 , inventory_item_id
4321 , tare_weight
4322 , tare_weight_uom_code
4323 FROM wms_license_plate_numbers
4324 START WITH lpn_id = p_lpn_id
4325 CONNECT BY parent_lpn_id = PRIOR lpn_id;
4326
4327 BEGIN
4328 -- Standard Start of API savepoint
4329 SAVEPOINT PACKUNPACK_CONTAINER;
4330
4331 -- Standard call to check for call compatibility.
4332 IF NOT fnd_api.compatible_api_call(l_api_version, p_api_version, l_api_name, g_pkg_name) THEN
4333 fnd_message.set_name('WMS', 'WMS_CONT_INCOMPATIBLE_API_CALL');
4334 fnd_msg_pub.ADD;
4335 RAISE fnd_api.g_exc_unexpected_error;
4336 END IF;
4337
4338 -- Initialize message list if p_init_msg_list is set to TRUE.
4339 IF fnd_api.to_boolean(p_init_msg_list) THEN
4340 fnd_msg_pub.initialize;
4341 END IF;
4342
4343 -- Initialize API return status to success
4344 x_return_status := fnd_api.g_ret_sts_success;
4345
4346 IF ( l_debug = 1 ) THEN
4347 mdebug(l_api_name || ' Entered ' || g_pkg_version, 1);
4348 mdebug('orgid='||p_organization_id||' sub='||p_subinventory||' loc='||p_locator_id||' lpnid='||p_lpn_id||' cntlpn='||p_content_lpn_id||' enfrc='||p_enforce_wv_constraints, G_INFO);
4349 mdebug('itemid='||p_content_item_id||' rev='||p_revision||' lot='||p_lot_number||' fmsn='||p_from_serial_number||' tosn='||p_to_serial_number||' itmds='||p_content_item_desc, G_INFO);
4350 mdebug('qty='||p_quantity||' uom='||p_uom||' cg='||p_cost_group_id||' oper='||p_operation||' upkall='||p_unpack_all||' unnst='||p_auto_unnest_empty_lpns||' ign='||p_ignore_item_controls, G_INFO);
4351 mdebug('styp='||p_source_type_id||' shdr='||p_source_header_id||' sln='||p_source_line_id||' slndt='||p_source_line_detail_id||' snm='||p_source_name, G_INFO);
4352 mdebug('secondary quantity='||p_sec_quantity||' secondary uom='||p_sec_uom); --INVCONV kkillams
4353 END IF;
4354
4355 -- Need to do this to support old legacy parameter
4356 IF ( p_unpack_all = 1 ) THEN
4357 l_operation_mode := L_UNPACK_ALL;
4358 ELSE
4359 l_operation_mode := p_operation;
4360 END IF;
4361
4362 IF ( p_from_serial_number IS NOT NULL ) THEN
4363 l_serial_summary_entry := 1;
4364 ELSE
4365 l_serial_summary_entry := 2;
4366 END IF;
4367
4368 l_progress := 'Retrieve valuse for parent LPN';
4369
4370 l_lpn.lpn_id := p_lpn_id;
4371 l_lpn.license_plate_number := NULL;
4372 l_result := WMS_CONTAINER_PVT.validate_lpn(l_lpn, 1);
4373
4374 IF (l_result = inv_validate.f) THEN
4375 IF (l_debug = 1) THEN
4376 mdebug(p_lpn_id || 'is an invalid lpn_id', G_ERROR);
4377 END IF;
4378 fnd_message.set_name('WMS', 'WMS_CONT_INVALID_LPN');
4379 fnd_msg_pub.ADD;
4380 RAISE fnd_api.g_exc_error;
4381 END IF;
4382
4383 IF (l_debug = 1) THEN
4384 mdebug('lpn='||l_lpn.license_plate_number||' org='||l_lpn.organization_id||' sub='||l_lpn.subinventory_code||' loc='||l_lpn.locator_id||' ctx='||l_lpn.lpn_context, G_MESSAGE);
4385 mdebug('lpnid='||l_lpn.lpn_id||' lpn='||l_lpn.license_plate_number||' ctx='||l_lpn.lpn_context||' plpn='||l_lpn.parent_lpn_id||' olpn='||l_lpn.outermost_lpn_id||' itm='||l_lpn.inventory_item_id||' rev='||l_lpn.revision, G_INFO);
4386 mdebug('lot='||l_lpn.lot_number||' sn='||l_lpn.serial_number||' cg='||l_lpn.cost_group_id||' org='||l_lpn.organization_id||' sub='||l_lpn.subinventory_code||' loc='||l_lpn.locator_id||' gwuom='||l_lpn.gross_weight_uom_code, G_INFO);
4387 mdebug('gwt='||l_lpn.gross_weight||' vuom='||l_lpn.content_volume_uom_code||' vol='||l_lpn.content_volume||' twuom='||l_lpn.tare_weight_uom_code||' twt='||l_lpn.tare_weight||' stype='||l_lpn.source_type_id, G_INFO);
4388 mdebug('shdr='||l_lpn.source_header_id||' srcln='||l_lpn.source_line_id||' srclndt='||l_lpn.source_line_detail_id||' srcnm='||l_lpn.source_name||' stat='|| l_lpn.status_id ||' seal='||l_lpn.sealed_status, G_INFO);
4389 END IF;
4390
4391 -- Validate that LPN is in correct organzation
4392 IF ( p_organization_id <> l_lpn.organization_id ) THEN
4393 l_progress := 'Org passed by user does not match org on LPN';
4394 fnd_message.set_name('WMS', 'WMS_LPN_DIFF_ORG_ERR');
4395 fnd_message.set_token('LPN', l_lpn.license_plate_number);
4396 fnd_msg_pub.ADD;
4397 RAISE fnd_api.g_exc_error;
4398 END IF;
4399
4400 -- Validate quantities
4401 IF ( NVL(p_quantity, 0) < 0 OR NVL(p_primary_quantity, 0) < 0 ) THEN
4402 l_progress := 'cannot pass negitive qty to this API';
4403 fnd_message.set_name('WMS', 'WMS_CONT_NEG_QTY');
4404 fnd_msg_pub.ADD;
4405 RAISE fnd_api.g_exc_error;
4406 END IF;
4407
4408 IF ( p_content_lpn_id IS NOT NULL ) THEN
4409 l_progress := 'Validate Content LPN';
4410 l_content_lpn.lpn_id := p_content_lpn_id;
4411 l_result := WMS_CONTAINER_PVT.validate_lpn(l_content_lpn);
4412
4413 IF (l_result = inv_validate.f) THEN
4414 IF (l_debug = 1) THEN
4415 mdebug(p_lpn_id || 'is an invalid lpn_id', G_ERROR);
4416 END IF;
4417 fnd_message.set_name('WMS', 'WMS_CONT_INVALID_CONTENT_LPN');
4418 fnd_msg_pub.ADD;
4419 RAISE fnd_api.g_exc_error;
4420 END IF;
4421
4422 IF (l_debug = 1) THEN
4423 mdebug('cntlpn='||l_content_lpn.license_plate_number||' org='||l_content_lpn.organization_id||' sub='||l_content_lpn.subinventory_code||' loc='||l_content_lpn.locator_id||' ctx='||l_content_lpn.lpn_context, G_MESSAGE);
4424 mdebug('lpnid='||l_content_lpn.lpn_id||' lpn='||l_content_lpn.license_plate_number||' ctx='||l_content_lpn.lpn_context||' plpn='||l_content_lpn.parent_lpn_id||' olpn='||l_content_lpn.outermost_lpn_id, G_INFO);
4425 mdebug('itm='||l_content_lpn.inventory_item_id||' rev='||l_content_lpn.revision||' lot='||l_content_lpn.lot_number||' sn='||l_content_lpn.serial_number||' cg='||l_content_lpn.cost_group_id||' org='||l_content_lpn.organization_id, G_INFO);
4426 mdebug('sub='||l_content_lpn.subinventory_code||' loc='||l_content_lpn.locator_id||' gwuom='||l_content_lpn.gross_weight_uom_code||' gwt='||l_content_lpn.gross_weight||' vuom='||l_content_lpn.content_volume_uom_code, G_INFO);
4427 mdebug('vol='||l_content_lpn.content_volume||' twuom='||l_content_lpn.tare_weight_uom_code||' twt='||l_content_lpn.tare_weight||' stype='||l_content_lpn.source_type_id||' shdr='||l_content_lpn.source_header_id, G_INFO);
4428 mdebug('srcln='||l_content_lpn.source_line_id||' srclndt='||l_content_lpn.source_line_detail_id||' srcnm='||l_content_lpn.source_name||' stat='||l_content_lpn.status_id, G_INFO);
4429 END IF;
4430
4431 -- Check that the content lpn is in fact stored within the given parent lpn
4432 -- Do this check only for the unpack operation
4433 IF ( l_operation_mode = L_UNPACK ) THEN
4434 IF (l_content_lpn.parent_lpn_id <> l_lpn.lpn_id) THEN
4435 IF (l_debug = 1) THEN
4436 mdebug('content lpn not in parent lpn', G_ERROR);
4437 END IF;
4438 fnd_message.set_name('WMS', 'WMS_CONT_LPN_NOT_IN_LPN');
4439 fnd_msg_pub.ADD;
4440 RAISE fnd_api.g_exc_error;
4441 END IF;
4442 END IF;
4443
4444 l_quantity := 1;
4445 l_primary_quantity := 1;
4446 ELSIF ( p_content_item_id IS NOT NULL ) THEN
4447 l_progress := 'Calling INV_CACHE.Set_Item_Rec to get item values';
4448
4449 IF ( inv_cache.set_item_rec(
4450 p_organization_id => p_organization_id
4451 , p_item_id => p_content_item_id ) )
4452 THEN
4453 IF (l_debug = 1) THEN
4454 mdebug('Got Item info puom='||inv_cache.item_rec.primary_uom_code||' snctl='||inv_cache.item_rec.serial_number_control_code, G_INFO);
4455 mdebug('wuom='||inv_cache.item_rec.weight_uom_code||' wt='||inv_cache.item_rec.unit_weight||' vuom='||inv_cache.item_rec.volume_uom_code||' vol='||inv_cache.item_rec.unit_volume, G_INFO);
4456 END IF;
4457 ELSE
4458 l_progress := 'Error calling INV_CACHE.Set_Item_Rec for orgid'||p_organization_id||' item id='||p_content_item_id;
4459 fnd_message.set_name('WMS', 'WMS_CONT_INVALID_ITEM');
4460 fnd_msg_pub.ADD;
4461 RAISE fnd_api.g_exc_error;
4462 END IF;
4463
4464 IF ( p_primary_quantity IS NULL ) THEN
4465 IF ( p_uom = inv_cache.item_rec.primary_uom_code ) THEN
4466 l_primary_quantity := p_quantity;
4467 ELSE
4468 l_primary_quantity := Convert_UOM(p_content_item_id, p_quantity, p_uom, inv_cache.item_rec.primary_uom_code);
4469 END IF;
4470 ELSE
4471 l_primary_quantity := p_primary_quantity;
4472 END IF;
4473
4474 l_quantity := p_quantity;
4475
4476 IF (l_debug = 1) THEN
4477 mdebug('l_quantity='||l_quantity||' l_primary_quantity='||l_primary_quantity, G_INFO);
4478 END IF;
4479 ELSIF ( l_operation_mode <> L_UNPACK_ALL ) THEN
4480 -- Unpack all transaction does not need a content lpn/item every other transaction should however.
4481 l_progress := 'Either an item or a content lpn must be specified';
4482 fnd_message.set_name('WMS', 'WMS_CONT_INVALID_ITEM');
4483 fnd_msg_pub.ADD;
4484 fnd_message.set_name('WMS', 'WMS_CONT_INVALID_CONTENT_LPN');
4485 fnd_msg_pub.ADD;
4486 RAISE fnd_api.g_exc_error;
4487 END IF;
4488
4489 -- Parse Serials with out validation
4490 -- Sub and locator might not be given in the case of pre-packing
4491 IF (p_content_item_id IS NOT NULL) THEN
4492 /* Toshiba Fix */
4493 IF ( inv_cache.item_rec.serial_number_control_code NOT IN (1) ) THEN
4494 IF ((p_from_serial_number IS NOT NULL) AND (p_to_serial_number IS NOT NULL)) THEN
4495 l_progress := 'Call this API to parse sn '||p_from_serial_number||'-'||p_to_serial_number;
4496
4497 IF (NOT mtl_serial_check.inv_serial_info(p_from_serial_number, p_to_serial_number, l_prefix, l_quantity, l_from_number, l_to_number, l_errorcode)) THEN
4498 IF (l_debug = 1) THEN
4499 mdebug('Invalid serial number in range', G_ERROR);
4500 END IF;
4501 fnd_message.set_name('WMS', 'WMS_CONT_INVALID_SER');
4502 fnd_msg_pub.ADD;
4503 RAISE fnd_api.g_exc_error;
4504 END IF;
4505
4506 l_progress := 'Done with call to parse sn';
4507 IF (l_debug = 1) THEN
4508 mdebug('Parse SN done prefix='||l_prefix||' qty='||l_quantity||' fmnum='||l_from_number||' tonum='||l_to_number, G_MESSAGE);
4509 END IF;
4510
4511 -- bug5025225 transaction of serial items assumed to be in primary UOM
4512 -- must assign value to primary quantity.
4513 l_primary_quantity := l_quantity;
4514
4515 -- Check that in the case of a range of serial numbers, that the
4516 -- inputted p_quantity equals the amount of items in the serial range.
4517 IF (p_quantity IS NOT NULL) THEN
4518 IF (p_quantity <> l_quantity) THEN
4519 IF (l_debug = 1) THEN
4520 mdebug('Serial range quantity '||l_quantity||' not the same as given qty '||p_quantity, G_ERROR);
4521 END IF;
4522 fnd_message.set_name('WMS', 'WMS_CONT_INVALID_X_QTY');
4523 fnd_msg_pub.ADD;
4524 RAISE fnd_api.g_exc_error;
4525 END IF;
4526 END IF;
4527 END IF;
4528 END IF;
4529 END IF;
4530
4531 l_progress := 'Figure out what subinventory we are trying to pack into';
4532 IF ( p_subinventory IS NULL ) THEN
4533 IF ( l_lpn.subinventory_code IS NOT NULL ) THEN
4534 l_subinventory := l_lpn.subinventory_code;
4535 l_locator_id := l_lpn.locator_id;
4536 ELSIF ( l_content_lpn.subinventory_code IS NOT NULL ) THEN
4537 l_subinventory := l_content_lpn.subinventory_code;
4538 l_locator_id := l_content_lpn.locator_id;
4539 ELSIF ( l_lpn.lpn_context IN (LPN_CONTEXT_INV, LPN_CONTEXT_PICKED) ) THEN
4540 IF (l_debug = 1) THEN
4541 mdebug('No sub and loc info found' , 1);
4542 END IF;
4543 FND_MESSAGE.SET_NAME('WMS', 'WMS_LPN_SUBLOC_MISS');
4544 FND_MSG_PUB.ADD;
4545 RAISE FND_API.G_EXC_ERROR;
4546 END IF;
4547 ELSE
4548 l_subinventory := p_subinventory;
4549 l_locator_id := p_locator_id;
4550 END IF;
4551
4552 IF ( l_subinventory IS NOT NULL ) THEN
4553 l_progress := 'Calling Inv_Cache.Set_Tosub_Rec to get sub';
4554 IF ( NOT inv_cache.set_tosub_rec(p_organization_id, l_subinventory) ) THEN
4555 l_progress := 'Failed to find subinventory org='||p_organization_id||' sub='||l_subinventory;
4556 FND_MESSAGE.SET_NAME('INV', 'INVALID_SUB');
4557 FND_MSG_PUB.ADD;
4558 RAISE FND_API.G_EXC_ERROR;
4559 END IF;
4560 END IF;
4561
4562 IF ( p_subinventory IS NOT NULL AND NVL(inv_cache.tosub_rec.lpn_controlled_flag, 2) = 1 ) THEN
4563 -- subinventory and location infromation was passed validate against lpn
4564 IF ( p_subinventory <> NVL(l_lpn.subinventory_code, l_content_lpn.subinventory_code) OR
4565 p_locator_id <> NVL(l_lpn.locator_id, l_content_lpn.locator_id ) ) THEN
4566 IF (l_debug = 1) THEN
4567 mdebug('LPN was found to be in a different sub/loc than what user specified' , 1);
4568 mdebug('lpn sub=' || l_lpn.subinventory_code ||' lpn loc=' || l_lpn.locator_id, 1);
4569 END IF;
4570 -- Recieving LPNs may have Rcv locations on them but. Allow the location
4571 -- to be different
4572 IF ( l_lpn.lpn_context <> LPN_CONTEXT_RCV ) THEN
4573 FND_MESSAGE.SET_NAME('WMS', 'WMS_LPN_SUBLOC_MISMATCH');
4574 FND_MSG_PUB.ADD;
4575 RAISE FND_API.G_EXC_ERROR;
4576 END IF;
4577 END IF;
4578 END IF;
4579
4580 /*** Packing or Adjust Operation ***/
4581 IF ( l_operation_mode = L_PACK OR l_operation_mode = L_CORRECT ) THEN
4582 -- Check that in case of a pack, the destination subinventory
4583 -- is an LPN enabled/controlled subinventory otherwise fail.
4584 IF ( l_subinventory IS NOT NULL AND NVL(inv_cache.tosub_rec.lpn_controlled_flag, 2) <> 1 ) THEN
4585 fnd_message.set_name('WMS', 'WMS_CONT_NON_LPN_SUB');
4586 fnd_msg_pub.ADD;
4587 RAISE fnd_api.g_exc_error;
4588 END IF;
4589
4590 IF ( p_content_lpn_id IS NOT NULL AND p_content_item_id IS NULL ) THEN
4591 l_progress := 'Packing a LPN into another LPN';
4592
4593 -- Update content LPN parent lpn to be null
4594 l_cont_new.lpn_id := p_content_lpn_id;
4595 l_cont_new.parent_lpn_id := l_lpn.lpn_id;
4596 l_cont_new.outermost_lpn_id := l_lpn.outermost_lpn_id;
4597 l_cont_new.source_type_id := p_source_type_id;
4598 l_cont_new.source_header_id := p_source_header_id;
4599 l_cont_new.source_line_id := p_source_line_id;
4600 l_cont_new.source_line_detail_id := p_source_line_detail_id;
4601 l_cont_new.source_name := p_source_name;
4602
4603 -- If the LPN has no sub or loc information, it will take on the values of the packed item.
4604
4605 IF ( l_lpn.subinventory_code IS NULL ) THEN
4606 IF (l_debug = 1) THEN
4607 mdebug('Xfer LPN has no sub lpnctx='||l_lpn.lpn_context||' clpn sub='||l_content_lpn.subinventory_code||' loc='||l_content_lpn.locator_id||' ctx='||l_content_lpn.lpn_context, G_MESSAGE);
4608 END IF;
4609 -- Update the local LPN variable
4610 l_new.lpn_id := l_lpn.lpn_id;
4611 l_new.subinventory_code := l_subinventory;
4612 l_new.locator_id := l_locator_id;
4613
4614 IF ( l_lpn.lpn_context = LPN_CONTEXT_PREGENERATED ) THEN
4615 -- If pregenerated take context of the content LPN
4616 l_new.lpn_context := l_content_lpn.lpn_context;
4617 END IF;
4618 ELSIF ( l_lpn.subinventory_code <> l_content_lpn.subinventory_code OR
4619 l_lpn.locator_id <> l_content_lpn.locator_id ) THEN
4620 -- Check if the content LPN's sub and loc are the same as the parent lpn
4621
4622 IF (l_debug = 1) THEN
4623 mdebug('parent lpn sub '|| l_lpn.subinventory_code || ' or loc ' || l_lpn.locator_id, G_ERROR);
4624 mdebug('differs from content item sub '|| l_lpn.subinventory_code || ' or loc ' || l_lpn.locator_id, G_ERROR);
4625 END IF;
4626 fnd_message.set_name('WMS', 'WMS_CONT_MISMATCHED_SUB_LOC');
4627 fnd_msg_pub.ADD;
4628 RAISE fnd_api.g_exc_error;
4629 END IF;
4630
4631 -- Only if there is a difference in location, update nested
4632 -- lpns/items/serials with the new location
4633 IF ( l_lpn.organization_id <> l_content_lpn.organization_id OR
4634 l_lpn.subinventory_code <> l_content_lpn.subinventory_code OR
4635 l_lpn.locator_id <> l_content_lpn.locator_id )
4636 THEN
4637 l_tmp_bulk_lpns.lpn_id.delete;
4638
4639 OPEN nested_children_cursor(l_content_lpn.outermost_lpn_id);
4640
4641 FETCH nested_children_cursor
4642 BULK COLLECT INTO l_tmp_bulk_lpns.lpn_id;
4643
4644 IF (l_debug = 1) THEN
4645 mdebug('Bulk update child LPN WLC/MSN: '||l_tmp_bulk_lpns.lpn_id.first||'-'||l_tmp_bulk_lpns.lpn_id.last, G_INFO);
4646 END IF;
4647
4648 -- Update the location information for the packed items
4649 IF ( l_lpn.organization_id <> l_content_lpn.organization_id) THEN
4650 FORALL bulk_i IN l_tmp_bulk_lpns.lpn_id.first .. l_tmp_bulk_lpns.lpn_id.last
4651 UPDATE wms_lpn_contents
4652 SET organization_id = l_lpn.organization_id
4653 , last_update_date = SYSDATE
4654 , last_updated_by = fnd_global.user_id
4655 , request_id = l_request_id
4656 WHERE parent_lpn_id = l_tmp_bulk_lpns.lpn_id(bulk_i);
4657
4658 IF (l_debug = 1) THEN
4659 mdebug('Bulk updated org in WLC cnt='||SQL%ROWCOUNT, G_INFO);
4660 END IF;
4661 END IF;
4662
4663 -- Update the location information for serialized packed items
4664 FORALL bulk_i IN l_tmp_bulk_lpns.lpn_id.first .. l_tmp_bulk_lpns.lpn_id.last
4665 UPDATE mtl_serial_numbers
4666 SET current_organization_id = l_lpn.organization_id
4667 , current_subinventory_code = l_lpn.subinventory_code
4668 , current_locator_id = l_lpn.locator_id
4669 , last_update_date = SYSDATE
4670 , last_updated_by = fnd_global.user_id
4671 WHERE lpn_id = l_tmp_bulk_lpns.lpn_id(bulk_i);
4672
4673 IF (l_debug = 1) THEN
4674 mdebug('Bulk updated org/sub/loc in MSN cnt='||SQL%ROWCOUNT, G_INFO);
4675 END IF;
4676
4677 CLOSE nested_children_cursor;
4678 END IF;
4679
4680 -- Update the location information for the nested child containers
4681 l_progress := 'Pack LPN: Need to update parent lpns weight and volume';
4682 l_wt_vol_new := l_lpn;
4683 l_change_in_gross_weight := l_content_lpn.gross_weight;
4684 l_change_in_gross_weight_uom := l_content_lpn.gross_weight_uom_code;
4685 -- bug5404902 Added to update tare weight of parent
4686 l_change_in_tare_weight := l_content_lpn.tare_weight;
4687 l_change_in_tare_weight_uom := l_content_lpn.tare_weight_uom_code;
4688
4689 -- Need to find if the container of content volume is greater and increment parent
4690 -- LPNs content volume by that amount
4691 Get_Greater_Qty (
4692 p_debug => l_debug
4693 , p_inventory_item_id => l_content_lpn.inventory_item_id
4694 , p_quantity1 => l_content_lpn.container_volume
4695 , p_quantity1_uom => l_content_lpn.container_volume_uom
4696 , p_quantity2 => l_content_lpn.content_volume
4697 , p_quantity2_uom => l_content_lpn.content_volume_uom_code
4698 , x_greater_qty => l_change_in_volume
4699 , x_greater_qty_uom => l_change_in_volume_uom );
4700
4701 ELSIF ( p_content_lpn_id IS NULL AND p_content_item_id IS NOT NULL ) THEN
4702 l_progress := 'Packing a non-container item item_id='|| p_content_item_id;
4703
4704 -- If the LPN has no sub or loc information, it will take on the values of the packed item.
4705 IF (l_lpn.subinventory_code IS NULL AND
4706 (p_subinventory IS NOT NULL OR p_locator_id IS NOT NULL))
4707 THEN
4708 l_progress := 'LPN has no loc info, setting to values passed in by api';
4709 l_new.lpn_id := l_lpn.lpn_id;
4710 l_new.subinventory_code := p_subinventory;
4711 l_new.locator_id := p_locator_id;
4712 END IF;
4713
4714 -- If item is serail controlled update MSN
4715 IF ( p_from_serial_number IS NOT NULL ) THEN
4716 l_progress := 'Packing serialized items sn '||p_from_serial_number||'-'||p_to_serial_number;
4717
4718 -- Serialized item packed LPN information are stored in the serial numbers table
4719 -- Also update the cost group field since it is not guaranteed that the serial number will
4720 -- have that value stamped
4721 UPDATE mtl_serial_numbers
4722 SET lpn_id = p_lpn_id
4723 , cost_group_id = p_cost_group_id
4724 , last_update_date = SYSDATE
4725 , last_updated_by = fnd_global.user_id
4726 , last_txn_source_type_id = p_source_type_id
4727 , last_txn_source_id = p_source_header_id
4728 , last_txn_source_name = p_source_name
4729 , revision = DECODE(current_status, 3, revision, p_revision)
4730 , lot_number = DECODE(current_status, 3, lot_number, p_lot_number)
4731 WHERE inventory_item_id = p_content_item_id
4732 AND current_organization_id = p_organization_id
4733 AND length(serial_number) = length(p_from_serial_number)
4734 AND serial_number BETWEEN p_from_serial_number AND NVL(p_to_serial_number, p_from_serial_number);
4735
4736 l_serial_quantity := SQL%ROWCOUNT;
4737
4738 IF (l_debug = 1) THEN
4739 mdebug('Packed serials cnt='||l_serial_quantity, G_INFO);
4740 END IF;
4741
4742 -- Check that in the case of a range of serial numbers, that the
4743 -- inputted p_quantity equals the amount of items in the serial range.
4744 IF ( p_quantity IS NOT NULL ) THEN
4745 IF ( l_serial_quantity <> l_primary_quantity ) THEN
4746 l_progress := 'Serial range quantity '||l_serial_quantity||' not the same as given qty '||l_primary_quantity;
4747 fnd_message.set_name('WMS', 'WMS_CONT_INVALID_X_QTY');
4748 fnd_msg_pub.ADD;
4749 RAISE fnd_api.g_exc_error;
4750 END IF;
4751 END IF;
4752 END IF;
4753
4754 -- Keep track of change in quantity since in case of correction
4755 -- it will be the difference of existing quantity and new quantity
4756 l_item_quantity := l_primary_quantity;
4757
4758 OPEN existing_record_cursor(l_lpn.lpn_context, l_serial_summary_entry);
4759
4760 FETCH existing_record_cursor INTO l_existing_record_cursor;
4761
4762 IF ( existing_record_cursor%FOUND ) THEN
4763 IF (l_debug = 1) THEN
4764 mdebug('Got WLC rec pqty='||l_existing_record_cursor.primary_quantity||' qty='||l_existing_record_cursor.quantity||' uom='||l_existing_record_cursor.uom_code||' cg='||l_existing_record_cursor.cost_group_id, G_INFO);
4765 END IF;
4766
4767 -- Validate that if the same item (as the passed-in item p_content_item_id)
4768 -- exists on the destination LPN (p_lpn_id) at the top level (not in a child LPN),
4769 -- their cost groups are the same.
4770 IF ( p_validation_level = fnd_api.g_valid_level_full ) THEN
4771 IF ( l_serial_summary_entry <> 1 AND p_cost_group_id <> l_existing_record_cursor.cost_group_id ) THEN
4772 IF (l_debug = 1) THEN
4773 mdebug('Cost Group Violation during packing cg='||l_existing_record_cursor.cost_group_id||' already exists in lpn', G_ERROR);
4774 END IF;
4775 fnd_message.set_name('WMS', 'WMS_CONT_DIFF_CST_GRPS');
4776 fnd_msg_pub.ADD;
4777 RAISE fnd_api.g_exc_error;
4778 END IF;
4779 END IF;
4780
4781 --INCONV kkillams
4782 IF p_sec_uom IS NOT NULL THEN
4783 l_sec_converted_quantity := inv_convert.inv_um_convert(p_content_item_id,
4784 g_precision,
4785 l_existing_record_cursor.secondary_quantity,
4786 l_existing_record_cursor.secondary_uom_code,
4787 p_sec_uom,
4788 NULL,
4789 NULL);
4790 IF ( l_sec_converted_quantity < 0 ) THEN
4791 fnd_message.set_name('INV', 'INV_UOM_CONVERSION_ERROR');
4792 fnd_message.set_token('uom1', l_existing_record_cursor.secondary_uom_code);
4793 fnd_message.set_token('uom2', p_sec_uom);
4794 fnd_message.set_token('module', l_api_name);
4795 fnd_msg_pub.ADD;
4796 RAISE fnd_api.g_exc_error;
4797 END IF;
4798 END IF;
4799 --INCONV kkillams
4800
4801 l_progress := 'Updating existing item row in WLC for pack';
4802 /* fix for bug 2949825 */
4803 IF ( l_operation_mode = L_CORRECT ) THEN
4804 UPDATE wms_lpn_contents
4805 SET last_update_date = SYSDATE
4806 , last_updated_by = fnd_global.user_id
4807 , request_id = l_request_id
4808 , quantity = l_quantity
4809 , uom_code = p_uom
4810 , primary_quantity = l_primary_quantity
4811 WHERE rowid = l_existing_record_cursor.rowid;
4812
4813 -- To calculate wt and volume changes need the difference in quantity
4814 l_item_quantity := l_primary_quantity - l_existing_record_cursor.primary_quantity;
4815 ELSE
4816 UPDATE WMS_LPN_CONTENTS
4817 SET last_update_date = SYSDATE
4818 , last_updated_by = FND_GLOBAL.USER_ID
4819 , request_id = l_request_id
4820 , quantity = quantity + l_quantity
4821 , uom_code = p_uom
4822 , primary_quantity = primary_quantity + l_primary_quantity
4823 , secondary_quantity = CASE WHEN p_sec_uom IS NOT NULL THEN l_sec_converted_quantity + p_sec_quantity
4824 ELSE secondary_quantity END --INVCONV kkillams
4825 WHERE rowid = l_existing_record_cursor.rowid;
4826 END IF;
4827 ELSE
4828 IF (l_debug = 1) THEN
4829 mdebug('Inserting new item row into WLC');
4830 END IF;
4831
4832 INSERT INTO wms_lpn_contents (
4833 last_update_date
4834 , last_updated_by
4835 , creation_date
4836 , created_by
4837 , request_id
4838 , lpn_content_id
4839 , parent_lpn_id
4840 , organization_id
4841 , inventory_item_id
4842 , item_description
4843 , revision
4844 , lot_number
4845 , quantity
4846 , uom_code
4847 , primary_quantity
4848 , cost_group_id
4849 , source_type_id
4850 , source_header_id
4851 , source_line_id
4852 , source_line_detail_id
4853 , source_name
4854 , serial_summary_entry
4855 , secondary_quantity
4856 , secondary_uom_code)
4857 VALUES (
4858 SYSDATE
4859 , fnd_global.user_id
4860 , SYSDATE
4861 , fnd_global.user_id
4862 , l_request_id
4863 , wms_lpn_contents_s.NEXTVAL
4864 , p_lpn_id
4865 , p_organization_id
4866 , p_content_item_id
4867 , p_content_item_desc
4868 , p_revision
4869 , p_lot_number
4870 , l_quantity
4871 , p_uom
4872 , l_primary_quantity
4873 , p_cost_group_id
4874 , p_source_type_id
4875 , p_source_header_id
4876 , p_source_line_id
4877 , p_source_line_detail_id
4878 , p_source_name
4879 , l_serial_summary_entry
4880 , p_sec_quantity --INVCONV kkillams
4881 , p_sec_uom --INVCONV kkillams
4882 );
4883 END IF;
4884
4885 CLOSE existing_record_cursor;
4886
4887 l_progress := 'Pack item: Need to update parent lpns weight and volume';
4888 l_wt_vol_new := l_lpn;
4889 l_change_in_gross_weight := l_item_quantity * inv_cache.item_rec.unit_weight;
4890 l_change_in_gross_weight_uom := inv_cache.item_rec.weight_uom_code;
4891 l_change_in_volume := l_item_quantity * inv_cache.item_rec.unit_volume;
4892 l_change_in_volume_uom := inv_cache.item_rec.volume_uom_code;
4893 ELSE /** Packing a one time item **/
4894 -- If the LPN has no sub or loc information, it will take on the
4895 -- values of the packed item.
4896 IF (l_lpn.subinventory_code IS NULL AND
4897 (p_subinventory IS NOT NULL OR p_locator_id IS NOT NULL))
4898 THEN
4899 l_new.lpn_id := p_lpn_id;
4900 l_new.subinventory_code := p_subinventory;
4901 l_new.locator_id := p_locator_id;
4902 END IF;
4903
4904 /* Pack the one time item */
4905 OPEN one_time_item_cursor;
4906 FETCH one_time_item_cursor INTO l_one_time_item_rec;
4907
4908 IF one_time_item_cursor%NOTFOUND THEN
4909 INSERT INTO wms_lpn_contents (
4910 last_update_date
4911 , last_updated_by
4912 , creation_date
4913 , created_by
4914 , request_id
4915 , lpn_content_id
4916 , parent_lpn_id
4917 , organization_id
4918 , inventory_item_id
4919 , item_description
4920 , revision
4921 , lot_number
4922 , serial_number
4923 , quantity
4924 , uom_code
4925 , primary_quantity
4926 , cost_group_id
4927 , source_type_id
4928 , source_header_id
4929 , source_line_id
4930 , source_line_detail_id
4931 , source_name
4932 , serial_summary_entry
4933 , secondary_quantity
4934 , secondary_uom_code
4935 )
4936 VALUES (
4937 SYSDATE
4938 , fnd_global.user_id
4939 , SYSDATE
4940 , fnd_global.user_id
4941 , l_request_id
4942 , WMS_LPN_CONTENTS_S.NEXTVAL
4943 , p_lpn_id
4944 , p_organization_id
4945 , p_content_item_id
4946 , p_content_item_desc
4947 , p_revision
4948 , p_lot_number
4949 , p_from_serial_number
4950 , l_quantity
4951 , p_uom
4952 , l_primary_quantity
4953 , p_cost_group_id
4954 , p_source_type_id
4955 , p_source_header_id
4956 , p_source_line_id
4957 , p_source_line_detail_id
4958 , p_source_name
4959 , 2
4960 , p_sec_quantity --INVCONV kkillams
4961 , p_sec_uom --INVCONV kkillams
4962 );
4963 ELSE
4964 UPDATE wms_lpn_contents
4965 SET last_update_date = SYSDATE
4966 , last_updated_by = fnd_global.user_id
4967 , request_id = l_request_id
4968 , quantity = NVL(l_one_time_item_rec.quantity, 1) + NVL(l_quantity, 1)
4969 , uom_code = p_uom
4970 , source_type_id = p_source_type_id
4971 , source_header_id = p_source_header_id
4972 , source_line_id = p_source_line_id
4973 , source_line_detail_id = p_source_line_detail_id
4974 , source_name = p_source_name
4975 , secondary_quantity = CASE WHEN p_sec_uom IS NOT NULL THEN NVL(l_one_time_item_rec.secondary_quantity, 1) +
4976 inv_convert.inv_um_convert(inventory_item_id
4977 ,g_precision
4978 ,NVL(l_quantity,1)
4979 ,p_uom
4980 ,p_sec_uom
4981 ,NULL
4982 ,NULL)
4983 ELSE secondary_quantity END --INVCONV kkillams
4984 , secondary_uom_code = p_sec_uom --INVCONV kkillams
4985 WHERE rowid = l_one_time_item_rec.rowid;
4986 END IF;
4987
4988 CLOSE one_time_item_cursor;
4989
4990 END IF;
4991 ELSIF ( l_operation_mode = L_UNPACK ) THEN /*** Unpacking Operation ***/
4992 IF ( p_content_lpn_id IS NOT NULL AND p_content_item_id IS NULL ) THEN
4993 -- Update content LPN parent lpn to be null
4994 l_cont_new.lpn_id := p_content_lpn_id;
4995 l_cont_new.parent_lpn_id := FND_API.G_MISS_NUM;
4996 l_cont_new.outermost_lpn_id := p_content_lpn_id;
4997
4998 /* Bug 2308339: Update the Organization, Sub, Locator only if Sub is LPN Controlled */
4999 IF( l_subinventory IS NOT NULL AND NVL(inv_cache.tosub_rec.lpn_controlled_flag, 2) = 1 ) THEN
5000 FOR l_child_lpn IN nested_children_cursor(p_content_lpn_id) LOOP
5001 -- Only if there is a difference in location, update nested
5002 -- lpns/items/serials with the new location
5003 IF ( l_content_lpn.organization_id <> p_organization_id OR
5004 l_content_lpn.subinventory_code <> l_subinventory OR
5005 l_content_lpn.locator_id <> l_locator_id ) THEN
5006 -- Update the location information for the packed items
5007 IF ( l_content_lpn.organization_id <> p_organization_id ) THEN
5008 UPDATE wms_lpn_contents
5009 SET organization_id = p_organization_id
5010 , last_update_date = SYSDATE
5011 , last_updated_by = fnd_global.user_id
5012 , request_id = l_request_id
5013 WHERE organization_id = l_content_lpn.organization_id
5014 AND parent_lpn_id = l_child_lpn.lpn_id;
5015 END IF;
5016
5017 -- Update the location information for serialized packed items
5018 UPDATE mtl_serial_numbers
5019 SET current_organization_id = p_organization_id
5020 , current_subinventory_code = l_subinventory
5021 , current_locator_id = l_locator_id
5022 , last_update_date = SYSDATE
5023 , last_updated_by = fnd_global.user_id
5024 WHERE current_organization_id = l_content_lpn.organization_id
5025 AND lpn_id = l_child_lpn.lpn_id;
5026 END IF;
5027 END LOOP;
5028
5029 -- Update the location information for the nested child containers
5030 l_cont_new.organization_id := p_organization_id;
5031 l_cont_new.subinventory_code := l_subinventory;
5032 l_cont_new.locator_id := l_locator_id;
5033 END IF;
5034
5035 -- Check to see if there are any items or child containers in soruce LPN
5036 IF ( NVL(p_auto_unnest_empty_lpns, 1) = 1 AND l_lpn_is_empty = 0 ) THEN
5037 BEGIN
5038 SELECT 0 INTO l_lpn_is_empty
5039 FROM dual
5040 WHERE EXISTS (
5041 SELECT 1 FROM wms_lpn_contents
5042 WHERE organization_id = p_organization_id
5043 AND parent_lpn_id = l_lpn.lpn_id )
5044 OR EXISTS (
5045 SELECT 1 FROM wms_license_plate_numbers
5046 WHERE organization_id = p_organization_id
5047 AND parent_lpn_id = l_lpn.lpn_id
5048 AND lpn_id <> l_content_lpn.lpn_id );
5049 EXCEPTION
5050 WHEN NO_DATA_FOUND THEN
5051 l_lpn_is_empty := 1;
5052 END;
5053 END IF;
5054
5055 -- If the source LPN is not empty then the update weight and volume of source LPN
5056 -- Otherwise this calculation is irrelevant since the lpn will become pregenerated
5057 IF ( l_lpn_is_empty <> 1 ) THEN
5058 l_progress := 'Unpack LPN: Need to update parent lpns weight and volume';
5059 l_wt_vol_new := l_lpn;
5060 l_change_in_gross_weight := -1 * l_content_lpn.gross_weight;
5061 l_change_in_gross_weight_uom := l_content_lpn.gross_weight_uom_code;
5062 -- bug5404902 Added to update tare weight of parent
5063 l_change_in_tare_weight := -1 * l_content_lpn.tare_weight;
5064 l_change_in_tare_weight_uom := l_content_lpn.tare_weight_uom_code;
5065
5066 -- Need to find if the container of content volume is greater and decrement parent
5067 -- LPNs content volume by that amount
5068 Get_Greater_Qty (
5069 p_debug => l_debug
5070 , p_inventory_item_id => l_content_lpn.inventory_item_id
5071 , p_quantity1 => l_content_lpn.container_volume
5072 , p_quantity1_uom => l_content_lpn.container_volume_uom
5073 , p_quantity2 => l_content_lpn.content_volume
5074 , p_quantity2_uom => l_content_lpn.content_volume_uom_code
5075 , x_greater_qty => l_change_in_volume
5076 , x_greater_qty_uom => l_change_in_volume_uom );
5077
5078 -- Unpack need change value to negative
5079 l_change_in_volume := -1 * l_change_in_volume;
5080 END IF;
5081 ELSIF ((p_content_lpn_id IS NULL) AND (p_content_item_id IS NOT NULL)) THEN
5082 l_progress := 'Unpacking item from LPN';
5083
5084 IF ((p_from_serial_number IS NOT NULL)AND (p_to_serial_number IS NOT NULL)) THEN
5085 l_progress := 'Unacking serialized items sn '||p_from_serial_number||'-'||p_to_serial_number;
5086
5087 -- Serialized item packed LPN information are stored
5088 -- in the serial numbers table
5089 UPDATE mtl_serial_numbers
5090 SET lpn_id = NULL
5091 , last_update_date = SYSDATE
5092 , last_updated_by = fnd_global.user_id
5093 WHERE inventory_item_id = p_content_item_id
5094 AND current_organization_id = p_organization_id
5095 AND length(serial_number) = length(p_from_serial_number)
5096 AND serial_number BETWEEN p_from_serial_number AND NVL(p_to_serial_number, p_from_serial_number);
5097
5098 IF (l_debug = 1) THEN
5099 mdebug('Unpacked serials cnt='||SQL%ROWCOUNT, G_INFO);
5100 END IF;
5101 END IF;
5102
5103 -- If serial numbers were passed to API remove contents from serial summary entries in WLC
5104 IF ( p_ignore_item_controls = 1 ) THEN
5105 l_serial_summary_entry := NULL;
5106 END IF;
5107
5108 -- Use l_item_quantity to remember how much qty needs to be decremented
5109 l_item_quantity := l_primary_quantity;
5110 l_uom_priority := p_uom;
5111
5112 l_progress := 'Opening existing_unpack_record_cursor serentry='||l_serial_summary_entry||' uom='||l_uom_priority;
5113 OPEN existing_unpack_record_cursor(l_serial_summary_entry, l_uom_priority);
5114
5115 LOOP
5116 FETCH existing_unpack_record_cursor INTO l_temp_record;
5117
5118 IF ( existing_unpack_record_cursor%FOUND ) THEN
5119 IF (l_debug = 1) THEN
5120 mdebug('Got WLC rec pqty='||l_temp_record.primary_quantity||' qty='||l_temp_record.quantity||' uom='||l_temp_record.uom_code||' lot='||l_temp_record.lot_number||' snsum='||l_temp_record.serial_summary_entry, G_INFO);
5121 END IF;
5122
5123 IF ( l_temp_record.primary_quantity IS NULL ) THEN
5124 l_temp_record.primary_quantity := Convert_UOM(
5125 p_content_item_id
5126 , l_temp_record.quantity
5127 , l_temp_record.uom_code
5128 , inv_cache.item_rec.primary_uom_code);
5129
5130 IF (l_debug = 1) THEN
5131 mdebug('Converted WLC pri qty='||l_temp_record.primary_quantity, G_INFO);
5132 END IF;
5133 END IF;
5134
5135 --INCONV kkillams
5136 IF (p_sec_uom IS NOT NULL ) AND
5137 (p_sec_uom <> l_temp_record.secondary_uom_code)
5138 THEN
5139 l_sec_converted_quantity := inv_convert.inv_um_convert(p_content_item_id,
5140 g_precision,
5141 l_temp_record.secondary_quantity,
5142 l_temp_record.secondary_uom_code,
5143 p_sec_uom,
5144 NULL,
5145 NULL);
5146 IF ( l_sec_converted_quantity < 0 ) THEN
5147 fnd_message.set_name('INV', 'INV_UOM_CONVERSION_ERROR');
5148 fnd_message.set_token('uom1', l_temp_record.secondary_uom_code);
5149 fnd_message.set_token('uom2', p_sec_uom);
5150 fnd_message.set_token('module', l_api_name);
5151 fnd_msg_pub.ADD;
5152 RAISE fnd_api.g_exc_error;
5153 END IF;
5154 END IF;
5155 --INCONV kkillams
5156
5157 IF ( round(l_item_quantity, g_precision) < round(l_temp_record.primary_quantity, g_precision) ) THEN
5158 IF ( l_temp_record.uom_code <> inv_cache.item_rec.primary_uom_code ) THEN
5159 l_converted_quantity := Convert_UOM(
5160 p_content_item_id
5161 , l_item_quantity
5162 , inv_cache.item_rec.primary_uom_code
5163 , l_temp_record.uom_code);
5164 ELSE
5165 l_converted_quantity := l_item_quantity;
5166 END IF;
5167
5168 -- Decrement unpack quantity from contents and break loop
5169 UPDATE wms_lpn_contents
5170 SET last_update_date = SYSDATE
5171 , last_updated_by = fnd_global.user_id
5172 , request_id = l_request_id
5173 , quantity = quantity - l_converted_quantity
5174 , primary_quantity = primary_quantity - l_item_quantity
5175 , secondary_quantity = CASE WHEN p_sec_uom IS NOT NULL
5176 THEN (l_sec_converted_quantity - inv_convert.inv_um_convert(p_content_item_id,
5177 g_precision,
5178 l_item_quantity,
5179 inv_cache.item_rec.primary_uom_code,
5180 p_sec_uom,
5181 NULL,
5182 NULL)
5183 )
5184 ELSE secondary_quantity END --INVCONV kkillams
5185 , secondary_uom_code = p_sec_uom
5186 WHERE rowid = l_temp_record.rowid;
5187
5188 EXIT;
5189 ELSIF ( round(l_item_quantity, g_precision) >= round(l_temp_record.primary_quantity, g_precision) ) THEN
5190 mdebug('Delete column from content table and decrement total unpack quantity', G_INFO);
5191 DELETE FROM wms_lpn_contents
5192 WHERE rowid = l_temp_record.rowid;
5193
5194 l_item_quantity := l_item_quantity - l_temp_record.primary_quantity;
5195 EXIT WHEN l_item_quantity <= 0;
5196 END IF;
5197 ELSIF ( l_uom_priority IS NOT NULL ) THEN
5198 IF (l_debug = 1) THEN
5199 mdebug('Not enough to unpack in trx uom='||l_uom_priority, G_ERROR);
5200 END IF;
5201 l_uom_priority := NULL;
5202 CLOSE existing_unpack_record_cursor;
5203 OPEN existing_unpack_record_cursor(l_serial_summary_entry, l_uom_priority);
5204 ELSIF ( l_item_quantity = l_primary_quantity ) THEN
5205 IF (l_debug = 1) THEN
5206 mdebug('Content item not found to unpack', G_ERROR);
5207 END IF;
5208 fnd_message.set_name('WMS', 'WMS_CONT_ITEM_NOT_FOUND');
5209 fnd_msg_pub.ADD;
5210 RAISE fnd_api.g_exc_error;
5211 ELSE
5212 IF (l_debug = 1) THEN
5213 mdebug('Not enough to upack, qty found='||l_item_quantity, G_ERROR);
5214 END IF;
5215 fnd_message.set_name('WMS', 'WMS_CONT_NOT_ENOUGH_TO_UNPACK');
5216 fnd_msg_pub.ADD;
5217 RAISE fnd_api.g_exc_error;
5218 END IF;
5219 END LOOP;
5220 CLOSE existing_unpack_record_cursor;
5221
5222 -- Check to see if there are any items or child containers in soruce LPN
5223 IF ( NVL(p_auto_unnest_empty_lpns, 1) = 1 AND l_lpn_is_empty = 0 ) THEN
5224 BEGIN
5225 SELECT 0 INTO l_lpn_is_empty
5226 FROM dual
5227 WHERE EXISTS (
5228 SELECT 1 FROM wms_lpn_contents
5229 WHERE organization_id = p_organization_id
5230 AND parent_lpn_id = l_lpn.lpn_id )
5231 OR EXISTS (
5232 SELECT 1 FROM wms_license_plate_numbers
5233 WHERE organization_id = p_organization_id
5234 AND parent_lpn_id = l_lpn.lpn_id );
5235 EXCEPTION
5236 WHEN NO_DATA_FOUND THEN
5237 l_lpn_is_empty := 1;
5238 END;
5239 END IF;
5240
5241 -- If the source LPN is not empty then the update weight and volume of source LPN
5242 -- Otherwise this calculation is irrelevant since the lpn will become pregenerated
5243 IF ( l_lpn_is_empty <> 1 ) THEN
5244 l_progress := 'Unpack item: Need to update parent lpns weight and volume';
5245 l_wt_vol_new := l_lpn;
5246 l_change_in_gross_weight := -1 * l_primary_quantity * inv_cache.item_rec.unit_weight;
5247 l_change_in_gross_weight_uom := inv_cache.item_rec.weight_uom_code;
5248 l_change_in_volume := -1 * l_primary_quantity * inv_cache.item_rec.unit_volume;
5249 l_change_in_volume_uom := inv_cache.item_rec.volume_uom_code;
5250 END IF;
5251 ELSIF (p_content_item_desc IS NOT NULL) THEN /*Unpacking a one time item*/
5252 OPEN one_time_item_cursor;
5253 FETCH one_time_item_cursor INTO l_one_time_item_rec;
5254
5255 IF one_time_item_cursor%FOUND THEN
5256 IF ( l_quantity < l_one_time_item_rec.quantity ) THEN
5257 UPDATE wms_lpn_contents
5258 SET last_update_date = SYSDATE
5259 , last_updated_by = fnd_global.user_id
5260 , request_id = l_request_id
5261 , quantity = (l_one_time_item_rec.quantity - l_quantity)
5262 , uom_code = p_uom
5263 WHERE rowid = l_one_time_item_rec.rowid;
5264 ELSIF ( l_quantity = l_one_time_item_rec.quantity ) THEN
5265 DELETE FROM wms_lpn_contents
5266 WHERE rowid = l_one_time_item_rec.rowid;
5267 ELSE
5268 IF (l_debug = 1) THEN
5269 mdebug('Not enough of this onetime item to unpack', G_ERROR);
5270 END IF;
5271 fnd_message.set_name('WMS', 'WMS_CONT_NOT_ENOUGH_TO_UNPACK');
5272 fnd_msg_pub.ADD;
5273 RAISE fnd_api.g_exc_error;
5274 END IF;
5275 ELSE
5276 IF (l_debug = 1) THEN
5277 mdebug('No one time items exits', G_ERROR);
5278 END IF;
5279 fnd_message.set_name('WMS', 'WMS_CONT_NO_ONE_TIME_ITEM');
5280 fnd_msg_pub.ADD;
5281 RAISE fnd_api.g_exc_error;
5282 END IF;
5283 END IF;
5284 ELSIF ( l_operation_mode = L_UNPACK_ALL ) THEN /*** Unpack All Operation ***/
5285 -- This lpn will be empty, need to check parent lpns to see if they also will
5286 -- be empty. if so, they will need to be made defined but not used.
5287 l_lpn_is_empty := 1;
5288 l_tmp_bulk_lpns.lpn_id.delete;
5289
5290 -- Update the information for the child containers
5291 FOR l_child_lpn IN nested_container_cursor LOOP
5292 IF (l_debug = 1) THEN
5293 mdebug('Unpacking all for child lpn='||l_child_lpn.lpn_id, G_INFO);
5294 END IF;
5295
5296 l_tmp_i := NVL(l_lpn_tbl.last, 0) + 1;
5297
5298 -- bug5404902 section for making tare via MSI
5299 IF ( l_child_lpn.inventory_item_id IS NOT NULL ) THEN
5300 SELECT unit_weight
5301 , weight_uom_code
5302 INTO l_lpn_tbl(l_tmp_i).tare_weight
5303 , l_lpn_tbl(l_tmp_i).tare_weight_uom_code
5304 FROM mtl_system_items
5305 WHERE organization_id = l_child_lpn.organization_id
5306 AND inventory_item_id = l_child_lpn.inventory_item_id;
5307 ELSE
5308 -- if there isn't a container item, empty lpns will have undefined
5309 -- tare weight
5310 l_lpn_tbl(l_tmp_i).tare_weight := fnd_api.g_miss_num;
5311 l_lpn_tbl(l_tmp_i).tare_weight_uom_code := fnd_api.g_miss_char;
5312 END IF;
5313
5314 l_lpn_tbl(l_tmp_i).lpn_id := l_child_lpn.lpn_id;
5315 l_lpn_tbl(l_tmp_i).organization_id := p_organization_id;
5316 l_lpn_tbl(l_tmp_i).subinventory_code := fnd_api.g_miss_char;
5317 l_lpn_tbl(l_tmp_i).locator_id := fnd_api.g_miss_num;
5318 l_lpn_tbl(l_tmp_i).parent_lpn_id := fnd_api.g_miss_num;
5319 l_lpn_tbl(l_tmp_i).content_volume := fnd_api.g_miss_num;
5320 l_lpn_tbl(l_tmp_i).content_volume_uom_code := fnd_api.g_miss_char;
5321 -- bug5404902 changed l_child_lpn to l_lpn_tbl(l_tmp_i) since it represents
5322 -- the container items original unit weight
5323 l_lpn_tbl(l_tmp_i).gross_weight := NVL(l_lpn_tbl(l_tmp_i).tare_weight, fnd_api.g_miss_num);
5324 l_lpn_tbl(l_tmp_i).gross_weight_uom_code := NVL(l_lpn_tbl(l_tmp_i).tare_weight_uom_code, fnd_api.g_miss_char);
5325 l_lpn_tbl(l_tmp_i).outermost_lpn_id := l_child_lpn.lpn_id;
5326 l_lpn_tbl(l_tmp_i).lpn_context := LPN_CONTEXT_PREGENERATED;
5327
5328 l_progress := 'Add child LPN to bulk rec to delete contents';
5329 l_tmp_bulk_lpns.lpn_id(NVL(l_tmp_bulk_lpns.lpn_id.last, 0) + 1) := l_child_lpn.lpn_id;
5330 END LOOP;
5331
5332 IF (l_debug = 1) THEN
5333 mdebug('Bulk Delete/Update LPNs in WLC/MSN: '||l_tmp_bulk_lpns.lpn_id.first||'-'||l_tmp_bulk_lpns.lpn_id.last, G_INFO);
5334 END IF;
5335
5336 -- Remove the records for the packed items
5337 FORALL bulk_i IN l_tmp_bulk_lpns.lpn_id.first .. l_tmp_bulk_lpns.lpn_id.last
5338 DELETE FROM wms_lpn_contents
5339 WHERE parent_lpn_id = l_tmp_bulk_lpns.lpn_id(bulk_i);
5340
5341 IF (l_debug = 1) THEN
5342 mdebug('Bulk delete from WLC cnt='||SQL%ROWCOUNT, G_INFO);
5343 END IF;
5344
5345 -- Update the information for serialized packed items
5346 FORALL bulk_i IN l_tmp_bulk_lpns.lpn_id.first .. l_tmp_bulk_lpns.lpn_id.last
5347 UPDATE mtl_serial_numbers
5348 SET last_update_date = SYSDATE
5349 , last_updated_by = fnd_global.user_id
5350 , lpn_id = NULL
5351 WHERE lpn_id = l_tmp_bulk_lpns.lpn_id(bulk_i);
5352
5353 IF (l_debug = 1) THEN
5354 mdebug('Bulk update MSN cnt='||SQL%ROWCOUNT, G_INFO);
5355 END IF;
5356 END IF;
5357
5358 IF ( l_lpn_is_empty = 1 ) THEN
5359 -- bug5404902 added org and item
5360 empty_lpn_rec.organization_id := l_lpn.organization_id;
5361 empty_lpn_rec.inventory_item_id := l_lpn.inventory_item_id;
5362 empty_lpn_rec.lpn_id := l_lpn.lpn_id;
5363 empty_lpn_rec.parent_lpn_id := l_lpn.parent_lpn_id;
5364 empty_lpn_rec.gross_weight := l_lpn.gross_weight;
5365 empty_lpn_rec.gross_weight_uom_code := l_lpn.gross_weight_uom_code;
5366 -- bug5404902 added
5367 empty_lpn_rec.tare_weight := l_lpn.tare_weight;
5368 empty_lpn_rec.tare_weight_uom_code := l_lpn.tare_weight_uom_code;
5369 empty_lpn_rec.container_volume := l_lpn.container_volume;
5370 empty_lpn_rec.container_volume_uom := l_lpn.container_volume_uom;
5371 empty_lpn_rec.content_volume := l_lpn.content_volume;
5372 empty_lpn_rec.content_volume_uom_code := l_lpn.content_volume_uom_code;
5373
5374 -- Since source lpn is being unnested, it may cause parent lpn to be empty and cause a chain reaction
5375 -- or parent LPNs to become pregenerated. Loop through parents until an unempty one is found
5376 LOOP
5377 IF (l_debug = 1) THEN
5378 mdebug('lpn_id='||empty_lpn_rec.lpn_id||' is empty, making pregenerated plpnid='||empty_lpn_rec.parent_lpn_id||' empty='||l_lpn_is_empty, G_MESSAGE);
5379 END IF;
5380
5381 l_tmp_i := NVL(l_lpn_tbl.last, 0) + 1;
5382
5383 -- bug5404902 section for making tare via MSI
5384 IF ( empty_lpn_rec.inventory_item_id IS NOT NULL ) THEN
5385 SELECT unit_weight
5386 , weight_uom_code
5387 INTO l_lpn_tbl(l_tmp_i).tare_weight
5388 , l_lpn_tbl(l_tmp_i).tare_weight_uom_code
5389 FROM mtl_system_items
5390 WHERE organization_id = empty_lpn_rec.organization_id
5391 AND inventory_item_id = empty_lpn_rec.inventory_item_id;
5392 ELSE
5393 -- if there isn't a container item, empty lpns will have undefined
5394 -- tare weight
5395 l_lpn_tbl(l_tmp_i).tare_weight := fnd_api.g_miss_num;
5396 l_lpn_tbl(l_tmp_i).tare_weight_uom_code := fnd_api.g_miss_char;
5397 END IF;
5398
5399 l_lpn_tbl(l_tmp_i).lpn_id := empty_lpn_rec.lpn_id;
5400 l_lpn_tbl(l_tmp_i).subinventory_code := fnd_api.g_miss_char;
5401 l_lpn_tbl(l_tmp_i).locator_id := fnd_api.g_miss_num;
5402 l_lpn_tbl(l_tmp_i).parent_lpn_id := fnd_api.g_miss_num;
5403 l_lpn_tbl(l_tmp_i).content_volume := fnd_api.g_miss_num;
5404 l_lpn_tbl(l_tmp_i).content_volume_uom_code := fnd_api.g_miss_char;
5405 -- bug5404902 changed empty_lpn_rec to l_lpn_tbl(l_tmp_i) since it represents
5406 -- the container items original unit weight
5407 l_lpn_tbl(l_tmp_i).gross_weight := NVL(l_lpn_tbl(l_tmp_i).tare_weight, fnd_api.g_miss_num);
5408 l_lpn_tbl(l_tmp_i).gross_weight_uom_code := NVL(l_lpn_tbl(l_tmp_i).tare_weight_uom_code, fnd_api.g_miss_char);
5409 l_lpn_tbl(l_tmp_i).outermost_lpn_id := empty_lpn_rec.lpn_id;
5410 l_lpn_tbl(l_tmp_i).lpn_context := LPN_CONTEXT_PREGENERATED;
5411
5412 IF ( empty_lpn_rec.parent_lpn_id IS NOT NULL ) THEN
5413 BEGIN
5414 SELECT 0 INTO l_lpn_is_empty
5415 FROM dual
5416 WHERE EXISTS (
5417 -- Check to make sure that the parent lpn has no items in it
5418 SELECT 1 FROM wms_lpn_contents
5419 WHERE organization_id = p_organization_id
5420 AND parent_lpn_id = empty_lpn_rec.parent_lpn_id )
5421 OR EXISTS (
5422 -- Check to make sure that the parent lpn has no lpns in it
5423 -- Ignore the child lpn that will become pregenerated later since
5424 -- we already know it will unpacked from the parent
5425 SELECT 1 FROM wms_license_plate_numbers
5426 WHERE organization_id = p_organization_id
5427 AND parent_lpn_id = empty_lpn_rec.parent_lpn_id
5428 AND lpn_id <> empty_lpn_rec.lpn_id );
5429 EXCEPTION
5430 WHEN NO_DATA_FOUND THEN
5431 l_lpn_is_empty := 1;
5432 END;
5433
5434 -- If lpn has any weight in it, it needs to be decremented from the the parent lpn
5435 IF ( l_lpn_is_empty <> 1 ) THEN
5436 l_progress := 'UPDATE Wt and Vol when making to auto unnest empty LPNs';
5437
5438 l_change_in_gross_weight := -1 * empty_lpn_rec.gross_weight;
5439 l_change_in_gross_weight_uom := empty_lpn_rec.gross_weight_uom_code;
5440 -- bug5404902 added
5441 l_change_in_tare_weight := -1 * empty_lpn_rec.tare_weight;
5442 l_change_in_tare_weight_uom := empty_lpn_rec.tare_weight_uom_code;
5443
5444 -- Need to find if the container of content volume is greater and decrement parent
5445 -- LPNs content volume by that amount
5446 Get_Greater_Qty (
5447 p_debug => l_debug
5448 , p_inventory_item_id => empty_lpn_rec.inventory_item_id
5449 , p_quantity1 => empty_lpn_rec.container_volume
5450 , p_quantity1_uom => empty_lpn_rec.container_volume_uom
5451 , p_quantity2 => empty_lpn_rec.content_volume
5452 , p_quantity2_uom => empty_lpn_rec.content_volume_uom_code
5453 , x_greater_qty => l_change_in_volume
5454 , x_greater_qty_uom => l_change_in_volume_uom );
5455
5456 -- Unpack need change value to negative
5457 l_change_in_volume := -1 * l_change_in_volume;
5458
5459 IF ( nested_parent_cursor%ISOPEN ) THEN
5460 FETCH nested_parent_cursor INTO empty_lpn_rec;
5461 l_wt_vol_new.lpn_id := empty_lpn_rec.lpn_id;
5462 l_wt_vol_new.inventory_item_id := empty_lpn_rec.inventory_item_id;
5463 l_wt_vol_new.gross_weight := empty_lpn_rec.gross_weight;
5464 l_wt_vol_new.gross_weight_uom_code := empty_lpn_rec.gross_weight_uom_code;
5465 l_wt_vol_new.tare_weight := empty_lpn_rec.tare_weight;
5466 l_wt_vol_new.tare_weight_uom_code := empty_lpn_rec.tare_weight_uom_code;
5467 l_wt_vol_new.content_volume := empty_lpn_rec.content_volume;
5468 l_wt_vol_new.content_volume_uom_code := empty_lpn_rec.content_volume_uom_code;
5469 ELSE -- Need to get lpn_information of parent_lpn
5470 SELECT lpn_id
5471 , inventory_item_id
5472 , gross_weight
5473 , gross_weight_uom_code
5474 , tare_weight
5475 , tare_weight_uom_code
5476 , content_volume
5477 , content_volume_uom_code
5478 INTO l_wt_vol_new.lpn_id
5479 , l_wt_vol_new.inventory_item_id
5480 , l_wt_vol_new.gross_weight
5481 , l_wt_vol_new.gross_weight_uom_code
5482 , l_wt_vol_new.tare_weight
5483 , l_wt_vol_new.tare_weight_uom_code
5484 , l_wt_vol_new.content_volume
5485 , l_wt_vol_new.content_volume_uom_code
5486 FROM wms_license_plate_numbers
5487 WHERE lpn_id = empty_lpn_rec.parent_lpn_id;
5488 END IF;
5489 END IF;
5490 END IF;
5491
5492 -- If parent lpn is not empty or doesn't exist, We are at the end.
5493 IF ( empty_lpn_rec.parent_lpn_id IS NULL OR l_lpn_is_empty = 0 ) THEN
5494 EXIT;
5495 ELSIF ( NOT nested_parent_cursor%ISOPEN ) THEN
5496 OPEN nested_parent_cursor(l_lpn.parent_lpn_id);
5497 END IF;
5498
5499 FETCH nested_parent_cursor INTO empty_lpn_rec;
5500 EXIT WHEN nested_parent_cursor%NOTFOUND;
5501 END LOOP;
5502
5503 IF ( nested_parent_cursor%ISOPEN ) THEN
5504 CLOSE nested_parent_cursor;
5505 END IF;
5506 END IF;
5507
5508 IF (l_debug = 1) THEN
5509 mdebug('lpn_id='||l_wt_vol_new.lpn_id||' change_gwt='||l_change_in_gross_weight||' change_gwt_uom='||l_change_in_gross_weight_uom||
5510 ' change_twt='||l_change_in_tare_weight||' change_twt_uom='||l_change_in_tare_weight_uom||' change_vol='||l_change_in_volume||' change_vol_uom='||l_change_in_volume_uom, G_INFO);
5511 END IF;
5512
5513 -- If a item or LPN was packed or unpacked from the parent_lpn (p_lpn). And it
5514 -- had a weight of volume. need to recalculate the weight and volume of the
5515 -- parent LPN
5516 -- bug5404902 add section for tare weight
5517 IF ( (NVL(l_change_in_gross_weight, 0) <> 0 AND l_change_in_gross_weight_uom IS NOT NULL)OR
5518 (NVL(l_change_in_tare_weight, 0) <> 0 AND l_change_in_tare_weight_uom IS NOT NULL)OR
5519 (NVL(l_change_in_volume, 0) <> 0 AND l_change_in_volume_uom IS NOT NULL) )
5520 THEN
5521 l_progress := 'calculate any change in weight and volume';
5522
5523 IF ( NVL(l_change_in_gross_weight, 0) = 0 OR l_change_in_gross_weight_uom IS NULL ) THEN
5524 -- Item/LPN weight not defined, no change in LPN weight
5525 l_wt_vol_new.gross_weight := NULL;
5526 l_wt_vol_new.gross_weight_uom_code := NULL;
5527 ELSIF ( NVL(l_wt_vol_new.gross_weight, 0) = 0 OR l_wt_vol_new.gross_weight_uom_code IS NULL ) THEN
5528 -- LPN has no gross weight, if packing assign total item/LPN weight to gross
5529 -- if unpacking, no change, since weight cannot go negative
5530 IF ( l_change_in_gross_weight > 0 ) THEN
5531 l_wt_vol_new.gross_weight := l_change_in_gross_weight;
5532 l_wt_vol_new.gross_weight_uom_code := l_change_in_gross_weight_uom;
5533 END IF;
5534 ELSIF ( l_wt_vol_new.gross_weight_uom_code = l_change_in_gross_weight_uom ) THEN
5535 -- Same uom, can simply add the two values
5536 l_wt_vol_new.gross_weight := l_wt_vol_new.gross_weight + l_change_in_gross_weight;
5537 ELSE
5538 -- Both are not null but with different UOMs need to convert
5539 -- If cannot covert uom, ignore the change in volume
5540 l_change_in_gross_weight := Convert_UOM(
5541 p_inventory_item_id => l_lpn.inventory_item_id
5542 , p_fm_quantity => l_change_in_gross_weight
5543 , p_fm_uom => l_change_in_gross_weight_uom
5544 , p_to_uom => l_wt_vol_new.gross_weight_uom_code
5545 , p_mode => G_NO_CONV_RETURN_ZERO );
5546
5547 l_wt_vol_new.gross_weight := l_wt_vol_new.gross_weight + l_change_in_gross_weight;
5548 END IF;
5549
5550 IF ( l_wt_vol_new.gross_weight < 0 ) THEN
5551 l_wt_vol_new.gross_weight := 0;
5552 END IF;
5553
5554 -- bug5404902 added section for tare weight
5555 l_progress := 'Calculate changes in tare weight';
5556
5557 IF ( NVL(l_change_in_tare_weight, 0) = 0 OR l_change_in_tare_weight_uom IS NULL ) THEN
5558 -- Child LPN tare weight not defined, no change in tare weight
5559 l_wt_vol_new.tare_weight := NULL;
5560 l_wt_vol_new.tare_weight_uom_code := NULL;
5561 ELSIF ( NVL(l_wt_vol_new.tare_weight, 0) = 0 OR l_wt_vol_new.tare_weight_uom_code IS NULL ) THEN
5562 -- LPN has no tare weight, if packing assign total child LPN tare weight to parent LPN tare
5563 -- if unpacking, no change, since weight cannot go negative
5564 IF ( l_change_in_tare_weight > 0 ) THEN
5565 l_wt_vol_new.tare_weight := l_change_in_tare_weight;
5566 l_wt_vol_new.tare_weight_uom_code := l_change_in_tare_weight_uom;
5567 END IF;
5568 ELSIF ( l_wt_vol_new.tare_weight_uom_code = l_change_in_tare_weight_uom ) THEN
5569 -- Same uom, can simply add the two values
5570 l_wt_vol_new.tare_weight := l_wt_vol_new.tare_weight + l_change_in_tare_weight;
5571 ELSE
5572 -- Both are not null but with different UOMs need to convert
5573 -- If cannot covert uom, ignore the change in volume
5574 l_change_in_tare_weight := Convert_UOM(
5575 p_inventory_item_id => l_lpn.inventory_item_id
5576 , p_fm_quantity => l_change_in_tare_weight
5577 , p_fm_uom => l_change_in_tare_weight_uom
5578 , p_to_uom => l_wt_vol_new.tare_weight_uom_code
5579 , p_mode => G_NO_CONV_RETURN_ZERO );
5580
5581 l_wt_vol_new.tare_weight := l_wt_vol_new.tare_weight + l_change_in_tare_weight;
5582 END IF;
5583
5584 IF ( l_wt_vol_new.tare_weight < 0 ) THEN
5585 l_wt_vol_new.tare_weight := 0;
5586 END IF;
5587
5588 l_progress := 'Calculate changes in volume';
5589
5590 IF ( NVL(l_change_in_volume, 0) = 0 OR l_change_in_volume_uom IS NULL ) THEN
5591 -- Item/LPN volume not defined, no change in LPN volume
5592 l_wt_vol_new.content_volume := NULL;
5593 l_wt_vol_new.content_volume_uom_code := NULL;
5594 ELSIF ( NVL(l_wt_vol_new.content_volume, 0) = 0 OR l_wt_vol_new.content_volume_uom_code IS NULL ) THEN
5595 -- LPN has no content volume, if packing assign total item/LPN volume to gross
5596 -- if unpacking, no change, since volume cannot go negative
5597 IF ( l_change_in_volume > 0 ) THEN
5598 l_wt_vol_new.content_volume := l_change_in_volume;
5599 l_wt_vol_new.content_volume_uom_code := l_change_in_volume_uom;
5600 END IF;
5601 ELSIF ( l_wt_vol_new.content_volume_uom_code = l_change_in_volume_uom ) THEN
5602 -- Same uom, can simply add the two values
5603 l_wt_vol_new.content_volume := l_wt_vol_new.content_volume + l_change_in_volume;
5604 ELSE
5605 -- Both are not null but with different UOMs need to convert
5606 -- If cannot covert uom, ignore the change in volume
5607 l_change_in_volume := Convert_UOM(
5608 p_inventory_item_id => l_lpn.inventory_item_id
5609 , p_fm_quantity => l_change_in_volume
5610 , p_fm_uom => l_change_in_volume_uom
5611 , p_to_uom => l_wt_vol_new.content_volume_uom_code
5612 , p_mode => G_NO_CONV_RETURN_ZERO );
5613
5614 l_wt_vol_new.content_volume := l_wt_vol_new.content_volume + l_change_in_volume;
5615 l_change_in_volume_uom := l_wt_vol_new.content_volume_uom_code;
5616 END IF;
5617
5618 IF ( l_new.content_volume < 0 ) THEN
5619 l_wt_vol_new.content_volume := 0;
5620 END IF;
5621
5622 -- bug5404902 added tare weight
5623 IF ( l_new.lpn_id = l_wt_vol_new.lpn_id ) THEN
5624 l_new.gross_weight := l_wt_vol_new.gross_weight;
5625 l_new.gross_weight_uom_code := l_wt_vol_new.gross_weight_uom_code;
5626 l_new.tare_weight := l_wt_vol_new.tare_weight;
5627 l_new.tare_weight_uom_code := l_wt_vol_new.tare_weight_uom_code;
5628 l_new.content_volume := l_wt_vol_new.content_volume;
5629 l_new.content_volume_uom_code := l_wt_vol_new.content_volume_uom_code;
5630 ELSE -- Not the immediate parent, create a new record
5631 l_tmp_i := NVL(l_lpn_tbl.last, 0) + 1;
5632 l_lpn_tbl(l_tmp_i).lpn_id := l_wt_vol_new.lpn_id;
5633 l_lpn_tbl(l_tmp_i).gross_weight := l_wt_vol_new.gross_weight;
5634 l_lpn_tbl(l_tmp_i).gross_weight_uom_code := l_wt_vol_new.gross_weight_uom_code;
5635 l_lpn_tbl(l_tmp_i).tare_weight := l_wt_vol_new.tare_weight;
5636 l_lpn_tbl(l_tmp_i).tare_weight_uom_code := l_wt_vol_new.tare_weight_uom_code;
5637 l_lpn_tbl(l_tmp_i).content_volume := l_wt_vol_new.content_volume;
5638 l_lpn_tbl(l_tmp_i).content_volume_uom_code := l_wt_vol_new.content_volume_uom_code;
5639 END IF;
5640 END IF;
5641
5642 -- IF both LPNs are picked and doing an unpack, need to update nested LPN structure in WDD
5643 IF ( p_lpn_id IS NOT NULL AND p_content_lpn_id IS NOT NULL AND l_operation_mode = L_UNPACK AND
5644 l_lpn.lpn_context = LPN_CONTEXT_PICKED AND l_content_lpn.lpn_context = LPN_CONTEXT_PICKED )
5645 THEN
5646 IF (l_debug = 1) THEN
5647 mdebug('Call to WSH Delivery_Detail_Action to unpack LPN heirarchy', G_INFO);
5648 END IF;
5649
5650 l_wsh_action_prms.caller := 'WMS';
5651 l_wsh_action_prms.action_code := 'UNPACK';
5652 l_wsh_action_prms.lpn_rec.organization_id := l_lpn.organization_id;
5653 l_wsh_action_prms.lpn_rec.lpn_id := l_lpn.lpn_id;
5654 l_wsh_action_prms.lpn_rec.container_name := l_lpn.license_plate_number;
5655 l_wsh_lpn_id_tbl(1) := p_content_lpn_id;
5656
5657 WSH_WMS_LPN_GRP.Delivery_Detail_Action (
5658 p_api_version_number => 1.0
5659 , p_init_msg_list => fnd_api.g_false
5660 , p_commit => fnd_api.g_false
5661 , x_return_status => x_return_status
5662 , x_msg_count => x_msg_count
5663 , x_msg_data => x_msg_data
5664 , p_lpn_id_tbl => l_wsh_lpn_id_tbl
5665 , p_del_det_id_tbl => l_wsh_del_det_id_tbl
5666 , p_action_prms => l_wsh_action_prms
5667 , x_defaults => l_wsh_defaults
5668 , x_action_out_rec => l_wsh_action_out_rec );
5669
5670 IF (x_return_status <> fnd_api.g_ret_sts_success) THEN
5671 l_progress := 'Delivery_Detail_Action failed';
5672 RAISE fnd_api.g_exc_error;
5673 ELSIF (l_debug = 1) THEN
5674 mdebug('Done with call to WSH Create_Update_Containers', G_INFO);
5675 END IF;
5676 END IF;
5677
5678 -- If there were any changes made to the parent LPN, add this to the lpn table
5679 -- to have WLPN be updated by modify_lpns
5680 IF ( l_new.lpn_id IS NOT NULL ) THEN
5681 l_lpn_tbl(NVL(l_lpn_tbl.last, 0) + 1) := l_new;
5682 END IF;
5683
5684 -- If there were any changes made to the content LPN, add this to the lpn table
5685 -- to have WLPN be updated by modify_lpns
5686 IF ( l_cont_new.lpn_id IS NOT NULL ) THEN
5687 l_lpn_tbl(NVL(l_lpn_tbl.last, 0) + 1) := l_cont_new;
5688 END IF;
5689
5690 -- Call Modify_LPNs API to update WLPN
5691 IF ( l_lpn_tbl.last > 0 ) THEN
5692 IF (l_debug = 1) THEN
5693 mdebug('Call to Modify_LPNs first='||l_lpn_tbl.first||' last='||l_lpn_tbl.last, G_INFO);
5694 END IF;
5695
5696 Modify_LPNs (
5697 p_api_version => 1.0
5698 , p_init_msg_list => fnd_api.g_false
5699 , p_commit => fnd_api.g_false
5700 , x_return_status => x_return_status
5701 , x_msg_count => x_msg_count
5702 , x_msg_data => x_msg_data
5703 , p_caller => 'WMS_PackUnpack_Container'
5704 , p_lpn_table => l_lpn_tbl );
5705
5706 IF (x_return_status <> fnd_api.g_ret_sts_success) THEN
5707 l_progress := 'Modify_LPNs failed';
5708 RAISE fnd_api.g_exc_error;
5709 END IF;
5710 END IF;
5711
5712 -- IF both LPNs are picked then need to update nested LPN structure
5713 IF ( p_lpn_id IS NOT NULL AND p_content_lpn_id IS NOT NULL AND l_operation_mode = L_PACK AND
5714 NVL(l_new.lpn_context, l_lpn.lpn_context) = LPN_CONTEXT_PICKED AND
5715 NVL(l_cont_new.lpn_context, l_content_lpn.lpn_context) = LPN_CONTEXT_PICKED )
5716 THEN
5717 IF (l_debug = 1) THEN
5718 mdebug('Call to WSH Delivery_Detail_Action to pack LPN heirarchy', G_INFO);
5719 END IF;
5720
5721 l_wsh_action_prms.caller := 'WMS';
5722 l_wsh_action_prms.action_code := 'PACK';
5723 l_wsh_action_prms.lpn_rec.organization_id := l_lpn.organization_id;
5724 l_wsh_action_prms.lpn_rec.lpn_id := l_lpn.lpn_id;
5725 l_wsh_action_prms.lpn_rec.container_name := l_lpn.license_plate_number;
5726 l_wsh_lpn_id_tbl(1) := p_content_lpn_id;
5727
5728 WSH_WMS_LPN_GRP.Delivery_Detail_Action (
5729 p_api_version_number => 1.0
5730 , p_init_msg_list => fnd_api.g_false
5731 , p_commit => fnd_api.g_false
5732 , x_return_status => x_return_status
5733 , x_msg_count => x_msg_count
5734 , x_msg_data => x_msg_data
5735 , p_lpn_id_tbl => l_wsh_lpn_id_tbl
5736 , p_del_det_id_tbl => l_wsh_del_det_id_tbl
5737 , p_action_prms => l_wsh_action_prms
5738 , x_defaults => l_wsh_defaults
5739 , x_action_out_rec => l_wsh_action_out_rec );
5740
5741 IF (x_return_status <> fnd_api.g_ret_sts_success) THEN
5742 l_progress := 'Delivery_Detail_Action failed';
5743 RAISE fnd_api.g_exc_error;
5744 ELSIF (l_debug = 1) THEN
5745 mdebug('Done with call to WSH Create_Update_Containers', G_INFO);
5746 END IF;
5747 END IF;
5748
5749 l_progress := 'Inserting record into WLH';
5750 INSERT INTO wms_lpn_histories (
5751 lpn_history_id
5752 , caller
5753 , source_transaction_id
5754 , parent_lpn_id
5755 , parent_license_plate_number
5756 , lpn_id
5757 , license_plate_number
5758 , inventory_item_id
5759 , item_description
5760 , revision
5761 , lot_number
5762 , serial_number
5763 , to_serial_number
5764 , quantity
5765 , uom_code
5766 , organization_id
5767 , subinventory_code
5768 , locator_id
5769 , lpn_context
5770 , status_id
5771 , sealed_status
5772 , operation_mode
5773 , last_update_date
5774 , last_updated_by
5775 , creation_date
5776 , created_by
5777 , cost_group_id
5778 , outermost_lpn_id
5779 , source_type_id
5780 , source_header_id
5781 , source_line_id
5782 , source_line_detail_id
5783 , source_name
5784 , secondary_quantity
5785 , secondary_uom_code
5786 )
5787 VALUES (
5788 WMS_LPN_HISTORIES_S.NEXTVAL
5789 , p_caller
5790 , p_source_transaction_id
5791 , p_lpn_id
5792 , l_lpn.license_plate_number
5793 , p_content_lpn_id
5794 , l_content_lpn.license_plate_number
5795 , p_content_item_id
5796 , p_content_item_desc
5797 , p_revision
5798 , p_lot_number
5799 , p_from_serial_number
5800 , p_to_serial_number
5801 , l_quantity
5802 , p_uom
5803 , p_organization_id
5804 , p_subinventory
5805 , p_locator_id
5806 , NVL(l_new.lpn_context, l_lpn.lpn_context)
5807 , l_lpn.status_id
5808 , l_lpn.sealed_status
5809 , l_operation_mode
5810 , SYSDATE
5811 , fnd_global.user_id
5812 , SYSDATE
5813 , fnd_global.user_id
5814 , p_cost_group_id
5815 , DECODE(l_new.outermost_lpn_id, fnd_api.g_miss_num, NULL, NVL(l_new.outermost_lpn_id, l_lpn.outermost_lpn_id))
5816 , NVL(p_source_type_id, l_lpn.source_type_id)
5817 , NVL(p_source_header_id, l_lpn.source_header_id)
5818 , NVL(p_source_line_id, l_lpn.source_line_id)
5819 , NVL(p_source_line_detail_id, l_lpn.source_line_detail_id)
5820 , NVL(p_source_name, l_lpn.source_name)
5821 , p_sec_quantity --INVCONV kkillams
5822 , p_sec_uom --INVCONV kkillams
5823 );
5824
5825 -- Standard check of p_commit.
5826 IF fnd_api.to_boolean(p_commit) THEN
5827 COMMIT WORK;
5828 END IF;
5829
5830 IF ( l_debug = 1 ) THEN
5831 mdebug(l_api_name||' Exited', 1);
5832 END IF;
5833
5834 fnd_msg_pub.count_and_get(p_count => x_msg_count, p_data => x_msg_data);
5835 EXCEPTION
5836 WHEN FND_API.G_EXC_ERROR THEN
5837 ROLLBACK TO PACKUNPACK_CONTAINER;
5838 x_return_status := fnd_api.g_ret_sts_error;
5839 FND_MSG_PUB.Count_And_Get(p_count => x_msg_count, p_data => x_msg_data);
5840
5841 IF (l_debug = 1) THEN
5842 mdebug(l_api_name ||' Exc err prog='||l_progress||' SQL err: '|| SQLERRM(SQLCODE), 1);
5843 FOR i in 1..x_msg_count LOOP
5844 l_msgdata := substr(l_msgdata||' | '||substr(fnd_msg_pub.get(x_msg_count-i+1, 'F'), 0, 200),1,2000);
5845 END LOOP;
5846 mdebug('msg: '||l_msgdata, 1);
5847 END IF;
5848 WHEN OTHERS THEN
5849 ROLLBACK TO PACKUNPACK_CONTAINER;
5850 x_return_status := fnd_api.g_ret_sts_unexp_error;
5851 FND_MSG_PUB.Count_And_Get(p_count => x_msg_count, p_data => x_msg_data);
5852 IF (l_debug = 1) THEN
5853 mdebug(l_api_name ||' Unexp err prog='||l_progress||' SQL err: '|| SQLERRM(SQLCODE), 1);
5854 END IF;
5855 END PackUnpack_Container;
5856
5857 -- ----------------------------------------------------------------------------------
5858 -- ----------------------------------------------------------------------------------
5859
5860 PROCEDURE Modify_LPN (
5861 p_api_version IN NUMBER
5862 , p_init_msg_list IN VARCHAR2 := fnd_api.g_false
5863 , p_commit IN VARCHAR2 := fnd_api.g_false
5864 , p_validation_level IN NUMBER := fnd_api.g_valid_level_full
5865 , x_return_status OUT NOCOPY VARCHAR2
5866 , x_msg_count OUT NOCOPY NUMBER
5867 , x_msg_data OUT NOCOPY VARCHAR2
5868 , p_lpn IN WMS_CONTAINER_PUB.LPN
5869 , p_caller IN VARCHAR2 := NULL
5870 ) IS
5871 l_api_name CONSTANT VARCHAR2(30) := 'Modify_LPN';
5872 l_api_version CONSTANT NUMBER := 1.0;
5873
5874 l_lpn_table WMS_Data_Type_Definitions_PUB.LPNTableType;
5875
5876 BEGIN
5877
5878 l_lpn_table(1).lpn_id := p_lpn.lpn_id;
5879 l_lpn_table(1).license_plate_number := p_lpn.license_plate_number;
5880 l_lpn_table(1).parent_lpn_id := p_lpn.parent_lpn_id;
5881 l_lpn_table(1).outermost_lpn_id := p_lpn.outermost_lpn_id;
5882 l_lpn_table(1).lpn_context := p_lpn.lpn_context;
5883
5884 l_lpn_table(1).organization_id := p_lpn.organization_id;
5885 l_lpn_table(1).subinventory_code := p_lpn.subinventory_code;
5886 l_lpn_table(1).locator_id := p_lpn.locator_id;
5887
5888 l_lpn_table(1).inventory_item_id := p_lpn.inventory_item_id;
5889 l_lpn_table(1).revision := p_lpn.revision;
5890 l_lpn_table(1).lot_number := p_lpn.lot_number;
5891 l_lpn_table(1).serial_number := p_lpn.serial_number;
5892 l_lpn_table(1).cost_group_id := p_lpn.cost_group_id;
5893
5894 l_lpn_table(1).tare_weight_uom_code := p_lpn.tare_weight_uom_code;
5895 l_lpn_table(1).tare_weight := p_lpn.tare_weight;
5896 l_lpn_table(1).gross_weight_uom_code := p_lpn.gross_weight_uom_code;
5897 l_lpn_table(1).gross_weight := p_lpn.gross_weight;
5898 l_lpn_table(1).container_volume_uom := p_lpn.container_volume_uom;
5899 l_lpn_table(1).container_volume := p_lpn.container_volume;
5900 l_lpn_table(1).content_volume_uom_code := p_lpn.content_volume_uom_code;
5901 l_lpn_table(1).content_volume := p_lpn.content_volume;
5902
5903 l_lpn_table(1).source_type_id := p_lpn.source_type_id;
5904 l_lpn_table(1).source_header_id := p_lpn.source_header_id;
5905 l_lpn_table(1).source_line_id := p_lpn.source_line_id;
5906 l_lpn_table(1).source_line_detail_id := p_lpn.source_line_detail_id;
5907 l_lpn_table(1).source_name := p_lpn.source_name;
5908
5909 l_lpn_table(1).attribute_category := p_lpn.attribute_category;
5910 l_lpn_table(1).attribute1 := p_lpn.attribute1;
5911 l_lpn_table(1).attribute2 := p_lpn.attribute2;
5912 l_lpn_table(1).attribute3 := p_lpn.attribute3;
5913 l_lpn_table(1).attribute4 := p_lpn.attribute4;
5914 l_lpn_table(1).attribute5 := p_lpn.attribute5;
5915 l_lpn_table(1).attribute6 := p_lpn.attribute6;
5916 l_lpn_table(1).attribute7 := p_lpn.attribute7;
5917 l_lpn_table(1).attribute8 := p_lpn.attribute8;
5918 l_lpn_table(1).attribute9 := p_lpn.attribute9;
5919 l_lpn_table(1).attribute10 := p_lpn.attribute10;
5920 l_lpn_table(1).attribute11 := p_lpn.attribute11;
5921 l_lpn_table(1).attribute12 := p_lpn.attribute12;
5922 l_lpn_table(1).attribute13 := p_lpn.attribute13;
5923 l_lpn_table(1).attribute14 := p_lpn.attribute14;
5924 l_lpn_table(1).attribute15 := p_lpn.attribute15;
5925
5926 Modify_LPNs (
5927 p_api_version => p_api_version
5928 , p_init_msg_list => p_init_msg_list
5929 , p_commit => p_commit
5930 , x_return_status => x_return_status
5931 , x_msg_count => x_msg_count
5932 , x_msg_data => x_msg_data
5933 , p_caller => p_caller
5934 , p_lpn_table => l_lpn_table );
5935
5936 END Modify_LPN;
5937
5938 -- ----------------------------------------------------------------------------------
5939 -- ----------------------------------------------------------------------------------
5940
5941 PROCEDURE Modify_LPN_Wrapper(
5942 p_api_version IN NUMBER
5943 , p_init_msg_list IN VARCHAR2 := fnd_api.g_false
5944 , p_commit IN VARCHAR2 := fnd_api.g_false
5945 , p_validation_level IN NUMBER := fnd_api.g_valid_level_full
5946 , x_return_status OUT NOCOPY VARCHAR2
5947 , x_msg_count OUT NOCOPY NUMBER
5948 , x_msg_data OUT NOCOPY VARCHAR2
5949 , p_lpn_id IN NUMBER
5950 , p_license_plate_number IN VARCHAR2 := NULL
5951 , p_inventory_item_id IN NUMBER := NULL
5952 , p_weight_uom_code IN VARCHAR2 := NULL
5953 , p_gross_weight IN NUMBER := NULL
5954 , p_volume_uom_code IN VARCHAR2 := NULL
5955 , p_content_volume IN NUMBER := NULL
5956 , p_status_id IN NUMBER := NULL
5957 , p_lpn_context IN NUMBER := NULL
5958 , p_sealed_status IN NUMBER := NULL
5959 , p_organization_id IN NUMBER := NULL
5960 , p_subinventory IN VARCHAR := NULL
5961 , p_locator_id IN NUMBER := NULL
5962 , p_source_type_id IN NUMBER := NULL
5963 , p_source_header_id IN NUMBER := NULL
5964 , p_source_name IN VARCHAR2 := NULL
5965 , p_source_line_id IN NUMBER := NULL
5966 , p_source_line_detail_id IN NUMBER := NULL
5967 , p_caller IN VARCHAR2 := NULL
5968 ) IS
5969 l_api_name CONSTANT VARCHAR2(30) := 'Modify_LPN_Wrapper';
5970 l_api_version CONSTANT NUMBER := 1.0;
5971 l_debug NUMBER := NVL(FND_PROFILE.VALUE('INV_DEBUG_TRACE'),0);
5972 l_progress VARCHAR2(10) := '0';
5973 l_msgdata VARCHAR2(1000);
5974
5975 l_lpn WMS_Data_Type_Definitions_PUB.LPNTableType;
5976
5977 BEGIN
5978 -- Standard Start of API savepoint
5979 SAVEPOINT MODIFY_LPN_WRAPPER_PVT;
5980
5981 -- Standard call to check for call compatibility.
5982 IF NOT fnd_api.compatible_api_call(l_api_version, p_api_version, l_api_name, g_pkg_name) THEN
5983 fnd_message.set_name('WMS', 'WMS_CONT_INCOMPATIBLE_API_CALL');
5984 fnd_msg_pub.ADD;
5985 RAISE fnd_api.g_exc_unexpected_error;
5986 END IF;
5987
5988 -- Initialize message list if p_init_msg_list is set to TRUE.
5989 IF fnd_api.to_boolean(p_init_msg_list) THEN
5990 fnd_msg_pub.initialize;
5991 END IF;
5992
5993 -- Initialize API return status to success
5994 x_return_status := fnd_api.g_ret_sts_success;
5995
5996 IF (l_debug = 1) THEN
5997 mdebug(l_api_name|| ' Entered '|| g_pkg_version, 1);
5998 END IF;
5999
6000 l_lpn(1).lpn_id := p_lpn_id;
6001 l_lpn(1).license_plate_number := p_license_plate_number;
6002 l_lpn(1).inventory_item_id := p_inventory_item_id;
6003 l_lpn(1).gross_weight_uom_code := p_weight_uom_code;
6004 l_lpn(1).gross_weight := p_gross_weight;
6005 l_lpn(1).content_volume_uom_code := p_volume_uom_code;
6006 l_lpn(1).content_volume := p_content_volume;
6007 --l_lpn(1).status_id := p_status_id;
6008 l_lpn(1).lpn_context := p_lpn_context;
6009 --l_lpn(1).sealed_status := p_sealed_status;
6010 l_lpn(1).organization_id := p_organization_id;
6011 l_lpn(1).subinventory_code := p_subinventory;
6012 l_lpn(1).locator_id := p_locator_id;
6013 l_lpn(1).source_type_id := p_source_type_id;
6014 l_lpn(1).source_header_id := p_source_header_id;
6015 l_lpn(1).source_line_id := p_source_line_id;
6016 l_lpn(1).source_line_detail_id := p_source_line_detail_id;
6017 l_lpn(1).source_name := p_source_name;
6018
6019 l_progress := '100';
6020 Modify_LPNs (
6021 p_api_version => p_api_version
6022 , p_init_msg_list => p_init_msg_list
6023 , p_commit => p_commit
6024 , x_return_status => x_return_status
6025 , x_msg_count => x_msg_count
6026 , x_msg_data => x_msg_data
6027 , p_caller => p_caller
6028 , p_lpn_table => l_lpn );
6029
6030 l_progress := '200';
6031 IF (x_return_status <> fnd_api.g_ret_sts_success) THEN
6032 -- Modify LPN should put the appropriate error message in the stack
6033 RAISE fnd_api.g_exc_error;
6034 END IF;
6035
6036 -- Standard check of p_commit.
6037 IF fnd_api.to_boolean(p_commit) THEN
6038 COMMIT WORK;
6039 END IF;
6040
6041 fnd_msg_pub.count_and_get(p_count => x_msg_count, p_data => x_msg_data);
6042 EXCEPTION
6043 WHEN fnd_api.g_exc_error THEN
6044 ROLLBACK TO MODIFY_LPN_WRAPPER_PVT;
6045 x_return_status := fnd_api.g_ret_sts_error;
6046 fnd_msg_pub.count_and_get(p_count => x_msg_count, p_data => x_msg_data);
6047 WHEN OTHERS THEN
6048 ROLLBACK TO MODIFY_LPN_WRAPPER_PVT;
6049 x_return_status := fnd_api.g_ret_sts_unexp_error;
6050
6051 IF fnd_msg_pub.check_msg_level(fnd_msg_pub.g_msg_lvl_unexp_error) THEN
6052 fnd_msg_pub.add_exc_msg(g_pkg_name, l_api_name);
6053 END IF;
6054
6055 fnd_msg_pub.count_and_get(p_count => x_msg_count, p_data => x_msg_data);
6056 IF (l_debug = 1) THEN
6057 mdebug(l_api_name ||' Error progress= '||l_progress||'SQL error: '|| SQLERRM(SQLCODE), G_ERROR);
6058 END IF;
6059 END Modify_LPN_Wrapper;
6060
6061 -- ----------------------------------------------------------------------------------
6062 -- ----------------------------------------------------------------------------------
6063
6064 PROCEDURE Validate_Update_Wt_Volume (
6065 p_api_version IN NUMBER
6066 , p_init_msg_list IN VARCHAR2 := fnd_api.g_false
6067 , p_commit IN VARCHAR2 := fnd_api.g_false
6068 , x_return_status OUT NOCOPY VARCHAR2
6069 , x_msg_count OUT NOCOPY NUMBER
6070 , x_msg_data OUT NOCOPY VARCHAR2
6071 , p_lpn_id IN NUMBER
6072 , p_content_lpn_id IN VARCHAR2 := NULL
6073 , p_content_item_id IN NUMBER := NULL
6074 , p_quantity IN NUMBER := NULL
6075 , p_uom IN VARCHAR2 := NULL
6076 , p_organization_id IN NUMBER := NULL
6077 , p_enforce_wv_constraints IN NUMBER := 2
6078 , p_operation IN NUMBER
6079 , p_action IN NUMBER
6080 , x_valid_operation OUT NOCOPY NUMBER
6081 ) IS
6082 l_api_name CONSTANT VARCHAR2(30) := 'Validate_Update_Wt_Volume';
6083 l_api_version CONSTANT NUMBER := 1.0;
6084 l_debug NUMBER := NVL(FND_PROFILE.VALUE('INV_DEBUG_TRACE'),0);
6085 l_progress VARCHAR2(10) := '0';
6086
6087 BEGIN
6088 -- Initialize API return status to success
6089 x_return_status := FND_API.G_RET_STS_SUCCESS;
6090
6091 END Validate_Update_Wt_Volume;
6092
6093 -- ----------------------------------------------------------------------------------
6094 -- ----------------------------------------------------------------------------------
6095
6096 PROCEDURE Container_Required_Qty(
6097 p_api_version IN NUMBER
6098 , p_init_msg_list IN VARCHAR2 := fnd_api.g_false
6099 , p_commit IN VARCHAR2 := fnd_api.g_false
6100 , x_return_status OUT NOCOPY VARCHAR2
6101 , x_msg_count OUT NOCOPY NUMBER
6102 , x_msg_data OUT NOCOPY VARCHAR2
6103 , p_source_item_id IN NUMBER
6104 , p_source_qty IN NUMBER
6105 , p_source_qty_uom IN VARCHAR2
6106 , p_qty_per_cont IN NUMBER := NULL
6107 , p_qty_per_cont_uom IN VARCHAR2 := NULL
6108 , p_organization_id IN NUMBER
6109 , p_dest_cont_item_id IN OUT NOCOPY NUMBER
6110 , p_qty_required OUT NOCOPY NUMBER
6111 ) IS
6112 l_api_name CONSTANT VARCHAR2(30) := 'Container_Required_Qty';
6113 l_api_version CONSTANT NUMBER := 1.0;
6114 l_source_item INV_Validate.ITEM;
6115 l_dest_cont_item INV_Validate.ITEM;
6116 l_cont_item INV_Validate.ITEM;
6117 l_org INV_Validate.ORG;
6118 l_result NUMBER;
6119 l_max_load_quantity NUMBER;
6120 l_qty_per_cont NUMBER;
6121 l_curr_min_container NUMBER;
6122 l_curr_min_value NUMBER;
6123 l_curr_load_quantity NUMBER;
6124 l_temp_min_value NUMBER;
6125 l_temp_value NUMBER;
6126 l_temp_load_quantity NUMBER;
6127 CURSOR max_load_cursor IS
6128 SELECT max_load_quantity
6129 FROM WSH_CONTAINER_ITEMS
6130 WHERE master_organization_id = p_organization_id
6131 AND container_item_id = p_dest_cont_item_id
6132 AND load_item_id = p_source_item_id;
6133
6134 CURSOR container_items_cursor IS
6135 SELECT container_item_id, max_load_quantity, preferred_flag
6136 FROM WSH_CONTAINER_ITEMS
6137 WHERE master_organization_id = p_organization_id
6138 AND load_item_id = p_source_item_id
6139 AND container_item_id IN
6140 (SELECT inventory_item_id
6141 FROM MTL_SYSTEM_ITEMS
6142 WHERE mtl_transactions_enabled_flag = 'Y'
6143 AND container_item_flag = 'Y'
6144 AND organization_id = p_organization_id);
6145
6146 l_debug number := NVL(FND_PROFILE.VALUE('INV_DEBUG_TRACE'),0);
6147 BEGIN
6148 -- Standard Start of API savepoint
6149 SAVEPOINT CONTAINER_REQUIRED_QTY_PVT;
6150 -- Standard call to check for call compatibility.
6151 IF NOT FND_API.Compatible_API_Call ( l_api_version ,
6152 p_api_version ,
6153 l_api_name ,
6154 G_PKG_NAME )
6155 THEN
6156 FND_MESSAGE.SET_NAME('WMS', 'WMS_CONT_INCOMPATIBLE_API_CALL');
6157 FND_MSG_PUB.ADD;
6158 RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
6159 END IF;
6160 -- Initialize message list if p_init_msg_list is set to TRUE.
6161 IF FND_API.to_Boolean( p_init_msg_list ) THEN
6162 FND_MSG_PUB.initialize;
6163 END IF;
6164 -- Initialize API return status to success
6165 x_return_status := FND_API.G_RET_STS_SUCCESS;
6166
6167 -- API body
6168
6169 /* Validate Organization ID */
6170 l_org.organization_id := p_organization_id;
6171 l_result := INV_Validate.Organization(l_org);
6172 IF (l_result = INV_Validate.F) THEN
6173 FND_MESSAGE.SET_NAME('WMS', 'WMS_CONT_INVALID_ORG');
6174 FND_MSG_PUB.ADD;
6175 RAISE FND_API.G_EXC_ERROR;
6176 END IF;
6177
6178 /* Validate Source item */
6179 l_source_item.inventory_item_id := p_source_item_id;
6180 l_result := INV_Validate.inventory_item(l_source_item, l_org);
6181 IF (l_result = INV_Validate.F) THEN
6182 FND_MESSAGE.SET_NAME('WMS', 'WMS_CONT_INVALID_ITEM');
6183 FND_MSG_PUB.ADD;
6184 RAISE FND_API.G_EXC_ERROR;
6185 END IF;
6186
6187 /* Validate Source Quantity */
6188 IF ((p_source_qty IS NULL) OR (p_source_qty <= 0)) THEN
6189 FND_MESSAGE.SET_NAME('WMS', 'WMS_CONT_INVALID_SRC_QTY');
6190 FND_MSG_PUB.ADD;
6191 RAISE FND_API.G_EXC_ERROR;
6192 END IF;
6193
6194 /* Validate Source UOM */
6195 l_result := INV_Validate.Uom(p_source_qty_uom, l_org, l_source_item);
6196 IF (l_result = INV_Validate.F) THEN
6197 FND_MESSAGE.SET_NAME('WMS', 'WMS_CONT_INVALID_SRC_UOM');
6198 FND_MSG_PUB.ADD;
6199 RAISE FND_API.G_EXC_ERROR;
6200 END IF;
6201
6202 /* Validate Quantity Per Container */
6203 IF (p_qty_per_cont IS NOT NULL) THEN
6204 IF (p_qty_per_cont <= 0) THEN
6205 FND_MESSAGE.SET_NAME('WMS', 'WMS_CONT_INVLD_QTY_PER_CONT');
6206 FND_MSG_PUB.ADD;
6207 RAISE FND_API.G_EXC_ERROR;
6208 END IF;
6209 END IF;
6210
6211 /* Validate Quantity Per Container UOM */
6212 IF (p_qty_per_cont IS NOT NULL) THEN
6213 l_result := INV_Validate.Uom(p_qty_per_cont_uom, l_org, l_source_item);
6214 IF (l_result = INV_Validate.F) THEN
6215 FND_MESSAGE.SET_NAME('WMS', 'WMS_CONT_INVLD_QTY_PER_UOM');
6216 FND_MSG_PUB.ADD;
6217 RAISE FND_API.G_EXC_ERROR;
6218 END IF;
6219 END IF;
6220
6221 /* Validate Destination container item */
6222 IF (p_dest_cont_item_id IS NOT NULL) THEN
6223 l_dest_cont_item.inventory_item_id := p_dest_cont_item_id;
6224 l_result := INV_Validate.inventory_item(l_dest_cont_item, l_org);
6225 IF (l_result = INV_Validate.F) THEN
6226 FND_MESSAGE.SET_NAME('WMS', 'WMS_CONT_INVALID_CONT_ITEM');
6227 FND_MSG_PUB.ADD;
6228 RAISE FND_API.G_EXC_ERROR;
6229 ELSIF (l_dest_cont_item.container_item_flag = 'N') THEN
6230 FND_MESSAGE.SET_NAME('WMS', 'WMS_CONT_ITEM_NOT_A_CONT');
6231 FND_MSG_PUB.ADD;
6232 RAISE FND_API.G_EXC_ERROR;
6233 END IF;
6234 END IF;
6235 /* End of input validation */
6236
6237 IF (p_dest_cont_item_id IS NOT NULL) THEN
6238 /* Extract or calculate the value of l_max_load_quantity */
6239 OPEN max_load_cursor;
6240 FETCH max_load_cursor INTO l_max_load_quantity;
6241 IF max_load_cursor%NOTFOUND THEN
6242 /* Need to calculate this value based on weight and volume constraints */
6243 -- Check that the source item contains all the physical item information
6244 -- needed for calculation of l_max_load_quantity
6245 IF ((l_source_item.unit_weight IS NULL) OR
6246 (l_source_item.weight_uom_code IS NULL) OR
6247 (l_source_item.unit_volume IS NULL) OR
6248 (l_source_item.volume_uom_code IS NULL)) THEN
6249 FND_MESSAGE.SET_NAME('WMS', 'WMS_CONT_NOT_ENOUGH_INFO');
6250 FND_MSG_PUB.ADD;
6251 RAISE FND_API.G_EXC_ERROR;
6252 END IF;
6253
6254 /* Volume constraint */
6255 l_temp_value := Convert_UOM(
6256 l_source_item.inventory_item_id
6257 , l_source_item.unit_volume
6258 , l_source_item.volume_uom_code
6259 , l_dest_cont_item.volume_uom_code);
6260
6261 IF (l_dest_cont_item.internal_volume IS NOT NULL) THEN
6262 -- Check that the source item's unit volume is less than or
6263 -- equal to the destination container item's internal volume
6264 IF (l_temp_value <= l_dest_cont_item.internal_volume) THEN
6265 l_max_load_quantity := FLOOR(l_dest_cont_item.internal_volume/l_temp_value);
6266 ELSE
6267 FND_MESSAGE.SET_NAME('WMS', 'WMS_CONT_ITEM_TOO_LARGE');
6268 FND_MSG_PUB.ADD;
6269 RAISE FND_API.G_EXC_ERROR;
6270 END IF;
6271 END IF;
6272 /* Weight constraint */
6273 l_temp_value := Convert_UOM(
6274 l_source_item.inventory_item_id
6275 , l_source_item.unit_weight
6276 , l_source_item.weight_uom_code
6277 , l_dest_cont_item.weight_uom_code);
6278
6279 /* Select the most constraining value for l_max_load_quantity */
6280 IF (l_dest_cont_item.maximum_load_weight IS NOT NULL) THEN
6281 -- Check that the source item's unit weight is less than or
6282 -- equal to the destination container item's maximum load weight
6283 IF (l_temp_value <= l_dest_cont_item.maximum_load_weight) THEN
6284 IF (l_max_load_quantity > FLOOR (l_dest_cont_item.maximum_load_weight /
6285 l_temp_value)) THEN
6286 l_max_load_quantity := FLOOR (l_dest_cont_item.maximum_load_weight /
6287 l_temp_value);
6288 END IF;
6289 ELSE
6290 FND_MESSAGE.SET_NAME('WMS', 'WMS_CONT_ITEM_TOO_LARGE');
6291 FND_MSG_PUB.ADD;
6292 RAISE FND_API.G_EXC_ERROR;
6293 END IF;
6294 END IF;
6295 END IF;
6296 CLOSE max_load_cursor;
6297
6298 /* Convert l_max_load_quantity into the same UOM as p_source_qty_uom */
6299 IF (l_max_load_quantity IS NOT NULL) THEN
6300 l_max_load_quantity := Convert_UOM(
6301 l_source_item.inventory_item_id
6302 , l_max_load_quantity
6303 , l_source_item.primary_uom_code
6304 , p_source_qty_uom);
6305 END IF;
6306
6307 /* Calculate the required number of containers needed to store the items */
6308 IF ((p_qty_per_cont IS NOT NULL) AND (l_max_load_quantity IS NOT NULL)) THEN
6309 l_qty_per_cont := Convert_UOM(
6310 l_source_item.inventory_item_id
6311 , p_qty_per_cont
6312 , p_qty_per_cont_uom
6313 , p_source_qty_uom);
6314
6315 IF (l_qty_per_cont > l_max_load_quantity) THEN
6316 FND_MESSAGE.SET_NAME('WMS', 'WMS_CONT_OVERPACKED_OPERATION');
6317 FND_MSG_PUB.ADD;
6318 RAISE FND_API.G_EXC_ERROR;
6319 ELSE
6320 p_qty_required := CEIL(p_source_qty/l_qty_per_cont);
6321 END IF;
6322 ELSIF ((p_qty_per_cont IS NULL) AND (l_max_load_quantity IS NOT NULL)) THEN
6323 p_qty_required := CEIL(p_source_qty/l_max_load_quantity);
6324 ELSE
6325 -- If the destination container item contains no internal volume or maximum
6326 -- load weight restriction values, assume that it has infinite capacity
6327 FND_MESSAGE.SET_NAME('WMS', 'WMS_CONT_NO_RESTRICTIONS_FND');
6328 -- FND_MESSAGE.SHOW;
6329 p_qty_required := 1;
6330 END IF;
6331
6332 ELSE /* No container item was given */
6333 l_curr_min_container := 0;
6334 -- Search through all the containers in WSH_CONTAINER_ITEMS table which can store
6335 -- the given load_item_id
6336 FOR v_container_item IN container_items_cursor LOOP
6337 /* Get the item information for the current container item being considered */
6338 l_cont_item.inventory_item_id := v_container_item.container_item_id;
6339 l_result := INV_Validate.inventory_item(l_cont_item, l_org);
6340 IF (l_result = INV_Validate.F) THEN
6341 FND_MESSAGE.SET_NAME('WMS', 'WMS_CONT_INVALID_CONT_ITEM');
6342 FND_MSG_PUB.ADD;
6343 RAISE FND_API.G_EXC_ERROR;
6344 END IF;
6345
6346 /* Get the max load quantity for that given container */
6347 l_temp_load_quantity := Convert_UOM (
6348 l_source_item.inventory_item_id
6349 , v_container_item.max_load_quantity
6350 , l_source_item.primary_uom_code
6351 , p_source_qty_uom);
6352
6353 -- Calculate the min value, i.e. how much space is empty in the final container
6354 -- used to store the items in units of the source item's uom
6355 l_temp_min_value := l_temp_load_quantity - MOD(p_source_qty, l_temp_load_quantity);
6356
6357 -- If ther preferred container flag is set for this container load relationship
6358 -- Use it reguardless of it's min value
6359 IF ( v_container_item.preferred_flag = 'Y' ) THEN
6360 l_curr_min_container := v_container_item.container_item_id;
6361 l_curr_load_quantity := l_temp_load_quantity;
6362 EXIT;
6363 -- Compare the min value for this container with the best one found so far
6364 ELSIF ((l_curr_min_container = 0) OR (l_temp_min_value < l_curr_min_value)) THEN
6365 l_curr_min_value := l_temp_min_value;
6366 l_curr_min_container := v_container_item.container_item_id;
6367 l_curr_load_quantity := l_temp_load_quantity;
6368 -- If the min values are the same, then choose the container which can hold
6369 -- more of the source item, i.e. has a higher load quantity
6370 ELSIF (l_temp_min_value = l_curr_min_value) THEN
6371 IF (l_temp_load_quantity > l_curr_load_quantity) THEN
6372 l_curr_min_value := l_temp_min_value;
6373 l_curr_min_container := v_container_item.container_item_id;
6374 l_curr_load_quantity := l_temp_load_quantity;
6375 END IF;
6376 END IF;
6377 END LOOP;
6378 /* No containers were found that can store the source item */
6379 IF (l_curr_min_container = 0) THEN
6380 p_qty_required := 0;
6381 FND_MESSAGE.SET_NAME('WMS', 'WMS_CONT_NO_CONTAINER_FOUND');
6382 FND_MSG_PUB.ADD;
6383 RAISE FND_API.G_EXC_ERROR;
6384 ELSE
6385 /* Valid container found. Store this information in the output parameters */
6386 p_dest_cont_item_id := l_curr_min_container;
6387 p_qty_required := CEIL(p_source_qty / l_curr_load_quantity);
6388 END IF;
6389 END IF;
6390 -- End of API body
6391
6392 -- Standard check of p_commit.
6393 IF FND_API.To_Boolean( p_commit ) THEN
6394 COMMIT WORK;
6395 END IF;
6396 -- Standard call to get message count and if count is 1,
6397 -- get message info.
6398 FND_MSG_PUB.Count_And_Get
6399 ( p_count => x_msg_count,
6400 p_data => x_msg_data
6401 );
6402 EXCEPTION
6403 WHEN FND_API.G_EXC_ERROR THEN
6404 ROLLBACK TO CONTAINER_REQUIRED_QTY_PVT;
6405 x_return_status := FND_API.G_RET_STS_ERROR;
6406 FND_MSG_PUB.Count_And_Get
6407 ( p_count => x_msg_count,
6408 p_data => x_msg_data
6409 );
6410 WHEN FND_API.G_EXC_UNEXPECTED_ERROR THEN
6411 ROLLBACK TO CONTAINER_REQUIRED_QTY_PVT;
6412 x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
6413 FND_MSG_PUB.Count_And_Get
6414 ( p_count => x_msg_count,
6415 p_data => x_msg_data
6416 );
6417 WHEN OTHERS THEN
6418 ROLLBACK TO CONTAINER_REQUIRED_QTY_PVT;
6419 x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
6420 IF FND_MSG_PUB.Check_Msg_Level
6421 (FND_MSG_PUB.G_MSG_LVL_UNEXP_ERROR)
6422 THEN
6423 FND_MSG_PUB.Add_Exc_Msg
6424 ( G_PKG_NAME ,
6425 l_api_name
6426 );
6427 END IF;
6428 FND_MSG_PUB.Count_And_Get
6429 ( p_count => x_msg_count,
6430 p_data => x_msg_data
6431 );
6432 END Container_Required_Qty;
6433
6434 -- ----------------------------------------------------------------------------------
6435 -- ----------------------------------------------------------------------------------
6436
6437 PROCEDURE Prepack_LPN_CP (
6438 ERRBUF OUT NOCOPY VARCHAR2
6439 , RETCODE OUT NOCOPY NUMBER
6440 , p_api_version IN NUMBER
6441 , p_organization_id IN NUMBER
6442 , p_subinventory IN VARCHAR2 := NULL
6443 , p_locator_id IN NUMBER := NULL
6444 , p_inventory_item_id IN NUMBER
6445 , p_revision IN VARCHAR2 := NULL
6446 , p_lot_number IN VARCHAR2 := NULL
6447 , p_quantity IN NUMBER
6448 , p_uom IN VARCHAR2
6449 , p_source IN NUMBER
6450 , p_serial_number_from IN VARCHAR2 := NULL
6451 , p_serial_number_to IN VARCHAR2 := NULL
6452 , p_container_item_id IN NUMBER := NULL
6453 , p_cont_revision IN VARCHAR2 := NULL
6454 , p_cont_lot_number IN VARCHAR2 := NULL
6455 , p_cont_serial_number_from IN VARCHAR2 := NULL
6456 , p_cont_serial_number_to IN VARCHAR2 := NULL
6457 , p_lpn_sealed_flag IN NUMBER := NULL
6458 , p_print_label IN NUMBER := NULL
6459 , p_print_content_report IN NUMBER := NULL
6460 , p_packaging_level IN NUMBER := -1
6461 , p_sec_quantity IN NUMBER := NULL --INVCONV kkillams
6462 , p_sec_uom IN VARCHAR2 := NULL --INVCONV kkillams
6463 ) IS
6464 l_api_name CONSTANT VARCHAR2(30) := 'Prepack_LPN_CP';
6465 l_api_version CONSTANT NUMBER := 1.0;
6466
6467 l_result NUMBER;
6468 x_return_status VARCHAR2(4);
6469 x_msg_count NUMBER;
6470 x_msg_data VARCHAR2(300);
6471 ret BOOLEAN;
6472 l_debug number := NVL(FND_PROFILE.VALUE('INV_DEBUG_TRACE'),0);
6473
6474 BEGIN
6475 -- Standard Start of API savepoint
6476 SAVEPOINT PREPACK_LPN_CP_PVT;
6477
6478 -- Standard call to check for call compatibility.
6479 IF NOT fnd_api.compatible_api_call(l_api_version, p_api_version, l_api_name, g_pkg_name) THEN
6480 fnd_message.set_name('WMS', 'WMS_CONT_INCOMPATIBLE_API_CALL');
6481 fnd_msg_pub.ADD;
6482 RAISE fnd_api.g_exc_unexpected_error;
6483 END IF;
6484
6485 -- Initialize API return status to success
6486 x_return_status := fnd_api.g_ret_sts_success;
6487
6488 -- Call Prepack LPN
6489 Prepack_LPN(
6490 p_api_version=> p_api_version,
6491 --p_init_msg_list=> := fnd_api.g_false,
6492 --p_commit=> fnd_api.g_false;,
6493 x_return_status=> x_return_status,
6494 x_msg_count=> x_msg_count,
6495 x_msg_data=> x_msg_data,
6496 p_organization_id=> p_organization_id,
6497 p_subinventory=> p_subinventory,
6498 p_locator_id=> p_locator_id,
6499 p_inventory_item_id=> p_inventory_item_id,
6500 p_revision=> p_revision,
6501 p_lot_number=> p_lot_number,
6502 p_quantity=> p_quantity,
6503 p_uom=> p_uom,
6504 p_source=> p_source,
6505 p_serial_number_from=> p_serial_number_from,
6506 p_serial_number_to=> p_serial_number_to,
6507 p_container_item_id=> p_container_item_id,
6508 p_cont_revision=> p_cont_revision,
6509 p_cont_lot_number=> p_cont_lot_number,
6510 p_cont_serial_number_from=> p_cont_serial_number_from,
6511 p_cont_serial_number_to=> p_cont_serial_number_to,
6512 p_lpn_sealed_flag=> p_lpn_sealed_flag,
6513 p_print_label=> p_print_label,
6514 p_print_content_report=> p_print_content_report,
6515 p_packaging_level=>p_packaging_level,
6516 p_sec_quantity => p_sec_quantity, --INVCONV kkillams
6517 p_sec_uom => p_sec_uom --INVCONV kkillams
6518 );
6519
6520 IF (x_return_status = fnd_api.g_ret_sts_success) THEN
6521 ret := fnd_concurrent.set_completion_status('NORMAL', x_msg_data);
6522 retcode := 0;
6523 ELSE
6524 ret := fnd_concurrent.set_completion_status('ERROR', x_msg_data);
6525 retcode := 2;
6526 errbuf := x_msg_data;
6527 END IF;
6528
6529 -- Standard call to get message count and if count is 1,
6530 -- get message info.
6531 fnd_msg_pub.count_and_get(p_count => x_msg_count, p_data => x_msg_data);
6532 EXCEPTION
6533 WHEN fnd_api.g_exc_error THEN
6534 ROLLBACK TO PREPACK_LPN_CP_PVT;
6535 x_return_status := fnd_api.g_ret_sts_error;
6536 fnd_msg_pub.count_and_get(p_count => x_msg_count, p_data => x_msg_data);
6537 WHEN fnd_api.g_exc_unexpected_error THEN
6538 ROLLBACK TO PREPACK_LPN_CP_PVT;
6539 x_return_status := fnd_api.g_ret_sts_unexp_error;
6540 fnd_msg_pub.count_and_get(p_count => x_msg_count, p_data => x_msg_data);
6541 WHEN OTHERS THEN
6542 ROLLBACK TO PREPACK_LPN_CP_PVT;
6543 x_return_status := fnd_api.g_ret_sts_unexp_error;
6544
6545 IF fnd_msg_pub.check_msg_level(fnd_msg_pub.g_msg_lvl_unexp_error) THEN
6546 fnd_msg_pub.add_exc_msg(g_pkg_name, l_api_name);
6547 END IF;
6548
6549 fnd_msg_pub.count_and_get(p_count => x_msg_count, p_data => x_msg_data);
6550 END prepack_lpn_cp;
6551
6552 -- ----------------------------------------------------------------------------------
6553 -- ----------------------------------------------------------------------------------
6554
6555 PROCEDURE Prepack_LPN(
6556 p_api_version IN NUMBER
6557 , p_init_msg_list IN VARCHAR2 := fnd_api.g_false
6558 , p_commit IN VARCHAR2 := fnd_api.g_false
6559 , x_return_status OUT NOCOPY VARCHAR2
6560 , x_msg_count OUT NOCOPY NUMBER
6561 , x_msg_data OUT NOCOPY VARCHAR2
6562 , p_organization_id IN NUMBER
6563 , p_subinventory IN VARCHAR2 := NULL
6564 , p_locator_id IN NUMBER := NULL
6565 , p_inventory_item_id IN NUMBER
6566 , p_revision IN VARCHAR2 := NULL
6567 , p_lot_number IN VARCHAR2 := NULL
6568 , p_quantity IN NUMBER
6569 , p_uom IN VARCHAR2
6570 , p_source IN NUMBER
6571 , p_serial_number_from IN VARCHAR2 := NULL
6572 , p_serial_number_to IN VARCHAR2 := NULL
6573 , p_container_item_id IN NUMBER := NULL
6574 , p_cont_revision IN VARCHAR2 := NULL
6575 , p_cont_lot_number IN VARCHAR2 := NULL
6576 , p_cont_serial_number_from IN VARCHAR2 := NULL
6577 , p_cont_serial_number_to IN VARCHAR2 := NULL
6578 , p_lpn_sealed_flag IN NUMBER := NULL
6579 , p_print_label IN NUMBER := NULL
6580 , p_print_content_report IN NUMBER := NULL
6581 , p_packaging_level IN NUMBER := -1
6582 , p_sec_quantity IN NUMBER := NULL --INVCONV kkillams
6583 , p_sec_uom IN VARCHAR2 := NULL --INVCONV kkillams
6584 ) IS
6585 l_api_name CONSTANT VARCHAR2(30) := 'Prepack_LPN';
6586 l_api_version CONSTANT NUMBER := 1.0;
6587 l_debug NUMBER := NVL(FND_PROFILE.VALUE('INV_DEBUG_TRACE'),0);
6588 l_progress VARCHAR2(10) := '0';
6589
6590 l_result NUMBER;
6591 l_container_item_id NUMBER := p_container_item_id;
6592 l_max_load_quantity NUMBER;
6593 l_quantity NUMBER;
6594 l_sec_quantity NUMBER; -- INVCONV kkillams
6595 l_primary_quantity NUMBER;
6596 l_lot_number VARCHAR2(30) := p_lot_number;
6597 l_uom VARCHAR(30) := p_uom;
6598 l_lpn_source NUMBER := p_source;
6599 l_sec_pack_quantity NUMBER; -- INVCONV kkillams
6600 l_sec_uom VARCHAR(3); -- INVCONV kkillams
6601 l_pack_quantity NUMBER;
6602 l_lpn_quantity NUMBER;
6603 l_process_id NUMBER;
6604 l_lpn_to_pack NUMBER;
6605 l_lpn_sealed_flag NUMBER := 2;
6606 l_print_label NUMBER := 2;
6607 l_print_content_report NUMBER := 2;
6608 l_serial_number_from VARCHAR2(30) := NULL;
6609 l_serial_number_to VARCHAR2(30) := NULL;
6610 l_serial_suffix_current NUMBER;
6611 l_serial_def_flag BOOLEAN := FALSE;
6612 l_serial_prefix VARCHAR2(30);
6613 l_serial_suffix_from NUMBER;
6614 l_serial_suffix_to NUMBER;
6615 l_serial_qty_btwn NUMBER;
6616 l_serial_suffix_length NUMBER := 0;
6617 temp NUMBER;
6618 l_cont_serial_number_from VARCHAR2(30) := NULL;
6619 l_cont_serial_number_to VARCHAR2(30) := NULL;
6620 l_cont_serial_suffix_current NUMBER;
6621 l_cont_serial_def_flag BOOLEAN := FALSE;
6622 l_cont_serial_prefix VARCHAR2(30);
6623 l_cont_serial_suffix_from NUMBER;
6624 l_cont_serial_suffix_to NUMBER;
6625 l_cont_serial_qty_btwn NUMBER;
6626 l_cont_serial_suffix_length NUMBER := 0;
6627 l_current_serial VARCHAR2(30);
6628 l_lpn_id_out NUMBER;
6629 l_lpn_out VARCHAR2(30);
6630 x_error_code NUMBER;
6631 x_proc_msg VARCHAR2(2000);
6632 x_xml_file VARCHAR2(30);
6633 l_trx_tmp_id NUMBER;
6634 l_trx_header_id NUMBER;
6635 l_ser_trx_id NUMBER := NULL;
6636 l_primary_uom VARCHAR2(4);
6637 l_lot_control_code NUMBER;
6638
6639 l_label_status VARCHAR2(300);
6640 l_input_param_tbl inv_label.input_parameter_rec_type;
6641 l_input_param_rec mtl_material_transactions_temp%ROWTYPE;
6642 l_counter NUMBER := 1; -- Counter variable initialized to 1
6643 l_qty NUMBER := 0;
6644 error_msg VARCHAR2(2000);
6645
6646 CURSOR container_load IS
6647 SELECT max_load_quantity
6648 FROM wsh_container_items
6649 WHERE load_item_id = p_inventory_item_id
6650 AND container_item_id = p_container_item_id
6651 AND master_organization_id = p_organization_id
6652 AND ROWNUM < 2;
6653
6654 CURSOR container_lpn IS
6655 SELECT lpn_id
6656 FROM wms_lpn_process_temp
6657 WHERE process_id = l_process_id;
6658
6659 CURSOR cartonization_cursor IS
6660 SELECT mmtt.cartonization_id,
6661 mmtt.transaction_quantity,
6662 mmtt.primary_quantity,
6663 mmtt.transaction_uom,
6664 mtlt.lot_number,
6665 NVL(msnt1.fm_serial_number, msnt2.fm_serial_number),
6666 NVL(msnt1.to_serial_number, msnt2.to_serial_number)
6667 , mmtt.secondary_transaction_quantity --INVCONV kkillams
6668 , mmtt.secondary_uom_code --INVCONV kkillams
6669 FROM mtl_material_transactions_temp mmtt, mtl_transaction_lots_temp mtlt, mtl_serial_numbers_temp msnt1, mtl_serial_numbers_temp msnt2
6670 WHERE mmtt.organization_id = p_organization_id
6671 AND mmtt.transaction_header_id = l_trx_header_id
6672 AND mtlt.transaction_temp_id(+) = mmtt.transaction_temp_id
6673 AND msnt1.transaction_temp_id(+) = mtlt.serial_transaction_temp_id
6674 AND msnt2.transaction_temp_id(+) = mmtt.transaction_temp_id;
6675
6676 BEGIN
6677 -- Standard Start of API savepoint
6678 SAVEPOINT prepack_lpn_pub;
6679
6680 -- Standard call to check for call compatibility.
6681 IF NOT fnd_api.compatible_api_call(l_api_version, p_api_version, l_api_name, g_pkg_name) THEN
6682 fnd_message.set_name('WMS', 'WMS_CONT_INCOMPATIBLE_API_CALL');
6683 fnd_msg_pub.ADD;
6684 RAISE fnd_api.g_exc_unexpected_error;
6685 END IF;
6686
6687 -- Initialize message list if p_init_msg_list is set to TRUE.
6688 IF fnd_api.to_boolean(p_init_msg_list) THEN
6689 fnd_msg_pub.initialize;
6690 END IF;
6691
6692 -- Initialize API return status to success
6693 --x_return_status := FND_API.G_RET_STS_SUCCESS;
6694
6695 -- API body
6696 IF (l_debug = 1) THEN
6697 mdebug(l_api_name || ' Entered ' || g_pkg_version, 1);
6698 mdebug('orgid=' ||p_organization_id|| ' sub=' ||p_subinventory|| ' loc=' ||p_locator_id|| ' qty=' ||p_quantity|| ' uom=' ||p_uom|| ' src=' ||p_source||' lvl='||p_packaging_level, G_INFO);
6699 mdebug('itemid=' ||p_inventory_item_id|| ' rev=' ||p_revision|| ' lot=' ||p_lot_number|| ' fmsn=' ||p_serial_number_from|| ' tosn=' ||p_serial_number_to, G_INFO);
6700 mdebug('citemid=' ||p_container_item_id|| ' crev=' ||p_cont_revision|| ' clot=' ||p_cont_lot_number|| ' cfmsn=' ||p_cont_serial_number_from|| ' ctosn=' ||p_cont_serial_number_to, G_INFO);
6701 END IF;
6702
6703 -- Find primary UOM for this item
6704 SELECT primary_uom_code, lot_control_code
6705 INTO l_primary_uom, l_lot_control_code
6706 FROM mtl_system_items
6707 WHERE organization_id = p_organization_id
6708 AND inventory_item_id = p_inventory_item_id;
6709
6710 IF ( p_source = LPN_CONTEXT_WIP ) THEN
6711 -- WIP needs a different context for generate lpns than what is given.
6712 l_lpn_source := LPN_PREPACK_FOR_WIP;
6713
6714 -- If lot controlled item in WIP and no lot is given generate a new lot for item
6715 IF ( l_lot_control_code = 2 AND p_lot_number IS NULL ) THEN
6716 l_lot_number := INV_LOT_API_PUB.Auto_Gen_Lot (
6717 p_api_version => 1.0
6718 , x_return_status => x_return_status
6719 , x_msg_count => x_msg_count
6720 , x_msg_data => x_msg_data
6721 , p_org_id => p_organization_id
6722 , p_inventory_item_id => p_inventory_item_id );
6723
6724 IF ( x_error_code <> 0 ) THEN
6725 IF (l_debug = 1) THEN
6726 mdebug('auto_gen_lot failed', G_ERROR);
6727 END IF;
6728 RAISE fnd_api.g_exc_error;
6729 END IF;
6730
6731 IF (l_debug = 1) THEN
6732 mdebug('lot number generated: '|| l_lot_number);
6733 END IF;
6734 END IF;
6735 END IF;
6736
6737 -- If a container item has been specified, find quantity of
6738 -- items that can be contained in each.
6739 IF (p_container_item_id IS NOT NULL) THEN
6740 FOR l_temp_rec IN container_load LOOP
6741 l_max_load_quantity := l_temp_rec.max_load_quantity;
6742 END LOOP;
6743
6744 IF (l_debug = 1) THEN
6745 mdebug('max load qty '|| TO_CHAR(l_max_load_quantity), G_INFO);
6746 END IF;
6747
6748 -- If no item container relationship exists assume container
6749 -- has infinite quanitiy and specify only one LPN, else
6750 -- calculate the number of containers need to prepack items
6751 IF (l_max_load_quantity IS NULL) THEN
6752 /* Generate only one LPN */
6753 l_lpn_quantity := 1;
6754 l_max_load_quantity := p_quantity;
6755 IF (l_debug = 1) THEN
6756 mdebug('Container_Required_Qty default '|| TO_CHAR(l_lpn_quantity), G_INFO);
6757 END IF;
6758 ELSE
6759 /* Calculate number of LPNs required */
6760 Container_Required_Qty(
6761 p_api_version=> 1.0,
6762 p_init_msg_list=> fnd_api.g_false,
6763 p_commit=> fnd_api.g_false,
6764 x_return_status=> x_return_status,
6765 x_msg_count=> x_msg_count,
6766 x_msg_data=> x_msg_data,
6767 p_source_item_id=> p_inventory_item_id,
6768 p_source_qty=> p_quantity,
6769 p_source_qty_uom=> p_uom,
6770 p_organization_id=> p_organization_id,
6771 p_dest_cont_item_id=> l_container_item_id,
6772 p_qty_required=> l_lpn_quantity
6773 );
6774
6775 IF (x_return_status <> fnd_api.g_ret_sts_success) THEN
6776 IF (l_debug = 1) THEN
6777 mdebug('calc lpn failed'|| x_msg_data, G_ERROR);
6778 END IF;
6779 fnd_message.set_name('WMS', 'WMS_CONT_QTY_ERROR');
6780 fnd_msg_pub.ADD;
6781 RAISE fnd_api.g_exc_unexpected_error;
6782 END IF;
6783
6784 IF (l_debug = 1) THEN
6785 mdebug('Container_Required_Qty '|| TO_CHAR(l_lpn_quantity), G_INFO);
6786 END IF;
6787 END IF;
6788
6789 Generate_LPN (
6790 p_api_version => p_api_version
6791 , p_init_msg_list => fnd_api.g_false
6792 , p_commit => fnd_api.g_false
6793 , x_return_status => x_return_status
6794 , x_msg_count => x_msg_count
6795 , x_msg_data => x_msg_data
6796 , p_organization_id => p_organization_id
6797 , p_container_item_id => l_container_item_id
6798 , p_revision => p_cont_revision
6799 , p_lot_number => p_cont_lot_number
6800 , p_from_serial_number => l_cont_serial_number_from
6801 , p_to_serial_number => l_cont_serial_number_to
6802 , p_quantity => l_lpn_quantity
6803 , p_process_id => l_process_id
6804 , p_lpn_id_out => l_lpn_id_out
6805 , p_lpn_out => l_lpn_out
6806 , p_source => l_lpn_source );
6807
6808 IF (x_return_status <> fnd_api.g_ret_sts_success) THEN
6809 IF (l_debug = 1) THEN
6810 mdebug('failed to generate lpn '|| x_msg_data, 1);
6811 END IF;
6812 fnd_message.set_name('WMS', 'WMS_LPN_GENERATION_FAIL');
6813 fnd_msg_pub.ADD;
6814 RAISE fnd_api.g_exc_unexpected_error;
6815 END IF;
6816
6817 IF (l_debug = 1) THEN
6818 mdebug('Process Id '|| TO_CHAR(l_process_id), G_INFO);
6819 END IF;
6820
6821 SELECT COUNT(*)
6822 INTO temp
6823 FROM wms_lpn_process_temp
6824 WHERE process_id = l_process_id;
6825
6826 IF (l_debug = 1) THEN
6827 mdebug('num lpn created: '|| TO_CHAR(temp), G_INFO);
6828 END IF;
6829 ELSE
6830 IF (l_debug = 1) THEN
6831 mdebug(' No container item specified ', G_MESSAGE);
6832 END IF;
6833 -- No container type specified, use cartonization API to find containers
6834 -- Convert transaction quantity to primary quantity
6835 l_primary_quantity := Convert_UOM(p_inventory_item_id, p_quantity, p_uom, l_primary_uom);
6836
6837 IF (l_debug = 1) THEN
6838 mdebug('using cartonization api', G_MESSAGE);
6839 END IF;
6840
6841 SELECT mtl_material_transactions_s.NEXTVAL
6842 INTO l_trx_header_id
6843 FROM DUAL;
6844
6845 IF (l_debug = 1) THEN
6846 mdebug('trx header id for cartonization created: '|| TO_CHAR(l_trx_header_id), G_INFO);
6847 END IF;
6848 x_error_code := inv_trx_util_pub.insert_line_trx(
6849 p_trx_hdr_id=> l_trx_header_id,
6850 p_item_id=> p_inventory_item_id,
6851 p_revision=> p_revision,
6852 p_org_id=> p_organization_id,
6853 p_trx_action_id=> inv_globals.g_action_containerpack,
6854 p_subinv_code=> p_subinventory,
6855 p_tosubinv_code=> NULL,
6856 p_locator_id=> p_locator_id,
6857 p_tolocator_id=> NULL,
6858 p_xfr_org_id=> NULL,
6859 p_trx_type_id=> inv_globals.g_type_container_pack,
6860 p_trx_src_type_id=> inv_globals.g_sourcetype_inventory,
6861 p_trx_qty=> p_quantity,
6862 p_pri_qty=> l_primary_quantity,
6863 p_uom=> p_uom,
6864 p_date=> SYSDATE,
6865 p_reason_id=> NULL,
6866 p_user_id=> fnd_global.user_id,
6867 p_frt_code=> NULL,
6868 p_ship_num=> NULL,
6869 p_dist_id=> NULL,
6870 p_way_bill=> NULL,
6871 p_exp_arr=> NULL,
6872 p_cost_group=> NULL,
6873 p_from_lpn_id=> NULL,
6874 p_cnt_lpn_id=> NULL,
6875 --p_xfr_lpn_id => l_lpn_to_pack,
6876 x_trx_tmp_id=> l_trx_tmp_id,
6877 x_proc_msg=> x_proc_msg,
6878 p_secondary_trx_qty =>p_sec_quantity, --INVCONV kkillams
6879 p_secondary_uom =>p_sec_uom --INVCONV kkillams
6880 );
6881
6882 IF (x_error_code <> 0) THEN
6883 IF (l_debug = 1) THEN
6884 mdebug('failed INSERT_LINE_TRX '|| x_error_code, 1);
6885 mdebug('error msg: '|| x_proc_msg, 1);
6886 END IF;
6887 fnd_message.set_name('WMS', 'WMS_INSERT_LINE_TRX_FAIL');
6888 fnd_msg_pub.ADD;
6889 RAISE fnd_api.g_exc_unexpected_error;
6890 END IF;
6891
6892 IF (l_debug = 1) THEN
6893 mdebug('trx temp id created: '|| TO_CHAR(l_trx_tmp_id), G_INFO);
6894 END IF;
6895
6896 IF ( x_error_code = 0 AND l_lot_number IS NOT NULL ) THEN
6897 IF (l_debug = 1) THEN
6898 mdebug('Insert lot entry in MTL_LOT_NUMBER_TEMP lot='|| l_lot_number, G_INFO);
6899 END IF;
6900 x_error_code := inv_trx_util_pub.insert_lot_trx(
6901 p_trx_tmp_id=> l_trx_tmp_id,
6902 p_user_id=> fnd_global.user_id,
6903 p_lot_number=> l_lot_number,
6904 p_trx_qty=> p_quantity,
6905 p_pri_qty=> l_primary_quantity,
6906 p_secondary_qty =>p_sec_quantity, --INVCONV kkillams
6907 p_secondary_uom =>p_sec_uom, --INVCONV kkillams
6908 x_ser_trx_id=> l_ser_trx_id,
6909 x_proc_msg=> x_proc_msg
6910 );
6911
6912 IF (x_error_code <> 0) THEN
6913 IF (l_debug = 1) THEN
6914 mdebug('failed INSERT_LOT_TRX lot='||l_lot_number||' '||x_error_code, G_ERROR);
6915 mdebug('error msg: '|| x_proc_msg, G_ERROR);
6916 END IF;
6917 fnd_message.set_name('WMS', 'WMS_INSERT_LOT_TRX_FAIL');
6918 fnd_msg_pub.ADD;
6919 RAISE fnd_api.g_exc_unexpected_error;
6920 END IF;
6921 END IF;
6922
6923 IF ( x_error_code = 0 AND l_serial_number_from IS NOT NULL ) THEN
6924 IF (l_ser_trx_id IS NOT NULL) THEN
6925 l_trx_tmp_id := l_ser_trx_id;
6926 END IF;
6927
6928 IF (l_debug = 1) THEN
6929 mdebug('inserting serials '|| l_serial_number_from || '-' || l_serial_number_to || ' into mmtt', G_INFO);
6930 mdebug('with l_trx_tmp_id='|| l_trx_tmp_id, G_INFO);
6931 END IF;
6932 --Insert serials into MTL_SERIAL_NUMBERS_TEMP
6933 x_error_code := inv_trx_util_pub.insert_ser_trx(
6934 p_trx_tmp_id=> l_trx_tmp_id,
6935 p_user_id=> fnd_global.user_id,
6936 p_fm_ser_num=> l_serial_number_from,
6937 p_to_ser_num=> l_serial_number_to,
6938 x_proc_msg=> x_proc_msg
6939 );
6940
6941 IF (x_error_code <> 0) THEN
6942 IF (l_debug = 1) THEN
6943 mdebug('failed INSERT_SER_TRX '|| x_error_code, G_ERROR);
6944 mdebug('error msg: '|| x_proc_msg, G_ERROR);
6945 END IF;
6946 fnd_message.set_name('WMS', 'WMS_INSERT_SER_TRX_FAIL');
6947 fnd_msg_pub.ADD;
6948 RAISE fnd_api.g_exc_unexpected_error;
6949 END IF;
6950 END IF;
6951
6952 IF (l_debug = 1) THEN
6953 mdebug('Calling cartonization', 9);
6954 END IF;
6955
6956 WMS_CARTNZN_WRAP.Cartonize (
6957 p_api_version => 1.0
6958 , p_init_msg_list => fnd_api.g_false
6959 , p_commit => fnd_api.g_false
6960 , x_return_status => x_return_status
6961 , x_msg_count => x_msg_count
6962 , x_msg_data => x_msg_data
6963 , p_org_id => p_organization_id
6964 , p_transaction_header_id => l_trx_header_id
6965 , p_stop_level => p_packaging_level
6966 , p_packaging_mode => WMS_CARTNZN_WRAP.PREPACK_PKG_MODE );
6967
6968 IF (x_return_status = fnd_api.g_ret_sts_error) THEN
6969 IF (l_debug = 1) THEN
6970 mdebug('Error in calling Cartonization'|| x_msg_data, 1);
6971 END IF;
6972 RAISE fnd_api.g_exc_error;
6973 ELSIF (x_return_status = fnd_api.g_ret_sts_unexp_error) THEN
6974 IF (l_debug = 1) THEN
6975 mdebug('Unexpectied error in calling Cartonization'|| x_msg_data, 1);
6976 END IF;
6977 RAISE fnd_api.g_exc_unexpected_error;
6978 ELSIF (x_return_status <> fnd_api.g_ret_sts_success) THEN
6979 IF (l_debug = 1) THEN
6980 mdebug('Undefined error in calling Cartonization'|| x_msg_data, 1);
6981 END IF;
6982 RAISE fnd_api.g_exc_unexpected_error;
6983 END IF;
6984
6985 IF (l_debug = 1) THEN
6986 mdebug('cartonization api done');
6987 END IF;
6988 -- Cartonization does label printing disable pack label printing
6989 l_print_label := 2;
6990
6991 -- Generate a process ID number to to insert LPNs into process temp table
6992 SELECT wms_lpn_process_temp_s.NEXTVAL
6993 INTO l_process_id
6994 FROM DUAL;
6995
6996 IF (l_debug = 1) THEN
6997 mdebug('created process id: '|| l_process_id, G_INFO);
6998 END IF;
6999 END IF;
7000
7001 --Could be useful later
7002 /*IF ( l_container_item.serial_number_control_code = 2 AND p_source IN (2,3) ) THEN
7003 -- Serials need to be dymanically generated for LPNs
7004 x_error_code := INV_SERIAL_NUMBER_PUB.GENERATE_SERIALS
7005 (p_org_id => p_organization_id,
7006 p_item_id => p_container_item_id,
7007 p_qty => l_lpn_quantity,
7008 p_wip_id => NULL,
7009 p_rev => p_cont_revision,
7010 p_lot => p_cont_lot_number,
7011 x_start_ser => l_cont_serial_number_from,
7012 x_end_ser => l_cont_serial_number_to,
7013 x_proc_msg => x_msg_data);
7014
7015 IF x_error_code <> 0 THEN
7016 IF (l_debug = 1) THEN
7017 mdebug('failed genreate serials ' || TO_CHAR(x_error_code));
7018 END IF;
7019 FND_MESSAGE.SET_NAME('WMS', 'WMS_CONT_INVALID_SER');
7020 FND_MSG_PUB.ADD;
7021 RAISE FND_API.G_EXC_ERROR;
7022 ELSE
7023 IF (l_debug = 1) THEN
7024 mdebug('genreated serials ' || l_cont_serial_number_from || ' - ' || l_cont_serial_number_to);
7025 END IF;
7026 END IF;
7027 END IF;*/
7028
7029 -- put total quantity into temp variable
7030 l_quantity := p_quantity;
7031 l_sec_quantity := p_sec_quantity; --INVCONV kkillams
7032
7033 IF l_serial_def_flag THEN
7034 l_serial_suffix_current := l_serial_suffix_from - 1;
7035 ELSE
7036 l_serial_number_from := NULL;
7037 l_serial_number_to := NULL;
7038 END IF;
7039
7040 -- Open Cursor
7041 IF (p_container_item_id IS NULL) THEN
7042 OPEN cartonization_cursor;
7043 ELSE
7044 OPEN container_lpn;
7045 END IF;
7046
7047 -- Pack and Change Context of LPN
7048 --FOR container_rec IN container_lpn
7049 LOOP
7050 IF (p_container_item_id IS NULL) THEN
7051 FETCH cartonization_cursor INTO l_lpn_to_pack, l_pack_quantity, l_primary_quantity,
7052 l_uom, l_lot_number, l_serial_number_from, l_serial_number_to,
7053 l_sec_pack_quantity,l_sec_uom; --INVCONV kkillams
7054 EXIT WHEN cartonization_cursor%NOTFOUND;
7055
7056 -- Cartonization created LPNs, lpn_context must be set before packing
7057 IF (l_debug = 1) THEN
7058 mdebug('setting lpn id= ' || l_lpn_to_pack || ' to context ' || l_lpn_source, G_INFO);
7059 END IF;
7060 -- Bug5659809: update last_update_date and last_update_by as well
7061 UPDATE wms_license_plate_numbers
7062 SET lpn_context = l_lpn_source
7063 , last_update_date = SYSDATE
7064 , last_updated_by = fnd_global.user_id
7065 WHERE lpn_id = l_lpn_to_pack;
7066 ELSE
7067 FETCH container_lpn INTO l_lpn_to_pack;
7068 EXIT WHEN container_lpn%NOTFOUND;
7069
7070 -- Pack the lesser of the maximum container load or remaining item quantity
7071 IF l_quantity < l_max_load_quantity THEN
7072 l_pack_quantity := l_quantity;
7073 l_sec_pack_quantity := l_sec_quantity; -- INVCONV kkillams
7074 ELSE
7075 l_pack_quantity := l_max_load_quantity;
7076 l_sec_pack_quantity := inv_convert.inv_um_convert(p_inventory_item_id,
7077 g_precision,
7078 l_max_load_quantity,
7079 p_uom,
7080 p_sec_uom,
7081 NULL,
7082 NULL); --INVCONV KKILLAMS
7083 l_quantity := l_quantity - l_max_load_quantity;
7084 END IF;
7085
7086 -- Not using cartonization. Need to convert pack quantity to a primary quantity
7087 l_primary_quantity := Convert_UOM(p_inventory_item_id, l_pack_quantity, p_uom, l_primary_uom);
7088
7089 -- set next group of serials to be packed.
7090 IF l_serial_def_flag THEN
7091 l_serial_suffix_from := l_serial_suffix_current + 1;
7092 --l_serial_suffix_current := l_serial_suffix_current + least(l_max_load_quantity, l_quantity);
7093 l_serial_suffix_current := l_serial_suffix_current + l_primary_quantity;
7094 l_serial_number_from := l_serial_prefix || LPAD(TO_CHAR(l_serial_suffix_from), l_serial_suffix_length, '0');
7095 l_serial_number_to := l_serial_prefix || LPAD(TO_CHAR(l_serial_suffix_current), l_serial_suffix_length, '0');
7096 END IF;
7097 END IF;
7098
7099 IF (l_lpn_to_pack IS NULL) THEN
7100 IF (l_debug = 1) THEN
7101 mdebug('cartonize failed: No LPN Specified in row', G_ERROR);
7102 END IF;
7103 fnd_message.set_name('WMS', 'WMS_CARTONIZE_ERROR');
7104 fnd_msg_pub.ADD;
7105 --COMMIT;
7106 RAISE fnd_api.g_exc_unexpected_error;
7107 END IF;
7108
7109 IF (l_debug = 1) THEN
7110 mdebug('packing lpn='|| l_lpn_to_pack || ' with qty=' || l_primary_quantity || ' ' ||l_primary_uom);
7111 mdebug('with lot='|| l_lot_number || ' serials=' || l_serial_number_from || '-' || l_serial_number_to);
7112 END IF;
7113
7114 --If an invenotory prepack, insert trx in mtl_material_transactions_temp table
7115 IF (p_source = 1) THEN
7116 -- if inventory prepack, trx header id required
7117 SELECT mtl_material_transactions_s.NEXTVAL
7118 INTO l_trx_header_id
7119 FROM DUAL;
7120
7121 IF (l_debug = 1) THEN
7122 mdebug('trx header id created: '|| TO_CHAR(l_trx_header_id), G_INFO);
7123 END IF;
7124
7125 IF (l_debug = 1) THEN
7126 mdebug('packing lpn: '|| TO_CHAR(l_lpn_to_pack) || ' with qty ' || TO_CHAR(l_primary_quantity));
7127 END IF;
7128 x_error_code := inv_trx_util_pub.insert_line_trx(
7129 p_trx_hdr_id=> l_trx_header_id,
7130 p_item_id=> p_inventory_item_id,
7131 p_revision=> p_revision,
7132 p_org_id=> p_organization_id,
7133 p_trx_action_id=> inv_globals.g_action_containerpack,
7134 p_subinv_code=> p_subinventory,
7135 p_tosubinv_code=> NULL,
7136 p_locator_id=> p_locator_id,
7137 p_tolocator_id=> NULL,
7138 p_xfr_org_id=> NULL,
7139 p_trx_type_id=> inv_globals.g_type_container_pack,
7140 p_trx_src_type_id=> inv_globals.g_sourcetype_inventory,
7141 p_trx_qty=> l_pack_quantity,
7142 p_pri_qty=> l_primary_quantity,
7143 p_uom=> l_primary_uom,
7144 p_date=> SYSDATE,
7145 p_reason_id=> NULL,
7146 p_user_id=> fnd_global.user_id,
7147 p_frt_code=> NULL,
7148 p_ship_num=> NULL,
7149 p_dist_id=> NULL,
7150 p_way_bill=> NULL,
7151 p_exp_arr=> NULL,
7152 p_cost_group=> NULL,
7153 p_from_lpn_id=> NULL,
7154 p_cnt_lpn_id=> NULL,
7155 p_xfr_lpn_id=> l_lpn_to_pack,
7156 x_trx_tmp_id=> l_trx_tmp_id,
7157 x_proc_msg=> x_proc_msg,
7158 p_secondary_trx_qty =>l_sec_pack_quantity, --INVCONV kkillams
7159 p_secondary_uom =>l_sec_uom --INVCONV kkillams
7160 );
7161
7162 IF (x_error_code <> 0) THEN
7163 IF (l_debug = 1) THEN
7164 mdebug('failed INSERT_LINE_TRX '|| x_error_code, G_ERROR);
7165 mdebug('error msg: '|| x_proc_msg, 1);
7166 END IF;
7167 fnd_message.set_name('WMS', 'WMS_INSERT_LINE_TRX_FAIL');
7168 fnd_msg_pub.ADD;
7169 RAISE fnd_api.g_exc_unexpected_error;
7170 END IF;
7171
7172 IF (l_debug = 1) THEN
7173 mdebug('trx temp id created: '|| TO_CHAR(l_trx_tmp_id), G_INFO);
7174 END IF;
7175
7176 IF ( x_error_code = 0 AND l_lot_number IS NOT NULL ) THEN
7177 IF (l_debug = 1) THEN
7178 mdebug('Insert lot entry in MTL_LOT_NUMBER_TEMP lot='|| l_lot_number, G_INFO);
7179 END IF;
7180 x_error_code := inv_trx_util_pub.insert_lot_trx(
7181 p_trx_tmp_id=> l_trx_tmp_id,
7182 p_user_id=> fnd_global.user_id,
7183 p_lot_number=> l_lot_number,
7184 p_trx_qty=> l_primary_quantity,
7185 p_pri_qty=> l_primary_quantity,
7186 p_secondary_qty => l_sec_pack_quantity, --INVCONV kkillams
7187 p_secondary_uom =>l_sec_uom, --INVCONV kkillams
7188 x_ser_trx_id=> l_ser_trx_id,
7189 x_proc_msg=> x_proc_msg
7190 );
7191
7192 IF (x_error_code <> 0) THEN
7193 IF (l_debug = 1) THEN
7194 mdebug('failed INSERT_LOT_TRX '|| x_error_code, 1);
7195 mdebug('error msg: '|| x_proc_msg, 1);
7196 END IF;
7197 fnd_message.set_name('WMS', 'WMS_INSERT_LOT_TRX_FAIL');
7198 fnd_msg_pub.ADD;
7199 RAISE fnd_api.g_exc_unexpected_error;
7200 END IF;
7201 END IF;
7202
7203 IF ( x_error_code = 0 AND l_serial_number_from IS NOT NULL ) THEN
7204 IF (l_ser_trx_id IS NOT NULL) THEN
7205 l_trx_tmp_id := l_ser_trx_id;
7206 END IF;
7207 IF (l_debug = 1) THEN
7208 mdebug('inserting serials '|| l_serial_number_from || '-' || l_serial_number_to || ' into mmtt', G_INFO);
7209 mdebug('with l_trx_tmp_id='|| l_trx_tmp_id, G_INFO);
7210 END IF;
7211 x_error_code := inv_trx_util_pub.insert_ser_trx(
7212 p_trx_tmp_id=> l_trx_tmp_id,
7213 p_user_id=> fnd_global.user_id,
7214 p_fm_ser_num=> l_serial_number_from,
7215 p_to_ser_num=> l_serial_number_to,
7216 x_proc_msg=> x_proc_msg
7217 );
7218
7219 IF (x_error_code <> 0) THEN
7220 IF (l_debug = 1) THEN
7221 mdebug('failed INSERT_SER_TRX '|| x_error_code, 1);
7222 mdebug('error msg: '|| x_proc_msg, 1);
7223 END IF;
7224 fnd_message.set_name('WMS', 'WMS_INSERT_SER_TRX_FAIL');
7225 fnd_msg_pub.ADD;
7226 RAISE fnd_api.g_exc_unexpected_error;
7227 END IF;
7228 END IF;
7229
7230 --Call LPN Transaction API
7231 IF (l_debug = 1) THEN
7232 mdebug('calling process lpn trx');
7233 END IF;
7234 x_error_code := inv_lpn_trx_pub.process_lpn_trx(p_trx_hdr_id => l_trx_header_id, p_commit => fnd_api.g_false, x_proc_msg => error_msg, p_business_flow_code => 20);
7235
7236 IF (x_error_code <> 0) THEN
7237 IF (l_debug = 1) THEN
7238 mdebug('failed PROCESS_LPN_TRX '|| x_error_code, 1);
7239 mdebug('error msg: '|| error_msg, G_ERROR);
7240 END IF;
7241 fnd_message.set_name('WMS', 'WMS_PROCESS_LPN_TRX_FAIL');
7242 fnd_msg_pub.ADD;
7243 RAISE fnd_api.g_exc_unexpected_error;
7244 END IF;
7245
7246 IF (l_debug = 1) THEN
7247 mdebug('Packed LPN_ID '|| TO_CHAR(l_lpn_to_pack), G_INFO);
7248 END IF;
7249 ELSE --Source is WIP or Rec do pack w/o trx manager
7250 IF (l_debug = 1) THEN
7251 mdebug('packing lpn: '|| l_lpn_to_pack || ' with qty ' || l_primary_quantity ||' '|| l_primary_uom, G_INFO);
7252 END IF;
7253
7254 PackUnpack_Container(
7255 p_api_version=> 1.0,
7256 p_init_msg_list=> fnd_api.g_false,
7257 p_commit=> fnd_api.g_false,
7258 p_validation_level=> fnd_api.g_valid_level_none,
7259 x_return_status=> x_return_status,
7260 x_msg_count=> x_msg_count,
7261 x_msg_data=> x_msg_data,
7262 p_lpn_id=> l_lpn_to_pack,
7263 p_content_item_id=> p_inventory_item_id,
7264 p_revision=> p_revision,
7265 p_lot_number=> l_lot_number,
7266 p_from_serial_number=> l_serial_number_from,
7267 p_to_serial_number=> l_serial_number_to,
7268 p_quantity=> l_primary_quantity,
7269 p_uom=> l_primary_uom,
7270 p_organization_id=> p_organization_id,
7271 p_operation=> 1 );
7272
7273 IF (x_return_status <> fnd_api.g_ret_sts_success) THEN
7274 IF (l_debug = 1) THEN
7275 mdebug('failed to pack lpn: '|| TO_CHAR(l_lpn_to_pack), G_ERROR);
7276 END IF;
7277 fnd_message.set_name('WMS', 'WMS_PACK_CONTAINER_FAIL');
7278 fnd_message.set_token('lpn', TO_CHAR(l_lpn_to_pack));
7279 fnd_msg_pub.ADD;
7280 --RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
7281 ELSE
7282 IF (l_debug = 1) THEN
7283 mdebug('packed lpn: '|| l_lpn_to_pack || ' with qty ' || l_primary_quantity, G_INFO);
7284 END IF;
7285 END IF;
7286 END IF;
7287
7288 IF (p_container_item_id IS NULL) THEN
7289 -- Insert the LPN created into the WMS_LPN_PROCESS_TEMP table
7290 IF (l_debug = 1) THEN
7291 mdebug('making insert to temp table', G_MESSAGE);
7292 END IF;
7293 INSERT INTO wms_lpn_process_temp ( process_id, lpn_id )
7294 VALUES ( l_process_id, l_lpn_to_pack);
7295 ELSE
7296 --Not through cartonization, need to insert Row for label printing
7297 l_input_param_rec.lpn_id := l_lpn_to_pack;
7298 l_input_param_tbl(l_counter) := l_input_param_rec;
7299 l_counter := l_counter + 1;
7300 END IF;
7301
7302 IF (l_lpn_sealed_flag = 1) THEN
7303 IF (l_debug = 1) THEN
7304 mdebug('Sealing LPN', G_MESSAGE);
7305 END IF;
7306 modify_lpn_wrapper(
7307 p_api_version=> 1.0,
7308 p_init_msg_list=> fnd_api.g_false,
7309 p_commit=> fnd_api.g_false,
7310 x_return_status=> x_return_status,
7311 x_msg_count=> x_msg_count,
7312 x_msg_data=> x_msg_data,
7313 p_lpn_id=> l_lpn_to_pack,
7314 p_sealed_status=> 1 );
7315
7316 IF (x_return_status <> fnd_api.g_ret_sts_success) THEN
7317 IF (l_debug = 1) THEN
7318 mdebug('failed to seal lpn: '|| TO_CHAR(l_lpn_to_pack), G_ERROR);
7319 END IF;
7320 fnd_message.set_name('WMS', 'WMS_PACK_CONTAINER_FAIL');
7321 fnd_msg_pub.ADD;
7322 RAISE fnd_api.g_exc_unexpected_error;
7323 END IF;
7324 END IF;
7325 END LOOP;
7326
7327 IF (l_debug = 1) THEN
7328 mdebug('done with loop', G_MESSAGE);
7329 END IF;
7330
7331 -- Label printing call with cartonization flow must be made if cartonization was used
7332 IF (p_container_item_id IS NULL) THEN
7333 inv_label.print_label (
7334 x_return_status => x_return_status
7335 , x_msg_count => x_msg_count
7336 , x_msg_data => x_msg_data
7337 , x_label_status => l_label_status
7338 , p_api_version => 1.0
7339 , p_print_mode => 1
7340 , p_business_flow_code => 22
7341 , p_transaction_id => WMS_CARTNZN_WRAP.get_lpns_generated_tb);
7342
7343 IF (x_return_status <> fnd_api.g_ret_sts_success) THEN
7344 IF (l_debug = 1) THEN
7345 mdebug('**Error in Cartonization Label Printing :'||x_return_status,1);
7346 END IF;
7347 RAISE FND_API.G_EXC_ERROR;
7348 END if;
7349 END IF;
7350
7351 IF (l_print_label = 1) THEN
7352 -- Print LPN Labels
7353 IF (l_debug = 1) THEN
7354 mdebug('Calling Print label api');
7355 END IF;
7356 inv_label.print_label(
7357 x_return_status=> x_return_status,
7358 x_msg_count=> x_msg_count,
7359 x_msg_data=> x_msg_data,
7360 x_label_status=> l_label_status,
7361 p_api_version=> 1.0,
7362 p_print_mode=> 2,
7363 p_business_flow_code=> 20,
7364 p_input_param_rec=> l_input_param_tbl
7365 );
7366
7367 IF (x_return_status <> fnd_api.g_ret_sts_success) THEN
7368 IF (l_debug = 1) THEN
7369 mdebug('failed to print labels', 1);
7370 END IF;
7371 fnd_message.set_name('WMS', 'WMS_PRINT_LABEL_FAIL');
7372 fnd_msg_pub.ADD;
7373 --RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
7374 END IF;
7375 END IF;
7376
7377 -- Close cursor
7378 IF (p_container_item_id IS NULL) THEN
7379 CLOSE cartonization_cursor;
7380 ELSE
7381 CLOSE container_lpn;
7382 END IF;
7383
7384 -- Delete lpn entries from temp table
7385 DELETE FROM wms_lpn_process_temp
7386 WHERE process_id = l_process_id;
7387
7388 -- Delete lpn entries from temp table
7389 IF (p_container_item_id IS NULL) THEN
7390 DELETE FROM mtl_material_transactions_temp
7391 WHERE transaction_header_id = l_trx_header_id;
7392 END IF;
7393
7394 -- End of API body
7395
7396 -- Standard check of p_commit.
7397 IF fnd_api.to_boolean(p_commit) THEN
7398 COMMIT WORK;
7399 END IF;
7400
7401 -- Standard call to get message count and if count is 1,
7402 -- get message info.
7403 fnd_msg_pub.count_and_get(p_count => x_msg_count, p_data => x_msg_data);
7404 EXCEPTION
7405 WHEN fnd_api.g_exc_error THEN
7406 IF (l_debug = 1) THEN
7407 mdebug('Execution Error', 1);
7408 END IF;
7409 ROLLBACK TO prepack_lpn_pub;
7410 x_return_status := fnd_api.g_ret_sts_error;
7411 fnd_msg_pub.count_and_get(p_count => x_msg_count, p_data => x_msg_data);
7412 WHEN fnd_api.g_exc_unexpected_error THEN
7413 IF (l_debug = 1) THEN
7414 mdebug('Unexpected Execution Error', 1);
7415 END IF;
7416 ROLLBACK TO prepack_lpn_pub;
7417 x_return_status := fnd_api.g_ret_sts_unexp_error;
7418 fnd_msg_pub.count_and_get(p_count => x_msg_count, p_data => x_msg_data);
7419 WHEN OTHERS THEN
7420 IF (l_debug = 1) THEN
7421 mdebug('others error', 1);
7422 END IF;
7423 ROLLBACK TO prepack_lpn_pub;
7424 x_return_status := fnd_api.g_ret_sts_error;
7425 fnd_msg_pub.count_and_get(p_count => x_msg_count, p_data => x_msg_data);
7426 END Prepack_LPN;
7427
7428 -- ----------------------------------------------------------------------------------
7429 -- ----------------------------------------------------------------------------------
7430
7431 PROCEDURE Pack_Prepack_Container(
7432 p_api_version IN NUMBER
7433 , p_init_msg_list IN VARCHAR2 := fnd_api.g_false
7434 , p_commit IN VARCHAR2 := fnd_api.g_false
7435 , p_validation_level IN NUMBER := fnd_api.g_valid_level_full
7436 , x_return_status OUT NOCOPY VARCHAR2
7437 , x_msg_count OUT NOCOPY NUMBER
7438 , x_msg_data OUT NOCOPY VARCHAR2
7439 , p_lpn_id IN NUMBER
7440 , p_content_item_id IN NUMBER := NULL
7441 , p_revision IN VARCHAR2 := NULL
7442 , p_lot_number IN VARCHAR2 := NULL
7443 , p_from_serial_number IN VARCHAR2 := NULL
7444 , p_to_serial_number IN VARCHAR2 := NULL
7445 , p_quantity IN NUMBER := 1
7446 , p_uom IN VARCHAR2 := NULL
7447 , p_organization_id IN NUMBER
7448 , p_operation IN NUMBER
7449 , p_source_type_id IN NUMBER := NULL
7450 ) IS
7451 l_api_name CONSTANT VARCHAR2(30) := 'Pack_Prepack_Container';
7452 l_api_version CONSTANT NUMBER := 1.0;
7453 l_debug NUMBER := NVL(FND_PROFILE.VALUE('INV_DEBUG_TRACE'),0);
7454 l_progress VARCHAR2(10) := '0';
7455
7456 l_current_serial VARCHAR2(30):= p_from_serial_number;
7457 l_prefix VARCHAR2(30);
7458 l_quantity NUMBER;
7459 l_from_number NUMBER;
7460 l_to_number NUMBER;
7461 l_length NUMBER;
7462 l_errorcode NUMBER;
7463
7464 l_padded_length NUMBER;
7465 l_current_number NUMBER;
7466 BEGIN
7467 -- Standard Start of API savepoint
7468 SAVEPOINT PACK_PREPACK_CONTAINER;
7469
7470 -- Standard call to check for call compatibility.
7471 IF NOT fnd_api.compatible_api_call(l_api_version, p_api_version, l_api_name, g_pkg_name) THEN
7472 fnd_message.set_name('WMS', 'WMS_CONT_INCOMPATIBLE_API_CALL');
7473 fnd_msg_pub.ADD;
7474 RAISE fnd_api.g_exc_unexpected_error;
7475 END IF;
7476
7477 -- Initialize message list if p_init_msg_list is set to TRUE.
7478 IF fnd_api.to_boolean(p_init_msg_list) THEN
7479 fnd_msg_pub.initialize;
7480 END IF;
7481
7482 -- Initialize API return status to success
7483 x_return_status := fnd_api.g_ret_sts_success;
7484
7485 -- API body
7486 IF (l_debug = 1) THEN
7487 mdebug(l_api_name || ' Entered ' || g_pkg_version, 1);
7488 mdebug('lpnid=' ||p_lpn_id|| ' orgid=' ||p_organization_id||' itemid=' ||p_content_item_id, G_INFO);
7489 mdebug('rev=' ||p_revision|| ' lot=' ||p_lot_number|| ' fmsn=' ||p_from_serial_number|| ' tosn=' ||p_to_serial_number, G_INFO);
7490 mdebug('qty=' ||p_quantity|| ' uom=' ||p_uom|| ' oper=' ||p_operation|| ' srctype=' ||p_source_type_id, G_INFO);
7491 END IF;
7492
7493 IF ( p_content_item_id IS NOT NULL ) THEN
7494 IF ( p_from_serial_number IS NOT NULL AND p_to_serial_number IS NOT NULL ) THEN
7495 -- Packing range serialized items
7496 -- Call this API to parse the serial numbers into prefixes and numbers
7497 IF (NOT mtl_serial_check.inv_serial_info(p_from_serial_number, p_to_serial_number, l_prefix, l_quantity, l_from_number, l_to_number, l_errorcode)) THEN
7498 IF (l_debug = 1) THEN
7499 mdebug('Invalid serial number given in range', 1);
7500 END IF;
7501 fnd_message.set_name('WMS', 'WMS_CONT_INVALID_SER');
7502 fnd_msg_pub.ADD;
7503 RAISE fnd_api.g_exc_error;
7504 END IF;
7505
7506 -- Initialize the current pointer variables
7507 l_current_serial := p_from_serial_number;
7508 l_current_number := l_from_number;
7509
7510 LOOP
7511 -- Serialized item packed LPN information are stored
7512 -- in the serial numbers table
7513 -- Also update the cost group field since it is not
7514 -- guaranteed that the serial number will have that value stamped
7515 -- if serial status is not resides in store (3), update lot and rev
7516 UPDATE mtl_serial_numbers
7517 SET lpn_id = p_lpn_id,
7518 last_update_date = SYSDATE,
7519 last_updated_by = fnd_global.user_id,
7520 last_txn_source_type_id = p_source_type_id,
7521 revision = DECODE(current_status, 3, revision, p_revision),
7522 lot_number = DECODE(current_status, 3, lot_number, p_lot_number)
7523 WHERE inventory_item_id = p_content_item_id
7524 AND serial_number = l_current_serial
7525 AND current_organization_id = p_organization_id;
7526
7527 EXIT WHEN l_current_serial = p_to_serial_number;
7528 /* Increment the current serial number */
7529 l_current_number := l_current_number + 1;
7530 l_padded_length := l_length - LENGTH(l_current_number);
7531
7532 IF l_prefix IS NOT NULL THEN
7533 l_current_serial := RPAD(l_prefix, l_padded_length, '0') || l_current_number;
7534 ELSE
7535 l_current_serial := Rpad('@',l_padded_length+1,'0') || l_current_number;
7536 l_current_serial := Substr(l_current_serial,2);
7537 END IF;
7538 -- Bug 2375043
7539 --l_current_serial := RPAD(l_prefix, l_padded_length, '0') || l_current_number;
7540 END LOOP;
7541
7542 UPDATE wms_lpn_contents
7543 SET last_update_date = SYSDATE,
7544 last_updated_by = fnd_global.user_id,
7545 serial_summary_entry = 1,
7546 source_type_id = p_source_type_id
7547 WHERE parent_lpn_id = p_lpn_id
7548 AND organization_id = p_organization_id
7549 AND inventory_item_id = p_content_item_id
7550 AND NVL(revision, G_NULL_CHAR) = NVL(p_revision, G_NULL_CHAR)
7551 AND NVL(lot_number, G_NULL_CHAR) = NVL(p_lot_number, G_NULL_CHAR);
7552
7553 UPDATE wms_license_plate_numbers
7554 SET last_update_date = SYSDATE,
7555 last_updated_by = fnd_global.user_id,
7556 lpn_context = LPN_CONTEXT_WIP
7557 WHERE lpn_id = p_lpn_id
7558 AND organization_id = p_organization_id;
7559 END IF;
7560 END IF;
7561 -- End of API body
7562
7563 -- Standard check of p_commit.
7564 IF fnd_api.to_boolean(p_commit) THEN
7565 COMMIT WORK;
7566 END IF;
7567
7568 -- Standard call to get message count and if count is 1,
7569 -- get message info.
7570 fnd_msg_pub.count_and_get(p_count => x_msg_count, p_data => x_msg_data);
7571 EXCEPTION
7572 WHEN fnd_api.g_exc_error THEN
7573 ROLLBACK TO PACK_PREPACK_CONTAINER;
7574 x_return_status := fnd_api.g_ret_sts_error;
7575 fnd_msg_pub.count_and_get(p_count => x_msg_count, p_data => x_msg_data);
7576 WHEN fnd_api.g_exc_unexpected_error THEN
7577 ROLLBACK TO PACK_PREPACK_CONTAINER;
7578 x_return_status := fnd_api.g_ret_sts_unexp_error;
7579 fnd_msg_pub.count_and_get(p_count => x_msg_count, p_data => x_msg_data);
7580 WHEN OTHERS THEN
7581 ROLLBACK TO PACK_PREPACK_CONTAINER;
7582 x_return_status := fnd_api.g_ret_sts_unexp_error;
7583
7584 IF fnd_msg_pub.check_msg_level(fnd_msg_pub.g_msg_lvl_unexp_error) THEN
7585 fnd_msg_pub.add_exc_msg(g_pkg_name, l_api_name);
7586 END IF;
7587
7588 fnd_msg_pub.count_and_get(p_count => x_msg_count, p_data => x_msg_data);
7589 END Pack_Prepack_Container;
7590
7591 -- ----------------------------------------------------------------------------------
7592 -- ----------------------------------------------------------------------------------
7593
7594 PROCEDURE Explode_LPN (
7595 p_api_version IN NUMBER
7596 , p_init_msg_list IN VARCHAR2 := fnd_api.g_false
7597 , p_commit IN VARCHAR2 := fnd_api.g_false
7598 , x_return_status OUT NOCOPY VARCHAR2
7599 , x_msg_count OUT NOCOPY NUMBER
7600 , x_msg_data OUT NOCOPY VARCHAR2
7601 , p_lpn_id IN NUMBER
7602 , p_explosion_level IN NUMBER := 0
7603 , x_content_tbl OUT NOCOPY WMS_CONTAINER_PUB.WMS_Container_Tbl_Type
7604 ) IS
7605 l_api_name CONSTANT VARCHAR2(30) := 'Explode_LPN';
7606 l_api_version CONSTANT NUMBER := 1.0;
7607 l_debug NUMBER := NVL(FND_PROFILE.VALUE('INV_DEBUG_TRACE'),0);
7608 l_progress VARCHAR2(10) := '0';
7609 l_msgdata VARCHAR2(1000);
7610
7611 l_counter NUMBER := 1; -- Counter variable initialized to 1
7612 l_current_lpn NUMBER;
7613 l_temp_uom_code VARCHAR2(3);
7614 l_container_content_rec WMS_CONTAINER_PUB.WMS_Container_Content_Rec_Type;
7615
7616 CURSOR nested_lpn_cursor IS
7617 SELECT lpn_id, parent_lpn_id, inventory_item_id, organization_id,
7618 revision, lot_number, serial_number, cost_group_id
7619 FROM WMS_LICENSE_PLATE_NUMBERS
7620 WHERE Level <= p_explosion_level
7621 START WITH lpn_id = p_lpn_id
7622 CONNECT BY parent_lpn_id = PRIOR lpn_id;
7623
7624 CURSOR all_nested_lpn_cursor IS
7625 SELECT lpn_id, parent_lpn_id, inventory_item_id, organization_id,
7626 revision, lot_number, serial_number, cost_group_id
7627 FROM WMS_LICENSE_PLATE_NUMBERS
7628 START WITH lpn_id = p_lpn_id
7629 CONNECT BY parent_lpn_id = PRIOR lpn_id;
7630
7631 CURSOR lpn_contents_cursor IS
7632 SELECT parent_lpn_id, inventory_item_id, item_description,
7633 organization_id, revision, lot_number,
7634 serial_number, quantity, uom_code, cost_group_id,
7635 secondary_quantity, secondary_uom_code --INVCONV kkillams
7636 FROM WMS_LPN_CONTENTS
7637 WHERE parent_lpn_id = l_current_lpn
7638 AND NVL(serial_summary_entry, 2) = 2;
7639
7640 CURSOR lpn_serial_contents_cursor IS
7641 SELECT inventory_item_id, current_organization_id, lpn_id,
7642 revision, lot_number, serial_number, cost_group_id
7643 FROM MTL_SERIAL_NUMBERS
7644 WHERE lpn_id = l_current_lpn
7645 -- bug 5103594, added the Order By clause
7646 ORDER BY inventory_item_id, revision, lot_number, serial_number;
7647
7648 BEGIN
7649 -- Standard Start of API savepoint
7650 SAVEPOINT EXPLODE_LPN;
7651
7652 IF (l_debug = 1) THEN
7653 mdebug(l_api_name || ' Entered ' || g_pkg_version, 1);
7654 mdebug('ver='||p_api_version||' initmsg='||p_init_msg_list||' commit='||p_commit||' lpn='||p_lpn_id||' explvl='||p_explosion_level, G_INFO);
7655 END IF;
7656
7657 -- Standard call to check for call compatibility.
7658 IF NOT fnd_api.compatible_api_call(l_api_version, p_api_version, l_api_name, g_pkg_name) THEN
7659 fnd_message.set_name('WMS', 'WMS_CONT_INCOMPATIBLE_API_CALL');
7660 fnd_msg_pub.ADD;
7661 RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
7662 END IF;
7663
7664 -- Initialize message list if p_init_msg_list is set to TRUE.
7665 IF FND_API.to_Boolean( p_init_msg_list ) THEN
7666 FND_MSG_PUB.initialize;
7667 END IF;
7668
7669 -- Initialize API return status to success
7670 x_return_status := FND_API.G_RET_STS_SUCCESS;
7671
7672 -- API body
7673 IF (p_explosion_level = 0) THEN
7674 /* Use the cursor that searches through all levels in the parent child relationship */
7675 FOR v_lpn_id IN all_nested_lpn_cursor LOOP
7676 l_current_lpn := v_lpn_id.lpn_id;
7677
7678 /* Store the lpn information also from license plate numbers table */
7679 l_container_content_rec.parent_lpn_id := v_lpn_id.parent_lpn_id;
7680 l_container_content_rec.content_lpn_id := v_lpn_id.lpn_id;
7681 l_container_content_rec.content_item_id := v_lpn_id.inventory_item_id;
7682 l_container_content_rec.content_description := NULL;
7683 l_container_content_rec.content_type := '2';
7684 l_container_content_rec.organization_id := v_lpn_id.organization_id;
7685 l_container_content_rec.revision := v_lpn_id.revision;
7686 l_container_content_rec.lot_number := v_lpn_id.lot_number;
7687 l_container_content_rec.serial_number := v_lpn_id.serial_number;
7688 l_container_content_rec.quantity := 1;
7689 l_container_content_rec.uom := NULL;
7690 l_container_content_rec.cost_group_id := v_lpn_id.cost_group_id;
7691
7692 x_content_tbl(l_counter) := l_container_content_rec;
7693 l_counter := l_counter + 1;
7694
7695 /* Store all the item information from the lpn contents table */
7696 FOR v_lpn_content IN lpn_contents_cursor LOOP
7697 l_container_content_rec.parent_lpn_id := v_lpn_content.parent_lpn_id;
7698 l_container_content_rec.content_lpn_id := NULL;
7699 l_container_content_rec.content_item_id := v_lpn_content.inventory_item_id;
7700 l_container_content_rec.content_description := v_lpn_content.item_description;
7701 IF (v_lpn_content.inventory_item_id IS NOT NULL) THEN
7702 l_container_content_rec.content_type := '1';
7703 ELSE
7704 l_container_content_rec.content_type := '3';
7705 END IF;
7706 l_container_content_rec.organization_id := v_lpn_content.organization_id;
7707 l_container_content_rec.revision := v_lpn_content.revision;
7708 l_container_content_rec.lot_number := v_lpn_content.lot_number;
7709 l_container_content_rec.serial_number := v_lpn_content.serial_number;
7710 l_container_content_rec.quantity := v_lpn_content.quantity;
7711 l_container_content_rec.uom := v_lpn_content.uom_code;
7712 l_container_content_rec.cost_group_id := v_lpn_content.cost_group_id;
7713 l_container_content_rec.sec_quantity := v_lpn_content.secondary_quantity; --INVCONV kkillams
7714 l_container_content_rec.sec_uom := v_lpn_content.secondary_uom_code; --INVCONV kkillams
7715 x_content_tbl(l_counter) := l_container_content_rec;
7716 l_counter := l_counter + 1;
7717 END LOOP;
7718
7719 -- Store all the serialized item information from the serial
7720 -- numbers table
7721 FOR v_lpn_serial_content IN lpn_serial_contents_cursor LOOP
7722 /* Get the primary UOM for the serialized item */
7723 SELECT primary_uom_code
7724 INTO l_temp_uom_code
7725 FROM mtl_system_items
7726 WHERE inventory_item_id = v_lpn_serial_content.inventory_item_id
7727 AND organization_id = v_lpn_serial_content.current_organization_id;
7728
7729 l_container_content_rec.parent_lpn_id := v_lpn_serial_content.lpn_id;
7730 l_container_content_rec.content_lpn_id := NULL;
7731 l_container_content_rec.content_item_id := v_lpn_serial_content.inventory_item_id;
7732 l_container_content_rec.content_description := NULL;
7733 l_container_content_rec.content_type := '1';
7734 l_container_content_rec.organization_id := v_lpn_serial_content.current_organization_id;
7735 l_container_content_rec.revision := v_lpn_serial_content.revision;
7736 l_container_content_rec.lot_number := v_lpn_serial_content.lot_number;
7737 l_container_content_rec.serial_number := v_lpn_serial_content.serial_number;
7738 l_container_content_rec.quantity := 1;
7739 l_container_content_rec.uom := l_temp_uom_code;
7740 l_container_content_rec.cost_group_id := v_lpn_serial_content.cost_group_id;
7741
7742 x_content_tbl(l_counter) := l_container_content_rec;
7743 l_counter := l_counter + 1;
7744 END LOOP;
7745 END LOOP;
7746 ELSE
7747 /* Use the cursor that searches only a specified number of levels */
7748 FOR v_lpn_id IN nested_lpn_cursor LOOP
7749 l_current_lpn := v_lpn_id.lpn_id;
7750
7751 /* Store the lpn information also from license plate numbers table */
7752 l_container_content_rec.parent_lpn_id := v_lpn_id.parent_lpn_id;
7753 l_container_content_rec.content_lpn_id := v_lpn_id.lpn_id;
7754 l_container_content_rec.content_item_id := v_lpn_id.inventory_item_id;
7755 l_container_content_rec.content_description := NULL;
7756 l_container_content_rec.content_type := '2';
7757 l_container_content_rec.organization_id := v_lpn_id.organization_id;
7758 l_container_content_rec.revision := v_lpn_id.revision;
7759 l_container_content_rec.lot_number := v_lpn_id.lot_number;
7760 l_container_content_rec.serial_number := v_lpn_id.serial_number;
7761 l_container_content_rec.quantity := 1;
7762 l_container_content_rec.uom := NULL;
7763 l_container_content_rec.cost_group_id := v_lpn_id.cost_group_id;
7764
7765 x_content_tbl(l_counter) := l_container_content_rec;
7766 l_counter := l_counter + 1;
7767
7768 /* Store all the item information from the lpn contents table */
7769 FOR v_lpn_content IN lpn_contents_cursor LOOP
7770 l_container_content_rec.parent_lpn_id := v_lpn_content.parent_lpn_id;
7771 l_container_content_rec.content_lpn_id := NULL;
7772 l_container_content_rec.content_item_id := v_lpn_content.inventory_item_id;
7773 l_container_content_rec.content_description := v_lpn_content.item_description;
7774 IF (v_lpn_content.inventory_item_id IS NOT NULL) THEN
7775 l_container_content_rec.content_type := '1';
7776 ELSE
7777 l_container_content_rec.content_type := '3';
7778 END IF;
7779 l_container_content_rec.organization_id := v_lpn_content.organization_id;
7780 l_container_content_rec.revision := v_lpn_content.revision;
7781 l_container_content_rec.lot_number := v_lpn_content.lot_number;
7782 l_container_content_rec.serial_number := v_lpn_content.serial_number;
7783 l_container_content_rec.quantity := v_lpn_content.quantity;
7784 l_container_content_rec.uom := v_lpn_content.uom_code;
7785 l_container_content_rec.cost_group_id := v_lpn_content.cost_group_id;
7786 l_container_content_rec.sec_quantity := v_lpn_content.secondary_quantity; --INVCONV kkillams
7787 l_container_content_rec.sec_uom := v_lpn_content.secondary_uom_code; --INVCONV kkillams
7788
7789 x_content_tbl(l_counter) := l_container_content_rec;
7790 l_counter := l_counter + 1;
7791 END LOOP;
7792
7793 -- Store all the serialized item information from the serial
7794 -- numbers table
7795 FOR v_lpn_serial_content IN lpn_serial_contents_cursor LOOP
7796 /* Get the primary UOM for the serialized item */
7797 SELECT primary_uom_code
7798 INTO l_temp_uom_code
7799 FROM mtl_system_items
7800 WHERE inventory_item_id = v_lpn_serial_content.inventory_item_id
7801 AND organization_id = v_lpn_serial_content.current_organization_id;
7802
7803 l_container_content_rec.parent_lpn_id := v_lpn_serial_content.lpn_id;
7804 l_container_content_rec.content_lpn_id := NULL;
7805 l_container_content_rec.content_item_id := v_lpn_serial_content.inventory_item_id;
7806 l_container_content_rec.content_description := NULL;
7807 l_container_content_rec.content_type := '1';
7808 l_container_content_rec.organization_id := v_lpn_serial_content.current_organization_id;
7809 l_container_content_rec.revision := v_lpn_serial_content.revision;
7810 l_container_content_rec.lot_number := v_lpn_serial_content.lot_number;
7811 l_container_content_rec.serial_number := v_lpn_serial_content.serial_number;
7812 l_container_content_rec.quantity := 1;
7813 l_container_content_rec.uom := l_temp_uom_code;
7814 l_container_content_rec.cost_group_id := v_lpn_serial_content.cost_group_id;
7815
7816 x_content_tbl(l_counter) := l_container_content_rec;
7817 l_counter := l_counter + 1;
7818 END LOOP;
7819 END LOOP;
7820 END IF;
7821 -- End of API body
7822
7823 IF (l_debug = 1) THEN
7824 mdebug(l_api_name || ' Exit x_content_tbl count=' ||x_content_tbl.last, G_INFO);
7825 END IF;
7826
7827 -- Standard check of p_commit.
7828 IF FND_API.To_Boolean( p_commit ) THEN
7829 COMMIT WORK;
7830 END IF;
7831
7832 -- Standard call to get message count and if count is 1,
7833 -- get message info.
7834 FND_MSG_PUB.Count_And_Get( p_count => x_msg_count, p_data => x_msg_data );
7835 EXCEPTION
7836 WHEN FND_API.G_EXC_ERROR THEN
7837 ROLLBACK TO EXPLODE_LPN;
7838 x_return_status := FND_API.G_RET_STS_ERROR;
7839 FND_MSG_PUB.Count_And_Get( p_count => x_msg_count, p_data => x_msg_data );
7840
7841 IF (l_debug = 1) THEN
7842 mdebug(l_api_name ||' Exc err prog='||g_progress||' SQL err: '|| SQLERRM(SQLCODE), 1);
7843 FOR i in 1..x_msg_count LOOP
7844 l_msgdata := substr(l_msgdata||' | '||substr(fnd_msg_pub.get(x_msg_count-i+1, 'F'), 0, 200),1,2000);
7845 END LOOP;
7846 mdebug('msg: '||l_msgdata, 1);
7847 END IF;
7848 WHEN FND_API.G_EXC_UNEXPECTED_ERROR THEN
7849 ROLLBACK TO EXPLODE_LPN;
7850 x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
7851 FND_MSG_PUB.Count_And_Get( p_count => x_msg_count, p_data => x_msg_data );
7852
7853 IF (l_debug = 1) THEN
7854 mdebug(l_api_name ||' Unexp err prog='||g_progress||' SQL err: '|| SQLERRM(SQLCODE), 1);
7855 FOR i in 1..x_msg_count LOOP
7856 l_msgdata := substr(l_msgdata||' | '||substr(fnd_msg_pub.get(x_msg_count-i+1, 'F'), 0, 200),1,2000);
7857 END LOOP;
7858 mdebug('msg: '||l_msgdata, 1);
7859 END IF;
7860 WHEN OTHERS THEN
7861 ROLLBACK TO EXPLODE_LPN;
7862 x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
7863
7864 IF FND_MSG_PUB.Check_Msg_Level(FND_MSG_PUB.G_MSG_LVL_UNEXP_ERROR) THEN
7865 FND_MSG_PUB.Add_Exc_Msg(G_PKG_NAME, l_api_name);
7866 END IF;
7867
7868 FND_MSG_PUB.Count_And_Get( p_count => x_msg_count, p_data => x_msg_data );
7869
7870 IF (l_debug = 1) THEN
7871 mdebug(l_api_name ||' Others err prog='||g_progress||' SQL err: '|| SQLERRM(SQLCODE), 1);
7872 FOR i in 1..x_msg_count LOOP
7873 l_msgdata := substr(l_msgdata||' | '||substr(fnd_msg_pub.get(x_msg_count-i+1, 'F'), 0, 200),1,2000);
7874 END LOOP;
7875 mdebug('msg: '||l_msgdata, 1);
7876 END IF;
7877 END Explode_LPN;
7878
7879 -- ----------------------------------------------------------------------------------
7880 -- ----------------------------------------------------------------------------------
7881
7882 FUNCTION Validate_LPN (
7883 p_lpn IN OUT nocopy WMS_CONTAINER_PUB.LPN
7884 , p_lock IN NUMBER := 2
7885 ) RETURN NUMBER IS
7886 l_api_name CONSTANT VARCHAR2(30) := 'Validate_LPN';
7887 l_api_version CONSTANT NUMBER := 1.0;
7888 l_debug NUMBER := NVL(FND_PROFILE.VALUE('INV_DEBUG_TRACE'),0);
7889 l_progress VARCHAR2(10) := '0';
7890
7891 BEGIN
7892 /* Check that either an lpn id or license plate number was given */
7893 IF ((p_lpn.lpn_id IS NULL OR p_lpn.lpn_id = FND_API.G_MISS_NUM) AND
7894 (p_lpn.license_plate_number IS NULL OR
7895 p_lpn.license_plate_number = FND_API.G_MISS_CHAR)) THEN
7896 RETURN F;
7897 END IF;
7898
7899 /* Search the table for an entry that matches the given input(s) */
7900 IF (p_lpn.license_plate_number IS NULL OR
7901 p_lpn.license_plate_number = FND_API.G_MISS_CHAR)
7902 THEN
7903 IF ( p_lock = 1 ) THEN
7904 SELECT *
7905 INTO p_lpn
7906 FROM WMS_LICENSE_PLATE_NUMBERS
7907 WHERE LPN_ID = p_lpn.lpn_id
7908 FOR UPDATE;
7909 ELSE
7910 SELECT *
7911 INTO p_lpn
7912 FROM WMS_LICENSE_PLATE_NUMBERS
7913 WHERE LPN_ID = p_lpn.lpn_id;
7914 END IF;
7915
7916 RETURN T;
7917 ELSIF (p_lpn.lpn_id IS NULL OR p_lpn.lpn_id = FND_API.G_MISS_NUM) THEN
7918 IF ( p_lock = 1 ) THEN
7919 SELECT *
7920 INTO p_lpn
7921 FROM WMS_LICENSE_PLATE_NUMBERS
7922 WHERE LICENSE_PLATE_NUMBER = p_lpn.license_plate_number
7923 FOR UPDATE;
7924 ELSE
7925 SELECT *
7926 INTO p_lpn
7927 FROM WMS_LICENSE_PLATE_NUMBERS
7928 WHERE LICENSE_PLATE_NUMBER = p_lpn.license_plate_number;
7929 END IF;
7930
7931 RETURN T;
7932 ELSE
7933 IF ( p_lock = 1 ) THEN
7934 SELECT *
7935 INTO p_lpn
7936 FROM WMS_LICENSE_PLATE_NUMBERS
7937 WHERE LPN_ID = p_lpn.lpn_id
7938 AND LICENSE_PLATE_NUMBER = p_lpn.license_plate_number
7939 FOR UPDATE;
7940 ELSE
7941 SELECT *
7942 INTO p_lpn
7943 FROM WMS_LICENSE_PLATE_NUMBERS
7944 WHERE LPN_ID = p_lpn.lpn_id
7945 AND LICENSE_PLATE_NUMBER = p_lpn.license_plate_number;
7946 END IF;
7947
7948 RETURN T;
7949 END IF;
7950 EXCEPTION
7951 WHEN NO_DATA_FOUND OR TOO_MANY_ROWS THEN
7952 RETURN F;
7953 WHEN OTHERS THEN
7954 RETURN F;
7955 END Validate_LPN;
7956
7957 -- ----------------------------------------------------------------------------------
7958 -- ----------------------------------------------------------------------------------
7959
7960 FUNCTION Validate_LPN (
7961 p_organization_id IN NUMBER
7962 , p_lpn_id IN NUMBER
7963 , p_validation_type IN VARCHAR2
7964 ) RETURN NUMBER IS
7965 l_api_name CONSTANT VARCHAR2(30) := 'Validate_LPN';
7966 l_api_version CONSTANT NUMBER := 1.0;
7967 l_debug NUMBER := NVL(FND_PROFILE.VALUE('INV_DEBUG_TRACE'),0);
7968 l_progress VARCHAR2(10) := '0';
7969
7970 CURSOR Nested_LPN_Cursor IS
7971 SELECT lpn_id
7972 FROM wms_license_plate_numbers
7973 WHERE outermost_lpn_id = p_lpn_id;
7974
7975 lpn_rec Nested_LPN_Cursor%ROWTYPE;
7976 l_lpn_is_valid NUMBER := WMS_CONTAINER_PVT.F;
7977 l_parent_lpn_id NUMBER;
7978 BEGIN
7979 IF (l_debug = 1) THEN
7980 mdebug(l_api_name || ' Entered ' || g_pkg_version, 1);
7981 mdebug('orgid=' ||p_organization_id||' lpnid='||p_lpn_id||' type='||p_validation_type, G_MESSAGE);
7982 END IF;
7983
7984 IF ( p_validation_type = WMS_CONTAINER_PVT.G_RECONFIGURE_LPN OR
7985 p_validation_type = WMS_CONTAINER_PVT.G_NO_ONHAND_EXISTS ) THEN
7986 l_progress := '100';
7987 -- Check if the lpn_id entered is the outermost
7988 BEGIN
7989 SELECT parent_lpn_id INTO l_parent_lpn_id
7990 FROM wms_license_plate_numbers
7991 WHERE organization_id = p_organization_id
7992 AND lpn_id = p_lpn_id;
7993 EXCEPTION
7994 WHEN NO_DATA_FOUND THEN
7995 IF ( l_debug = 1 ) THEN
7996 mdebug('lpnid='||p_lpn_id|| ' does not exist', G_ERROR);
7997 END IF;
7998 fnd_message.set_name('WMS', 'WMS_CONT_INVALID_LPN');
7999 fnd_msg_pub.ADD;
8000 RETURN WMS_CONTAINER_PVT.F;
8001 END;
8002
8003 l_progress := '110';
8004 IF ( l_parent_lpn_id IS NOT NULL ) THEN
8005 IF ( l_debug = 1 ) THEN
8006 mdebug('lpnid='||p_lpn_id|| ' is not the outermost LPN', G_ERROR);
8007 END IF;
8008 fnd_message.set_name('WMS', 'WMS_LPN_NOT_OUTERMOST');
8009 fnd_msg_pub.ADD;
8010 RETURN WMS_CONTAINER_PVT.F;
8011 END IF;
8012 END IF;
8013
8014 l_progress := '200';
8015 OPEN Nested_LPN_Cursor;
8016 FETCH Nested_LPN_Cursor INTO lpn_rec;
8017
8018 l_progress := '210';
8019 IF ( Nested_LPN_Cursor%FOUND ) THEN
8020 l_lpn_is_valid := WMS_CONTAINER_PVT.T;
8021 l_progress := '220';
8022 WHILE ( l_lpn_is_valid = WMS_CONTAINER_PVT.T AND Nested_LPN_Cursor%FOUND ) LOOP
8023 IF ( p_validation_type = WMS_CONTAINER_PVT.G_RECONFIGURE_LPN ) THEN
8024 -- Check if the lpn is on a reservation
8025 BEGIN
8026 SELECT WMS_CONTAINER_PVT.F
8027 INTO l_lpn_is_valid
8028 FROM mtl_reservations
8029 WHERE organization_id = p_organization_id
8030 AND lpn_id = lpn_rec.lpn_id
8031 AND rownum < 2;
8032 IF ( l_debug = 1 ) THEN
8033 mdebug('lpnid='||lpn_rec.lpn_id|| ' is reserved', G_ERROR);
8034 END IF;
8035 fnd_message.set_name('INV', 'INV_LPN_RESERVED');
8036 fnd_msg_pub.ADD;
8037 EXIT;
8038 EXCEPTION
8039 WHEN NO_DATA_FOUND THEN
8040 NULL; --no rows fround everything is okay
8041 END;
8042
8043 -- check to see if there are pending transactions or the
8044 -- lpn has been allocatied
8045 BEGIN
8046 SELECT WMS_CONTAINER_PVT.F
8047 INTO l_lpn_is_valid
8048 FROM mtl_material_transactions_temp
8049 WHERE organization_id = p_organization_id
8050 AND ( ALLOCATED_LPN_ID = lpn_rec.lpn_id OR
8051 lpn_id = lpn_rec.lpn_id OR
8052 content_lpn_id = lpn_rec.lpn_id OR
8053 transfer_lpn_id = lpn_rec.lpn_id )
8054 AND rownum < 2;
8055 IF ( l_debug = 1 ) THEN
8056 mdebug('lpnid='||lpn_rec.lpn_id||' is in a pending MMTT transaction', G_ERROR);
8057 END IF;
8058 fnd_message.set_name('WMS', 'INV_PART_OF_PENDING_TXN');
8059 fnd_message.set_token('ENTITY1','INV_LPN');
8060 fnd_msg_pub.ADD;
8061 EXIT;
8062 EXCEPTION
8063 WHEN NO_DATA_FOUND THEN
8064 NULL; --no rows fround everything is okay
8065 END;
8066 END IF;
8067
8068 IF ( p_validation_type = WMS_CONTAINER_PVT.G_NO_ONHAND_EXISTS ) THEN
8069 -- check to see if there is any onhand quantity associated with lpn
8070 BEGIN
8071 SELECT WMS_CONTAINER_PVT.F
8072 INTO l_lpn_is_valid
8073 FROM mtl_onhand_quantities_detail
8074 WHERE organization_id = p_organization_id
8075 AND lpn_id = lpn_rec.lpn_id
8076 AND rownum < 2;
8077 IF ( l_debug = 1 ) THEN
8078 mdebug('lpnid='||lpn_rec.lpn_id||' has onhand associated with it', G_ERROR);
8079 END IF;
8080 fnd_message.set_name('WMS', 'WMS_CONT_NON_EMPTY_LPN');
8081 fnd_msg_pub.ADD;
8082 EXIT;
8083 EXCEPTION
8084 WHEN NO_DATA_FOUND THEN
8085 NULL; --no rows fround everything is okay
8086 END;
8087
8088 --check to see if there are any serial numbers associated with lpn
8089 BEGIN
8090 SELECT WMS_CONTAINER_PVT.F
8091 INTO l_lpn_is_valid
8092 FROM mtl_serial_numbers
8093 WHERE current_organization_id = p_organization_id
8094 AND lpn_id = lpn_rec.lpn_id
8095 AND rownum < 2;
8096 IF ( l_debug = 1 ) THEN
8097 mdebug('lpnid='||lpn_rec.lpn_id|| ' has serial numbers associated with it', G_ERROR);
8098 END IF;
8099 fnd_message.set_name('WMS', 'WMS_CONT_NON_EMPTY_LPN');
8100 fnd_msg_pub.ADD;
8101 EXIT;
8102 EXCEPTION
8103 WHEN NO_DATA_FOUND THEN
8104 NULL; --no rows fround everything is okay
8105 END;
8106 END IF;
8107 FETCH Nested_LPN_Cursor INTO lpn_rec;
8108 END LOOP;
8109 END IF;
8110 l_progress := '300';
8111 CLOSE Nested_LPN_Cursor;
8112
8113 IF ( l_debug = 1 ) THEN
8114 mdebug(l_api_name || ' Exited return='||l_lpn_is_valid, 1);
8115 END IF;
8116 RETURN l_lpn_is_valid;
8117 EXCEPTION
8118 WHEN OTHERS THEN
8119 IF (l_debug = 1) THEN
8120 mdebug(l_api_name ||' Error progress= '||l_progress||'SQL error: '|| SQLERRM(SQLCODE), G_ERROR);
8121 END IF;
8122 RETURN WMS_CONTAINER_PVT.F;
8123 END Validate_LPN;
8124
8125 -- ----------------------------------------------------------------------------------
8126 -- ----------------------------------------------------------------------------------
8127
8128 PROCEDURE Merge_Up_LPN (
8129 p_api_version IN NUMBER
8130 , p_init_msg_list IN VARCHAR2 := fnd_api.g_false
8131 , p_commit IN VARCHAR2 := fnd_api.g_false
8132 , x_return_status OUT NOCOPY VARCHAR2
8133 , x_msg_count OUT NOCOPY NUMBER
8134 , x_msg_data OUT NOCOPY VARCHAR2
8135 , p_organization_id IN NUMBER
8136 , p_outermost_lpn_id IN NUMBER
8137 ) IS
8138 l_api_name CONSTANT VARCHAR2(30) := 'Merge_Up_LPN';
8139 l_api_version CONSTANT NUMBER := 1.0;
8140 l_debug NUMBER := NVL(FND_PROFILE.VALUE('INV_DEBUG_TRACE'),0);
8141 l_progress VARCHAR2(10) := '0';
8142
8143 l_contents_tbl WMS_CONTAINER_PUB.WMS_CONTAINER_TBL_TYPE;
8144 l_return_status NUMBER;
8145 l_trx_tmp_id NUMBER;
8146 l_ser_tmp_id NUMBER;
8147 l_trx_hdr_id NUMBER;
8148 l_converted_qty NUMBER;
8149 l_primary_uom VARCHAR2(3);
8150
8151 l_insert_item_rec BOOLEAN := FALSE;
8152 l_insert_lot_rec BOOLEAN := FALSE;
8153 l_insert_ser_rec BOOLEAN := FALSE;
8154
8155 -- Variables for call to Inv_Serial_Info
8156 l_range_is_done BOOLEAN := FALSE;
8157 l_serial_def_flag BOOLEAN;
8158 l_serial_prefix VARCHAR2(30);
8159 l_fm_serial VARCHAR2(30);
8160 l_to_serial VARCHAR2(30);
8161 l_serial_suffix NUMBER;
8162 l_serial_suffix_length NUMBER := 0;
8163 l_temp_num NUMBER;
8164 v_acct_period_id NUMBER;
8165 v_open_past_period BOOLEAN := FALSE;
8166 l_label_status VARCHAR2(100);
8167 l_label_return VARCHAR2(1);
8168
8169 CURSOR Nested_LPN_cur IS
8170 SELECT lpn_id, lpn_context, subinventory_code, locator_id, parent_lpn_id
8171 FROM wms_license_plate_numbers
8172 WHERE lpn_id <> p_outermost_lpn_id
8173 START WITH lpn_id = p_outermost_lpn_id
8174 CONNECT BY parent_lpn_id = PRIOR lpn_id;
8175
8176 CURSOR LPN_item_cur (p_parent_lpn_id NUMBER) IS
8177 SELECT inventory_item_id, quantity, uom_code, revision, lot_number, quantity lot_quantity,
8178 cost_group_id, serial_summary_entry
8179 ,secondary_quantity, secondary_uom_code --INVCONV kkillams
8180 FROM wms_lpn_contents
8181 WHERE organization_id = p_organization_id
8182 AND parent_lpn_id = p_parent_lpn_id
8183 ORDER BY inventory_item_id, revision, cost_group_id, lot_number;
8184
8185 l_crnt_item_rec LPN_item_cur%ROWTYPE;
8186 l_next_item_rec LPN_item_cur%ROWTYPE;
8187
8188 CURSOR LPN_serial_cur (p_lpn_id NUMBER, p_item_id NUMBER, p_revision VARCHAR2, p_lot_number VARCHAR2) IS
8189 SELECT serial_number
8190 FROM mtl_serial_numbers
8191 WHERE current_organization_id = p_organization_id
8192 AND inventory_item_id = p_item_id
8193 AND lpn_id = p_lpn_id
8194 AND NVL(revision, '@') = NVL(p_revision, '@')
8195 AND NVL(lot_number, '@') = NVL(p_lot_number, '@');
8196
8197 l_crnt_ser_rec LPN_serial_cur%ROWTYPE;
8198
8199 BEGIN
8200 -- Standard Start of API savepoint
8201 SAVEPOINT MERGE_UP_LPN;
8202
8203 -- Initialize message list if p_init_msg_list is set to TRUE.
8204 IF fnd_api.to_boolean(p_init_msg_list) THEN
8205 fnd_msg_pub.initialize;
8206 END IF;
8207
8208 -- Initialize API return status to success
8209 x_return_status := FND_API.G_RET_STS_SUCCESS;
8210
8211 IF (l_debug = 1) THEN
8212 mdebug(l_api_name || ' Entered ' || g_pkg_version, 1);
8213 mdebug('orgid=' ||p_organization_id||' lpnid='||p_outermost_lpn_id, G_MESSAGE);
8214 END IF;
8215
8216 -- get the account period ID
8217 invttmtx.tdatechk(p_organization_id, SYSDATE, v_acct_period_id, v_open_past_period);
8218
8219 SELECT mtl_material_transactions_s.nextval
8220 INTO l_trx_hdr_id
8221 FROM DUAL;
8222
8223 FOR Nested_LPN_rec IN Nested_LPN_cur LOOP
8224 -- Insert an 'UNPACK' transaction of child LPN from parent LPN into
8225 -- MTL_MATERIAL_TRANSACTIONS_TEMP using standard MMTT insert API
8226 l_return_status := INV_TRX_UTIL_PUB.INSERT_LINE_TRX (
8227 p_trx_hdr_id => l_trx_hdr_id
8228 , p_item_id => -1
8229 , p_org_id => p_organization_id
8230 , p_subinv_code => Nested_LPN_rec.subinventory_code
8231 , p_locator_id => Nested_LPN_rec.locator_id
8232 , p_trx_src_type_id => INV_GLOBALS.G_SourceType_Inventory
8233 , p_trx_action_id => INV_GLOBALS.G_Action_ContainerUnPack
8234 , p_trx_type_id => INV_GLOBALS.G_TYPE_CONTAINER_UNPACK
8235 , p_trx_qty => 1
8236 , p_pri_qty => 1
8237 , p_uom => 'Ea'
8238 , p_date => SYSDATE
8239 , p_user_id => fnd_global.user_id
8240 , p_from_lpn_id => Nested_LPN_rec.parent_lpn_id
8241 , p_cnt_lpn_id => Nested_LPN_rec.lpn_id
8242 , x_trx_tmp_id => l_trx_tmp_id
8243 , x_proc_msg => x_msg_data );
8244 IF ( l_return_status <> 0) THEN
8245 IF (l_debug = 1) THEN
8246 mdebug('Insert_Line_Trx failed :'||x_msg_data, 1);
8247 END IF;
8248 RAISE FND_API.G_EXC_ERROR;
8249 END IF;
8250
8251 IF (l_debug = 1) THEN
8252 mdebug('Inserted unpack hdrid='||l_trx_hdr_id||' tempid='||l_trx_tmp_id||' lpn='||Nested_LPN_rec.lpn_id||' parlpn='|| Nested_LPN_rec.parent_lpn_id, 4);
8253 END IF;
8254
8255 OPEN LPN_item_cur( Nested_LPN_rec.lpn_id );
8256 FETCH LPN_item_cur INTO l_next_item_rec;
8257
8258 IF ( LPN_item_cur%FOUND ) THEN
8259 -- Create new trx temp id
8260 SELECT mtl_material_transactions_s.nextval
8261 INTO l_trx_tmp_id
8262 FROM DUAL;
8263
8264 -- Find the primary uom
8265 SELECT primary_uom_code
8266 INTO l_primary_uom
8267 FROM mtl_system_items
8268 WHERE organization_id = p_organization_id
8269 AND inventory_item_id = l_next_item_rec.inventory_item_id;
8270
8271 LOOP
8272 l_crnt_item_rec := l_next_item_rec;
8273 EXIT WHEN l_crnt_item_rec.inventory_item_id IS NULL;
8274 FETCH LPN_item_cur INTO l_next_item_rec;
8275
8276 IF ( LPN_item_cur%NOTFOUND ) THEN
8277 l_next_item_rec.inventory_item_id := NULL;
8278 l_next_item_rec.revision := NULL;
8279 END IF;
8280
8281 IF (l_debug = 1) THEN
8282 mdebug('critm='||l_crnt_item_rec.inventory_item_id||' rv='||l_crnt_item_rec.revision||' lot='||l_crnt_item_rec.lot_number||' qty='||l_crnt_item_rec.quantity||' uom='||l_crnt_item_rec.uom_code||' lqty='||l_crnt_item_rec.lot_quantity);
8283 mdebug('sec uom='||l_crnt_item_rec.secondary_uom_code||' sec qty='||l_crnt_item_rec.secondary_quantity, 4);
8284 mdebug('nxitm='||l_next_item_rec.inventory_item_id||' rv='||l_next_item_rec.revision||' lot='||l_next_item_rec.lot_number||' qty='||l_next_item_rec.quantity||' uom='||l_next_item_rec.uom_code||' lqty='||l_next_item_rec.lot_quantity);
8285 mdebug('sec uom='||l_next_item_rec.secondary_uom_code||' sec qty='||l_next_item_rec.secondary_quantity, 4);
8286 END IF;
8287
8288 IF ( l_crnt_item_rec.inventory_item_id = l_next_item_rec.inventory_item_id AND
8289 NVL(l_crnt_item_rec.revision, '@') = NVL(l_next_item_rec.revision, '@') AND
8290 NVL(l_crnt_item_rec.cost_group_id, -9) = NVL(l_next_item_rec.cost_group_id, -9) ) THEN
8291 -- Will be adding quantities, make sure the uoms are the same
8292 IF ( l_crnt_item_rec.uom_code <> l_next_item_rec.uom_code ) THEN
8293 l_next_item_rec.quantity := Convert_UOM(l_crnt_item_rec.inventory_item_id, l_next_item_rec.quantity, l_next_item_rec.uom_code, l_next_item_rec.uom_code);
8294 l_next_item_rec.uom_code := l_crnt_item_rec.uom_code;
8295 END IF;
8296 -- These to records can go into the same MMTT line add the quantities
8297 l_next_item_rec.quantity := l_next_item_rec.quantity + l_crnt_item_rec.quantity;
8298
8299 IF ( l_crnt_item_rec.lot_number = l_next_item_rec.lot_number ) THEN
8300 l_next_item_rec.lot_quantity := l_next_item_rec.quantity + l_crnt_item_rec.lot_quantity;
8301 ELSIF ( l_crnt_item_rec.lot_number IS NOT NULL ) THEN
8302 l_insert_lot_rec := TRUE;
8303 END IF;
8304 ELSE -- Different item/rev need to make MMTT
8305 l_insert_item_rec := TRUE;
8306 -- If lot controlled, will need to insert lot record too
8307 IF ( l_crnt_item_rec.lot_number IS NOT NULL ) THEN
8308 l_insert_lot_rec := TRUE;
8309 ELSIF ( l_crnt_item_rec.serial_summary_entry = 1 ) THEN
8310 l_insert_ser_rec := TRUE;
8311 l_ser_tmp_id := l_trx_tmp_id;
8312 END IF;
8313 END IF;
8314
8315 IF ( l_insert_lot_rec ) THEN
8316 IF ( l_crnt_item_rec.uom_code <> l_primary_uom ) THEN
8317 l_converted_qty := Convert_UOM(l_crnt_item_rec.inventory_item_id, l_crnt_item_rec.quantity, l_crnt_item_rec.uom_code, l_primary_uom);
8318 ELSE
8319 l_converted_qty := l_crnt_item_rec.lot_quantity;
8320 END IF;
8321 -- Insert record into MTL_TRANSACTIONS_LOTS_TEMP
8322 l_return_status := INV_TRX_UTIL_PUB.Insert_Lot_Trx(
8323 p_trx_tmp_id => l_trx_tmp_id
8324 , p_user_id => fnd_global.user_id
8325 , p_lot_number => l_crnt_item_rec.lot_number
8326 , p_trx_qty => l_crnt_item_rec.lot_quantity
8327 , p_pri_qty => l_converted_qty
8328 , p_secondary_qty => l_crnt_item_rec.secondary_quantity --INVCONV kkillams
8329 , p_secondary_uom => l_crnt_item_rec.secondary_uom_code --INVCONV kkillams
8330 , x_ser_trx_id => l_ser_tmp_id
8331 , x_proc_msg => x_msg_data );
8332 IF ( l_return_status <> 0 ) THEN
8333 IF (l_debug = 1) THEN
8334 mdebug('Insert_Lot_Trx failed :'||x_msg_data, 1);
8335 END IF;
8336 RAISE FND_API.G_EXC_ERROR;
8337 END IF;
8338
8339 IF (l_debug = 1) THEN
8340 mdebug('Inserted lot tempid='||l_trx_tmp_id||' lot='||l_crnt_item_rec.lot_number||' qty='||l_crnt_item_rec.lot_quantity||' stmpid='||l_ser_tmp_id, 4);
8341 END IF;
8342
8343 -- May need to insert serials if item is serial controlled
8344 IF ( l_crnt_item_rec.serial_summary_entry = 1 ) THEN
8345 l_insert_ser_rec := TRUE;
8346 END IF;
8347 l_insert_lot_rec := FALSE;
8348 END IF;
8349
8350 -- Insert record into MTL_SERIAL_NUMBERS_TEMP
8351 IF ( l_insert_ser_rec ) THEN
8352 OPEN LPN_serial_cur(Nested_LPN_rec.lpn_id, l_crnt_item_rec.inventory_item_id,
8353 l_crnt_item_rec.revision, l_crnt_item_rec.lot_number);
8354 FETCH LPN_serial_cur INTO l_crnt_ser_rec;
8355 l_fm_serial:= l_crnt_ser_rec.serial_number;
8356 l_to_serial:= l_crnt_ser_rec.serial_number;
8357 LOOP
8358 FETCH LPN_serial_cur INTO l_crnt_ser_rec;
8359 IF (l_debug = 1) THEN
8360 mdebug('current serial='||l_crnt_ser_rec.serial_number, 4);
8361 END IF;
8362
8363 -- Algorithm to try and flatten serial ranges as much as possible
8364 IF ( LPN_serial_cur%FOUND AND l_serial_prefix IS NULL ) THEN
8365 l_serial_def_flag := MTL_SERIAL_CHECK.Inv_Serial_Info(
8366 l_fm_serial, l_to_serial, l_serial_prefix,
8367 l_temp_num, l_serial_suffix, l_serial_suffix, l_return_status);
8368 IF ( l_return_status <> 0 ) THEN
8369 IF (l_debug = 1) THEN
8370 mdebug('Inv_Serial_Info failed', 1);
8371 END IF;
8372 FND_MESSAGE.SET_NAME('WMS', 'WMS_CONT_INVALID_SER');
8373 FND_MSG_PUB.ADD;
8374 RAISE FND_API.G_EXC_ERROR;
8375 END IF;
8376 -- calculate the length of the serial number suffix
8377 l_serial_suffix_length := LENGTH(l_fm_serial) - LENGTH(l_serial_prefix);
8378 l_serial_suffix := l_serial_suffix + 1;
8379
8380 IF (l_debug = 1) THEN
8381 mdebug('New prefix='||l_serial_prefix||' suffix='||l_serial_suffix||' sfxlgth='||l_serial_suffix_length, 1);
8382 END IF;
8383 END IF;
8384
8385 IF ( l_crnt_ser_rec.serial_number = l_serial_prefix||LPAD(TO_CHAR(l_serial_suffix), l_serial_suffix_length, '0') ) THEN
8386 -- The serials are contiguous, set l_to_serial to new serial
8387 l_to_serial := l_crnt_ser_rec.serial_number;
8388 l_serial_suffix := l_serial_suffix + 1;
8389 ELSE
8390 l_range_is_done := TRUE;
8391 END IF;
8392
8393 mdebug('expected next sn='||l_serial_prefix||LPAD(TO_CHAR(l_serial_suffix), l_serial_suffix_length, '0'), 1);
8394
8395 IF ( l_range_is_done OR LPN_serial_cur%NOTFOUND ) THEN
8396 IF (l_debug = 1) THEN
8397 mdebug('Insert ser tempid='||l_ser_tmp_id||' fmsn='||l_fm_serial||' tosn='||l_to_serial, 4);
8398 END IF;
8399 -- Range finished or last serial processed, insert serial with API and reset from serial
8400 l_return_status := INV_TRX_UTIL_PUB.Insert_Ser_Trx (
8401 p_trx_tmp_id => l_ser_tmp_id
8402 , p_user_id => fnd_global.user_id
8403 , p_fm_ser_num => l_fm_serial
8404 , p_to_ser_num => l_to_serial
8405 , x_proc_msg => x_msg_data );
8406 IF ( l_return_status <> 0 ) THEN
8407 IF (l_debug = 1) THEN
8408 mdebug('Insert_Ser_Trx failed :'||x_msg_data, 1);
8409 END IF;
8410 RAISE FND_API.G_EXC_ERROR;
8411 END IF;
8412 -- reset serial variables
8413 l_fm_serial:= l_crnt_ser_rec.serial_number;
8414 l_to_serial:= l_crnt_ser_rec.serial_number;
8415 l_serial_prefix := NULL;
8416 l_range_is_done := FALSE;
8417 END IF;
8418
8419 EXIT WHEN LPN_serial_cur%NOTFOUND;
8420 END LOOP;
8421 CLOSE LPN_serial_cur;
8422 -- Reset serial variables
8423 l_insert_ser_rec := FALSE;
8424 END IF;
8425
8426 IF ( l_insert_item_rec ) THEN
8427 IF (l_debug = 1) THEN
8428 mdebug('Insert split tmpid='||l_trx_tmp_id||' plpn='||Nested_LPN_rec.parent_lpn_id||' itm='||l_crnt_item_rec.inventory_item_id||' rev='||l_crnt_item_rec.revision||' qty='||l_crnt_item_rec.quantity||' cg='||l_crnt_item_rec.cost_group_id, 4);
8429 END IF;
8430
8431 IF ( l_crnt_item_rec.uom_code <> l_primary_uom ) THEN
8432 l_converted_qty := Convert_UOM(l_crnt_item_rec.inventory_item_id, l_crnt_item_rec.quantity, l_crnt_item_rec.uom_code, l_primary_uom);
8433 ELSE
8434 l_converted_qty := l_crnt_item_rec.quantity;
8435 END IF;
8436
8437 -- MTL_MATERIAL_TRANSACTIONS_TEMP cannot use API because
8438 -- need to use sepecific transaction temp id
8439 INSERT INTO mtl_material_transactions_temp (
8440 transaction_header_id
8441 , transaction_temp_id
8442 , process_flag
8443 , creation_date
8444 , created_by
8445 , last_update_date
8446 , last_updated_by
8447 , last_update_login
8448 , transaction_date
8449 , organization_id
8450 , subinventory_code
8451 , locator_id
8452 , inventory_item_id
8453 , revision
8454 , cost_group_id
8455 , transaction_source_type_id
8456 , transaction_action_id
8457 , transaction_type_id
8458 , transaction_quantity
8459 , primary_quantity
8460 , transaction_uom
8461 , lpn_id
8462 , transfer_lpn_id
8463 , acct_period_id
8464 , secondary_transaction_quantity --INCONV kkillams
8465 , secondary_uom_code --INCONV kkillamsb
8466 ) VALUES (
8467 l_trx_hdr_id
8468 , l_trx_tmp_id
8469 , 'Y'
8470 , SYSDATE
8471 , fnd_global.user_id
8472 , SYSDATE
8473 , fnd_global.user_id
8474 , fnd_global.user_id
8475 , SYSDATE
8476 , p_organization_id
8477 , Nested_LPN_rec.subinventory_code
8478 , Nested_LPN_rec.locator_id
8479 , l_crnt_item_rec.inventory_item_id
8480 , l_crnt_item_rec.revision
8481 , l_crnt_item_rec.cost_group_id
8482 , INV_GLOBALS.G_SourceType_Inventory
8483 , INV_GLOBALS.G_Action_ContainerSplit
8484 , INV_GLOBALS.G_TYPE_CONTAINER_SPLIT
8485 , l_crnt_item_rec.quantity
8486 , l_converted_qty
8487 , l_crnt_item_rec.uom_code
8488 , Nested_LPN_rec.lpn_id
8489 , p_outermost_lpn_id
8490 , v_acct_period_id
8491 , l_crnt_item_rec.secondary_quantity --INCONV kkillams
8492 , l_crnt_item_rec.secondary_uom_code --INCONV kkillams
8493 );
8494
8495 -- Done with this item/revision/costgroup combo need new trx temp id
8496 SELECT mtl_material_transactions_s.nextval
8497 INTO l_trx_tmp_id
8498 FROM DUAL;
8499
8500 -- If next record is for a new item need to find the primary uom
8501 IF ( l_crnt_item_rec.inventory_item_id <> l_next_item_rec.inventory_item_id ) THEN
8502 SELECT primary_uom_code
8503 INTO l_primary_uom
8504 FROM mtl_system_items
8505 WHERE organization_id = p_organization_id
8506 AND inventory_item_id = l_crnt_item_rec.inventory_item_id;
8507 END IF;
8508 l_insert_item_rec := FALSE;
8509 END IF;
8510 END LOOP;
8511 END IF;
8512 CLOSE LPN_item_cur;
8513 END LOOP; -- Nested_LPN_cur
8514
8515 IF (l_debug = 1) THEN
8516 mdebug('Call to TM hdrid='||l_trx_hdr_id, 4);
8517 END IF;
8518 l_return_status := INV_LPN_TRX_PUB.PROCESS_LPN_TRX (
8519 p_trx_hdr_id => l_trx_hdr_id
8520 , x_proc_msg => x_msg_data
8521 , p_proc_mode => 1
8522 , p_atomic => fnd_api.g_true );
8523 IF ( l_return_status <> 0 ) THEN
8524 IF (l_debug = 1) THEN
8525 mdebug('PROCESS_LPN_TRX Failed msg: '||x_msg_data, 1);
8526 END IF;
8527 RAISE fnd_api.g_exc_error;
8528 END IF;
8529
8530 INV_LABEL.PRINT_LABEL_MANUAL_WRAP(
8531 x_return_status => l_label_return
8532 , x_msg_count => x_msg_count
8533 , x_msg_data => x_msg_data
8534 , x_label_status => l_label_status
8535 , p_business_flow_code => 36
8536 , p_lpn_id => p_outermost_lpn_id );
8537
8538 IF ( l_debug = 1 ) THEN
8539 mdebug('Called INV_LABEL.PRINT_LABEL, return_status='||l_label_return||' label stat='||l_label_status, 1);
8540 END IF;
8541
8542 -- Standard check of p_commit.
8543 IF FND_API.To_Boolean( p_commit ) THEN
8544 COMMIT WORK;
8545 END IF;
8546
8547 FND_MSG_PUB.Count_And_Get( p_count => x_msg_count, p_data => x_msg_data );
8548 EXCEPTION
8549 WHEN OTHERS THEN
8550 IF (l_debug = 1) THEN
8551 mdebug(l_api_name ||' Error l_progress=' || l_progress, 1);
8552 IF ( SQLCODE IS NOT NULL ) THEN
8553 mdebug('SQL error: ' || SQLERRM(SQLCODE), 1);
8554 END IF;
8555 END IF;
8556
8557 ROLLBACK TO MERGE_UP_LPN;
8558 x_return_status := fnd_api.g_ret_sts_error;
8559 fnd_message.set_name('WMS', 'WMS_API_FAILURE');
8560 fnd_msg_pub.ADD;
8561 FND_MSG_PUB.Count_And_Get(p_count => x_msg_count, p_data => x_msg_data);
8562 END Merge_Up_LPN;
8563
8564 -- ----------------------------------------------------------------------------------
8565 -- ----------------------------------------------------------------------------------
8566
8567 PROCEDURE Break_Down_LPN(
8568 p_api_version IN NUMBER
8569 , p_init_msg_list IN VARCHAR2 := fnd_api.g_false
8570 , p_commit IN VARCHAR2 := fnd_api.g_false
8571 , x_return_status OUT NOCOPY VARCHAR2
8572 , x_msg_count OUT NOCOPY NUMBER
8573 , x_msg_data OUT NOCOPY VARCHAR2
8574 , p_organization_id IN NUMBER
8575 , p_outermost_lpn_id IN NUMBER
8576 ) IS
8577 l_api_name CONSTANT VARCHAR2(30) := 'Break_Down_LPN';
8578 l_api_version CONSTANT NUMBER := 1.0;
8579 l_debug NUMBER := NVL(FND_PROFILE.VALUE('INV_DEBUG_TRACE'),0);
8580 l_progress VARCHAR2(10) := '0';
8581
8582 CURSOR nested_lpn_cursor IS
8583 SELECT rowid, lpn_id, parent_lpn_id, subinventory_code, locator_id
8584 FROM WMS_LICENSE_PLATE_NUMBERS
8585 WHERE lpn_id <> p_outermost_lpn_id
8586 START WITH lpn_id = p_outermost_lpn_id
8587 CONNECT BY parent_lpn_id = PRIOR lpn_id;
8588
8589 l_return_status NUMBER;
8590 l_trx_tmp_id NUMBER;
8591 l_trx_hdr_id NUMBER;
8592 l_label_count NUMBER := 1;
8593 l_label_status VARCHAR2(100);
8594 l_label_return VARCHAR2(1);
8595 l_input_param_rec_tbl INV_LABEL.input_parameter_rec_type;
8596
8597 BEGIN
8598 -- Standard Start of API savepoint
8599 SAVEPOINT BREAK_DOWN_LPN;
8600
8601 -- Standard call to check for call compatibility.
8602 IF NOT fnd_api.compatible_api_call(l_api_version, p_api_version, l_api_name, g_pkg_name) THEN
8603 fnd_message.set_name('WMS', 'WMS_CONT_INCOMPATIBLE_API_CALL');
8604 fnd_msg_pub.ADD;
8605 RAISE fnd_api.g_exc_unexpected_error;
8606 END IF;
8607
8608 -- Initialize message list if p_init_msg_list is set to TRUE.
8609 IF fnd_api.to_boolean(p_init_msg_list) THEN
8610 fnd_msg_pub.initialize;
8611 END IF;
8612
8613 -- Initialize API return status to success
8614 x_return_status := FND_API.G_RET_STS_SUCCESS;
8615
8616 IF (l_debug = 1) THEN
8617 mdebug(l_api_name || ' Entered ' || g_pkg_version, 1);
8618 mdebug('orgid=' ||p_organization_id||' lpnid='||p_outermost_lpn_id, G_MESSAGE);
8619 END IF;
8620
8621 SELECT mtl_material_transactions_s.nextval
8622 INTO l_trx_hdr_id
8623 FROM DUAL;
8624
8625 --Every nested lpn will need to be deconsolidated from the outermost lpn,
8626 FOR lpn_rec IN nested_lpn_cursor LOOP
8627 -- Insert an 'UNPACK' transaction of child LPN from parent LPN into
8628 -- MTL_MATERIAL_TRANSACTIONS_TEMP using standard MMTT insert API
8629 l_return_status := INV_TRX_UTIL_PUB.INSERT_LINE_TRX (
8630 p_trx_hdr_id => l_trx_hdr_id
8631 , p_item_id => -1
8632 , p_org_id => p_organization_id
8633 , p_subinv_code => lpn_rec.subinventory_code
8634 , p_locator_id => lpn_rec.locator_id
8635 , p_trx_src_type_id => INV_GLOBALS.G_SourceType_Inventory
8636 , p_trx_action_id => INV_GLOBALS.G_Action_ContainerUnPack
8637 , p_trx_type_id => INV_GLOBALS.G_TYPE_CONTAINER_UNPACK
8638 , p_trx_qty => 1
8639 , p_pri_qty => 1
8640 , p_uom => 'Ea'
8641 , p_date => SYSDATE
8642 , p_user_id => fnd_global.user_id
8643 , p_from_lpn_id => lpn_rec.parent_lpn_id
8644 , p_cnt_lpn_id => lpn_rec.lpn_id
8645 , x_trx_tmp_id => l_trx_tmp_id
8646 , x_proc_msg => x_msg_data );
8647 IF (l_debug = 1) THEN
8648 mdebug('Inserted unpack tempid='||l_trx_tmp_id||' lpn='||lpn_rec.lpn_id||' parlpn='|| lpn_rec.parent_lpn_id, 4);
8649 END IF;
8650 -- Add entry for this lpn to print label
8651 l_input_param_rec_tbl(l_label_count).lpn_id := lpn_rec.lpn_id;
8652 l_label_count := l_label_count + 1;
8653 END LOOP;
8654
8655 IF (l_debug = 1) THEN
8656 mdebug('Call to TM hdrid='||l_trx_hdr_id, 4);
8657 END IF;
8658 l_return_status := INV_LPN_TRX_PUB.PROCESS_LPN_TRX (
8659 p_trx_hdr_id => l_trx_hdr_id
8660 , x_proc_msg => x_msg_data
8661 , p_proc_mode => 1
8662 , p_atomic => fnd_api.g_true );
8663 IF ( l_return_status <> 0 ) THEN
8664 IF (l_debug = 1) THEN
8665 mdebug('PROCESS_LPN_TRX Failed msg: '||x_msg_data, 1);
8666 END IF;
8667 RAISE fnd_api.g_exc_error;
8668 END IF;
8669
8670 -- Add entry for this lpn to print label for outermost lpn
8671 l_input_param_rec_tbl(l_label_count).lpn_id := p_outermost_lpn_id;
8672
8673 INV_LABEL.PRINT_LABEL (
8674 x_return_status => l_label_return
8675 , x_msg_count => x_msg_count
8676 , x_msg_data => x_msg_data
8677 , x_label_status => l_label_status
8678 , p_api_version => 1.0
8679 , p_print_mode => 2
8680 , p_business_flow_code => 36
8681 , p_input_param_rec => l_input_param_rec_tbl ) ;
8682
8683 IF ( l_debug = 1 ) THEN
8684 mdebug('Called INV_LABEL.PRINT_LABEL, return_status='||l_label_return||' label stat='||l_label_status, 1);
8685 END IF;
8686
8687 -- Standard check of p_commit.
8688 IF FND_API.To_Boolean( p_commit ) THEN
8689 COMMIT WORK;
8690 END IF;
8691
8692 FND_MSG_PUB.Count_And_Get( p_count => x_msg_count, p_data => x_msg_data );
8693 EXCEPTION
8694 WHEN OTHERS THEN
8695 IF (l_debug = 1) THEN
8696 mdebug(l_api_name ||' Error l_progress=' || l_progress, 1);
8697 IF ( SQLCODE IS NOT NULL ) THEN
8698 mdebug('SQL error: ' || SQLERRM(SQLCODE), 1);
8699 END IF;
8700 END IF;
8701
8702 ROLLBACK TO BREAK_DOWN_LPN;
8703 x_return_status := fnd_api.g_ret_sts_error;
8704 fnd_message.set_name('WMS', 'WMS_API_FAILURE');
8705 fnd_msg_pub.ADD;
8706 FND_MSG_PUB.Count_And_Get(p_count => x_msg_count, p_data => x_msg_data);
8707 END Break_Down_LPN;
8708
8709 -- ----------------------------------------------------------------------------------
8710 -- ----------------------------------------------------------------------------------
8711
8712 PROCEDURE Initialize_LPN (
8713 p_api_version IN NUMBER
8714 , p_init_msg_list IN VARCHAR2 := fnd_api.g_false
8715 , p_commit IN VARCHAR2 := fnd_api.g_false
8716 , x_return_status OUT NOCOPY VARCHAR2
8717 , x_msg_count OUT NOCOPY NUMBER
8718 , x_msg_data OUT NOCOPY VARCHAR2
8719 , p_organization_id IN NUMBER
8720 , p_outermost_lpn_id IN NUMBER
8721 )IS
8722 l_api_name CONSTANT VARCHAR2(30) := 'Initialize_LPNs';
8723 l_api_version CONSTANT NUMBER := 1.0;
8724 l_debug NUMBER := NVL(FND_PROFILE.VALUE('INV_DEBUG_TRACE'),0);
8725 l_progress VARCHAR2(10) := '0';
8726
8727 CURSOR nested_lpn_cursor IS
8728 SELECT rowid, lpn_id
8729 FROM wms_license_plate_numbers
8730 WHERE organization_id = p_organization_id
8731 AND outermost_lpn_id = p_outermost_lpn_id;
8732
8733 BEGIN
8734 -- Standard Start of API savepoint
8735 SAVEPOINT INITIALIZE_LPN;
8736
8737 -- Standard call to check for call compatibility.
8738 IF NOT fnd_api.compatible_api_call(l_api_version, p_api_version, l_api_name, g_pkg_name) THEN
8739 fnd_message.set_name('WMS', 'WMS_CONT_INCOMPATIBLE_API_CALL');
8740 fnd_msg_pub.ADD;
8741 RAISE fnd_api.g_exc_unexpected_error;
8742 END IF;
8743
8744 -- Initialize message list if p_init_msg_list is set to TRUE.
8745 IF fnd_api.to_boolean(p_init_msg_list) THEN
8746 fnd_msg_pub.initialize;
8747 END IF;
8748
8749 -- Initialize API return status to success
8750 x_return_status := FND_API.G_RET_STS_SUCCESS;
8751
8752 IF (l_debug = 1) THEN
8753 mdebug(l_api_name || ' Entered ' || g_pkg_version, 1);
8754 mdebug('orgid=' ||p_organization_id||' lpnid='||p_outermost_lpn_id, G_MESSAGE);
8755 END IF;
8756
8757 FOR lpn_rec IN nested_lpn_cursor LOOP
8758 IF (l_debug = 1) THEN
8759 mdebug('Initializing LPN with lpnid='||lpn_rec.lpn_id, G_MESSAGE);
8760 END IF;
8761
8762 -- Remove all contents from WLC
8763 DELETE FROM wms_lpn_contents
8764 WHERE parent_lpn_id = lpn_rec.lpn_id;
8765
8766 -- Reset lpn properties to pregenerated
8767 UPDATE wms_license_plate_numbers
8768 SET lpn_context = LPN_CONTEXT_PREGENERATED
8769 , subinventory_code = NULL
8770 , locator_id = NULL
8771 , parent_lpn_id = NULL
8772 , outermost_lpn_id = lpn_id
8773 , content_volume = NULL
8774 , content_volume_uom_code = NULL
8775 , gross_weight = tare_weight
8776 , gross_weight_uom_code = tare_weight_uom_code
8777 , last_update_date = SYSDATE
8778 , last_updated_by = fnd_global.user_id
8779 WHERE rowid = lpn_rec.rowid;
8780 END LOOP;
8781
8782 -- Standard check of p_commit.
8783 IF FND_API.To_Boolean( p_commit ) THEN
8784 COMMIT WORK;
8785 END IF;
8786
8787 FND_MSG_PUB.Count_And_Get( p_count => x_msg_count, p_data => x_msg_data );
8788 EXCEPTION
8789 WHEN OTHERS THEN
8790 IF (l_debug = 1) THEN
8791 mdebug(l_api_name ||' Error l_progress=' || l_progress, 1);
8792 IF ( SQLCODE IS NOT NULL ) THEN
8793 mdebug('SQL error: ' || SQLERRM(SQLCODE), 1);
8794 END IF;
8795 END IF;
8796
8797 ROLLBACK TO INITIALIZE_LPN;
8798 x_return_status := fnd_api.g_ret_sts_error;
8799 FND_MSG_PUB.Count_And_Get(p_count => x_msg_count, p_data => x_msg_data);
8800 END Initialize_LPN;
8801
8802 -- ----------------------------------------------------------------------------------
8803 -- ----------------------------------------------------------------------------------
8804
8805 PROCEDURE plan_delivery(p_lpn_id IN NUMBER,
8806 x_return_status OUT nocopy VARCHAR2,
8807 x_msg_data OUT nocopy VARCHAR2,
8808 x_msg_count OUT nocopy NUMBER) IS
8809
8810 l_action_prms wsh_interface_ext_grp.del_action_parameters_rectype;
8811 l_delivery_id_tab wsh_util_core.id_tab_type;
8812 l_delivery_out_rec wsh_interface_ext_grp.del_action_out_rec_type;
8813 l_delivery_id NUMBER;
8814
8815 l_return_status VARCHAR2(1);
8816 l_msg_count NUMBER;
8817 l_msg_data VARCHAR2(2000);
8818 l_debug NUMBER := NVL(FND_PROFILE.VALUE('INV_DEBUG_TRACE'),0);
8819 BEGIN
8820
8821 SELECT wda.delivery_id
8822 INTO l_delivery_id
8823 FROM wsh_delivery_details_ob_grp_v wdd,
8824 wsh_delivery_assignments wda
8825 WHERE wdd.lpn_id IN (SELECT lpn_id FROM wms_license_plate_numbers
8826 WHERE outermost_lpn_id = (SELECT outermost_lpn_id
8827 FROM wms_license_plate_numbers
8828 WHERE lpn_id = p_lpn_id)
8829 AND lpn_context = 11)
8830 AND wdd.released_status = 'X' -- For LPN reuse ER : 6845650
8831 AND wda.parent_delivery_detail_id = wdd.delivery_detail_id
8832 AND ROWNUM = 1;
8833
8834 IF l_delivery_id IS NOT NULL THEN
8835 l_action_prms.caller := 'WMS_DLMG';
8836 l_action_prms.event := wsh_interface_ext_grp.g_start_of_packing;
8837 l_action_prms.action_code := 'ADJUST-PLANNED-FLAG';
8838
8839 l_delivery_id_tab(1) := l_delivery_id;
8840
8841 wsh_interface_ext_grp.delivery_action
8842 (p_api_version_number => 1.0,
8843 p_init_msg_list => fnd_api.g_false,
8844 p_commit => fnd_api.g_false,
8845 p_action_prms => l_action_prms,
8846 p_delivery_id_tab => l_delivery_id_tab,
8847 x_delivery_out_rec => l_delivery_out_rec,
8848 x_return_status => l_return_status,
8849 x_msg_count => l_msg_count,
8850 x_msg_data => l_msg_data);
8851
8852 IF x_return_status = 'E' THEN
8853 RAISE fnd_api.g_exc_error;
8854 ELSIF x_return_status = 'U' THEN
8855 RAISE fnd_api.g_exc_unexpected_error;
8856 END IF;
8857 END IF;
8858
8859 x_return_status := 'S';
8860
8861 EXCEPTION
8862 WHEN fnd_api.g_exc_error THEN
8863 x_return_status := 'E';
8864 mdebug('Plan Delivery: Error: E', 1);
8865 WHEN fnd_api.g_exc_unexpected_error THEN
8866 x_return_status := 'U';
8867 mdebug('Plan Delivery: Error: U', 1);
8868 WHEN OTHERS THEN
8869 x_return_status := 'U';
8870 IF (l_debug = 1) THEN
8871 mdebug('Plan Delivery: Error: ' || Sqlerrm, 1);
8872 END IF;
8873 END plan_delivery;
8874
8875 -- End of package
8876 END WMS_CONTAINER_PVT;