[Home] [Help]
PACKAGE BODY: APPS.INV_CYC_LOVS
Source
1 PACKAGE BODY INV_CYC_LOVS AS
2 /* $Header: INVCYCLB.pls 120.29.12010000.4 2008/10/06 19:16:01 ammathew ship $ */
3
4 -- Global constant holding the package name
5 G_PKG_NAME CONSTANT VARCHAR2 ( 30 ) := 'INV_CYC_LOVS';
6 -- Global variables used to store information related to a cycle count entry
7 g_count_quantity NUMBER;
8 g_count_uom VARCHAR2 ( 3 );
9 g_count_secondary_quantity NUMBER; -- INVCONV, NSRIVAST
10 g_count_secondary_uom VARCHAR2 ( 3 ); -- INVCONV, NSRIVAST
11 g_cc_entry CC_ENTRY;
12 g_cc_serial_entry CC_SERIAL_ENTRY;
13 g_pre_approve_flag VARCHAR2 ( 20 ) := 'FALSE';
14 g_serial_out_tolerance BOOLEAN := FALSE;
15 g_txn_header_id NUMBER;
16 g_txn_proc_mode NUMBER;
17 g_user_id NUMBER;
18 g_login_id NUMBER;
19 g_commit_status_flag NUMBER;
20 g_update_flag NUMBER;
21 g_insert_flag NUMBER;
22 g_serial_number VARCHAR2 ( 30 );
23 g_employee_id NUMBER;
24 g_employee_full_name VARCHAR2 ( 240 );
25 -- These two following values correspond to form checkbox values
26 -- for the current cycle count serial entry used mainly for multiple
27 -- serial counting
28 g_unit_status NUMBER;
29 g_system_present NUMBER;
30 g_serial_entry_status_code NUMBER;
31 g_count_entry_status_code NUMBER;
32
33 /* Bug 4495880-Added the global parameter and defaulted it to FALSE */
34 g_condition BOOLEAN := FALSE;
35 /* End of fix for Bug 4495880 */
36 g_updated_prior BOOLEAN := FALSE; -- Bug 6371673
37
38
39 -- Name: GET_CYC_LOV
40 --
41 -- Input parameters:
42 -- p_cycle_count Restricts LOV SQL to the user input text
43 -- p_organization_id Organization ID
44 --
45 -- Output parameters:
46 -- x_cyc_lov Returns LOV rows as a reference cursor
47 --
48 -- Functions: This API returns valid cycle counts
49 --
50
51 PROCEDURE get_cyc_lov (
52 x_cyc_lov OUT NOCOPY t_genref,
53 p_cycle_count IN VARCHAR2,
54 p_organization_id IN NUMBER
55 )
56 IS
57 l_debug NUMBER := NVL ( FND_PROFILE.VALUE ( 'INV_DEBUG_TRACE' ), 0 );
58 BEGIN
59 OPEN x_cyc_lov FOR
60 SELECT cycle_count_header_name,
61 cycle_count_header_id,
62 description,
63 inventory_adjustment_account,
64 orientation_code,
65 onhand_visible_flag,
66 zero_count_flag,
67 disable_date,
68 approval_option_code,
69 automatic_recount_flag,
70 unscheduled_count_entry,
71 approval_tolerance_positive,
72 approval_tolerance_negative,
73 cost_tolerance_positive,
74 cost_tolerance_negative,
75 hit_miss_tolerance_positive,
76 hit_miss_tolerance_negative,
77 serial_count_option,
78 serial_detail_option,
79 serial_adjustment_option,
80 serial_discrepancy_option,
81 container_adjustment_option,
82 container_discrepancy_option,
83 container_enabled_flag,
84 cycle_count_type,
85 schedule_empty_locations
86 FROM mtl_cycle_count_headers
87 WHERE organization_id = p_organization_id
88 AND trunc(nvl(disable_date, sysdate+1)) > trunc(sysdate) --Changed for bug 5519506
89 AND cycle_count_header_name LIKE ( p_cycle_count )
90 AND ( ( cycle_count_header_id IN (
91 SELECT UNIQUE cycle_count_header_id
92 FROM mtl_cycle_count_entries
93 WHERE organization_id = p_organization_id
94 AND entry_status_code IN ( 1, 3 ) )
95 )
96 OR NVL ( unscheduled_count_entry, 2 ) = 1
97 )
98 ORDER BY 1;
99 END get_cyc_lov;
100
101 PROCEDURE print_debug (
102 p_err_msg VARCHAR2
103 )
104 IS
105 l_debug NUMBER := NVL ( FND_PROFILE.VALUE ( 'INV_DEBUG_TRACE' ), 0 );
106 BEGIN
107 IF ( l_debug = 1 ) THEN
108 inv_mobile_helper_functions.tracelog ( p_err_msg => p_err_msg,
109 p_module => 'INV_CYC_LOVS',
110 p_level => 4
111 );
112 END IF;
113 -- dbms_output.put_line(p_err_msg);
114 END print_debug;
115
116 -- This will do an autonomous commit to update the
117 -- cycle count header with the next user count sequence
118 -- value so that one user does not lock up the entire
119 -- table when performing a cycle count
120 PROCEDURE update_count_list_sequence (
121 p_organization_id NUMBER,
122 p_cycle_count_header_id NUMBER,
123 x_count_list_sequence OUT NOCOPY NUMBER
124 )
125 IS
126 PRAGMA AUTONOMOUS_TRANSACTION;
127 l_count_list_sequence NUMBER;
128 l_debug NUMBER := NVL ( FND_PROFILE.VALUE ( 'INV_DEBUG_TRACE' ), 0 );
129 BEGIN
130 -- Calculate the next value for the count list sequence
131 SELECT NVL ( MAX ( count_list_sequence ), 0 ) + 1
132 INTO l_count_list_sequence
133 FROM mtl_cycle_count_entries
134 WHERE cycle_count_header_id = p_cycle_count_header_id
135 AND organization_id = p_organization_id;
136
137 -- Update this value for the cycle count header
138 UPDATE mtl_cycle_count_headers
139 SET next_user_count_sequence = l_count_list_sequence + 1
140 WHERE cycle_count_header_id = p_cycle_count_header_id
141 AND organization_id = p_organization_id;
142
143 COMMIT;
144 -- Set the output value
145 x_count_list_sequence := l_count_list_sequence;
146 END update_count_list_sequence;
147
148 PROCEDURE process_entry (
149 p_cycle_count_header_id IN NUMBER,
150 p_organization_id IN NUMBER,
151 p_subinventory IN VARCHAR2,
152 p_locator_id IN NUMBER,
153 p_parent_lpn_id IN NUMBER,
154 p_inventory_item_id IN NUMBER,
155 p_revision IN VARCHAR2,
156 p_lot_number IN VARCHAR2,
157 p_from_serial_number IN VARCHAR2,
158 p_to_serial_number IN VARCHAR2,
159 p_count_quantity IN NUMBER,
160 p_count_uom IN VARCHAR2,
161 p_unscheduled_count_entry IN NUMBER,
162 p_user_id IN NUMBER,
163 p_cost_group_id IN NUMBER
164 ,p_secondary_uom IN VARCHAR2 -- INVCONV, NSRIVAST
165 ,p_secondary_qty IN NUMBER -- INVCONV, NSRIVAST
166
167 )
168 IS
169 l_current_serial VARCHAR2 ( 30 );
170
171 CURSOR cc_entry_cursor
172 IS
173 SELECT *
174 FROM mtl_cycle_count_entries
175 WHERE cycle_count_header_id = p_cycle_count_header_id
176 AND organization_id = p_organization_id
177 AND subinventory = p_subinventory
178 AND NVL ( locator_id, -99999 ) = NVL ( p_locator_id, -99999 )
179 AND NVL ( parent_lpn_id, -99999 ) = NVL ( p_parent_lpn_id, -99999 )
180 AND inventory_item_id = p_inventory_item_id
181 AND NVL ( revision, '@@@@@' ) = NVL ( p_revision, '@@@@@' )
182 AND NVL ( lot_number, '@@@@@' ) = NVL ( p_lot_number, '@@@@@' )
183 AND NVL ( serial_number, '@@@@@' ) =
184 NVL ( l_current_serial, '@@@@@' )
185 AND entry_status_code IN ( 1, 3 );
186
187 CURSOR cc_multiple_serial_cursor
188 IS
189 SELECT *
190 FROM mtl_cycle_count_entries
191 WHERE cycle_count_header_id = p_cycle_count_header_id
192 AND organization_id = p_organization_id
193 AND subinventory = p_subinventory
194 AND NVL ( locator_id, -99999 ) = NVL ( p_locator_id, -99999 )
195 AND NVL ( parent_lpn_id, -99999 ) = NVL ( p_parent_lpn_id, -99999 )
196 AND inventory_item_id = p_inventory_item_id
197 AND NVL ( revision, '@@@@@' ) = NVL ( p_revision, '@@@@@' )
198 AND NVL ( lot_number, '@@@@@' ) = NVL ( p_lot_number, '@@@@@' )
199 AND entry_status_code IN ( 1, 3 );
200
201 CURSOR cc_discrepant_cursor
202 IS
203 SELECT *
204 FROM mtl_cycle_count_entries
205 WHERE cycle_count_header_id = p_cycle_count_header_id
206 AND organization_id = p_organization_id
207 AND NVL ( parent_lpn_id, -99999 ) = NVL ( p_parent_lpn_id, -99999 )
208 AND inventory_item_id = p_inventory_item_id
209 AND NVL ( revision, '@@@@@' ) = NVL ( p_revision, '@@@@@' )
210 AND NVL ( lot_number, '@@@@@' ) = NVL ( p_lot_number, '@@@@@' )
211 AND NVL ( serial_number, '@@@@@' ) =
212 NVL ( l_current_serial, '@@@@@' )
213 AND entry_status_code IN ( 1, 3 );
214
215 CURSOR cc_discrepant_multiple_cursor
216 IS
217 SELECT *
218 FROM mtl_cycle_count_entries
219 WHERE cycle_count_header_id = p_cycle_count_header_id
220 AND organization_id = p_organization_id
221 AND NVL ( parent_lpn_id, -99999 ) = NVL ( p_parent_lpn_id, -99999 )
222 AND inventory_item_id = p_inventory_item_id
223 AND NVL ( revision, '@@@@@' ) = NVL ( p_revision, '@@@@@' )
224 AND NVL ( lot_number, '@@@@@' ) = NVL ( p_lot_number, '@@@@@' )
225 AND entry_status_code IN ( 1, 3 );
226
227 -- Bug# 2708133
228 -- Add this cursor to use for discrepant serials.
229 -- Note that we don't match against sub, loc, rev, lot, or LPN
230 -- to allow for location discrepancies as well as rev, lot, and LPN
231 CURSOR cc_discrepant_serial_cursor
232 IS
233 SELECT *
234 FROM mtl_cycle_count_entries
235 WHERE cycle_count_header_id = p_cycle_count_header_id
236 AND organization_id = p_organization_id
237 AND inventory_item_id = p_inventory_item_id
238 AND serial_number = NVL ( l_current_serial, '@@@@@' )
239 AND entry_status_code IN ( 1, 3 );
240
241 l_prefix VARCHAR2 ( 30 );
242 l_quantity NUMBER;
243 l_from_number NUMBER;
244 l_to_number NUMBER;
245 l_errorcode NUMBER;
246 l_length NUMBER;
247 l_padded_length NUMBER;
248 l_current_number NUMBER;
249 l_serial_discrepancy NUMBER;
250 l_container_discrepancy NUMBER;
251 -- Bug# 2386128
252 -- Don't need this variable anymore
253 --l_count_list_sequence NUMBER;
254 l_cost_group_id NUMBER;
255 l_dispatched_count NUMBER;
256 l_dispatched_task NUMBER;
257 e_Task_Dispatched EXCEPTION;
258 l_debug NUMBER := NVL ( FND_PROFILE.VALUE ( 'INV_DEBUG_TRACE' ), 0 );
259
260 /* Bug 4891916-Added the following local variables for the call to label printing */
261 l_print_label NUMBER := NVL(FND_PROFILE.VALUE('WMS_LABEL_FOR_CYCLE_COUNT'),2);
262 l_business_flow_code NUMBER := 8;
263 l_label_status VARCHAR2 ( 300 ) := NULL;
264 l_return_status VARCHAR2(1) := fnd_api.g_ret_sts_success;
265 l_msg_count NUMBER;
266 l_msg_data VARCHAR2(240);
267 /* End of fix for Bug 4891916 */
268
269 BEGIN
270 IF ( l_debug = 1 ) THEN
271 print_debug ( '***Calling process_entry with the following parameters***'
272 );
273 print_debug ( 'p_cycle_count_header_id: ===> '
274 || p_cycle_count_header_id
275 );
276 print_debug ( 'p_organization_id: =========> ' || p_organization_id );
277 print_debug ( 'p_subinventory: ============> ' || p_subinventory );
278 print_debug ( 'p_locator_id: ==============> ' || p_locator_id );
279 print_debug ( 'p_parent_lpn_id: ===========> ' || p_parent_lpn_id );
280 print_debug ( 'p_inventory_item_id: =======> ' || p_inventory_item_id );
281 print_debug ( 'p_revision: ================> ' || p_revision );
282 print_debug ( 'p_lot_number: ==============> ' || p_lot_number );
283 print_debug ( 'p_from_serial_number: ======> '
284 || p_from_serial_number
285 );
286 print_debug ( 'p_to_serial_number: ========> ' || p_to_serial_number );
287 print_debug ( 'p_count_quantity: ==========> ' || p_count_quantity );
288 print_debug ( 'p_count_uom: ===============> ' || p_count_uom );
289 print_debug ( 'p_unscheduled_count_entry: => '
290 || p_unscheduled_count_entry
291 );
292 print_debug ( 'p_user_id: =================> ' || p_user_id );
293 print_debug ( 'p_cost_group_id: ===========> ' || p_cost_group_id );
294 print_debug ( 'p_secondary_uom: ===========> ' || p_secondary_uom ); -- INVCONV, NSRIVAST
295 print_debug ( 'p_secondary_qty: ===========> ' || p_secondary_qty ); -- INVCONV, NSRIVAST
296
297
298 END IF;
299
300 -- Initialize the message stack
301 FND_MSG_PUB.initialize;
302 -- Set the global variables
303 g_count_quantity := p_count_quantity;
304 g_count_uom := p_count_uom;
305 g_user_id := p_user_id;
306 g_count_secondary_quantity := p_secondary_qty ; -- INVCONV, NSRIVAST
307 g_count_secondary_uom := p_secondary_uom ; -- INVCONV, NSRIVAST
308 -- Get the profile values
309 get_profiles ( );
310 -- Get the employee ID information
311 get_employee ( p_organization_id => p_organization_id );
312
313 IF ( l_debug = 1 ) THEN
314 print_debug ( 'Employee ID: ' || g_employee_id );
315 END IF;
316
317 BEGIN
318 SELECT MIN ( cycle_count_entry_id )
319 INTO l_dispatched_task
320 FROM mtl_cycle_count_entries
321 WHERE cycle_count_header_id = p_cycle_count_header_id
322 AND organization_id = p_organization_id
323 AND subinventory = p_subinventory
324 AND NVL ( locator_id, -99999 ) = NVL ( p_locator_id, -99999 )
325 AND inventory_item_id = p_inventory_item_id
326 AND NVL ( revision, '@@@@@' ) = NVL ( p_revision, '@@@@@' )
327 AND entry_status_code IN ( 1, 3 );
328 EXCEPTION
329 WHEN NO_DATA_FOUND THEN
330 l_dispatched_task := -99999;
331 END;
332
333 IF ( l_debug = 1 ) THEN
334 print_debug ( 'Task Temp ID: ' || l_dispatched_task );
335 END IF;
336
337 SELECT COUNT ( * )
338 INTO l_dispatched_count
339 FROM wms_dispatched_tasks
340 WHERE task_type = 3
341 AND organization_id = p_organization_id
342 AND transaction_temp_id = l_dispatched_task
343 AND person_id <> NVL ( g_employee_id, -999 );
344
345 IF ( l_debug = 1 ) THEN
346 print_debug ( 'Dispatched Count: ' || l_dispatched_count );
347 END IF;
348
349 -- Cycle Counting task has already been dispatched
350 IF ( l_dispatched_count <> 0 ) THEN
351 IF ( l_debug = 1 ) THEN
352 print_debug ( 'The cycle count entry has already been dispatched as a '
353 || 'task to another user'
354 );
355 END IF;
356
357 RAISE e_Task_Dispatched;
358 END IF;
359
360 -- Check if the cycle count item is a serial controlled item
361 -- This is for single serial count option only
362 IF ( ( p_from_serial_number IS NOT NULL )
363 AND ( p_to_serial_number IS NOT NULL )
364 ) THEN
365 IF ( l_debug = 1 ) THEN
366 print_debug ( 'Single Serial controlled item' );
367 END IF;
368
369 -- Call this API to parse the serial numbers into prefixes and numbers
370 IF ( NOT MTL_Serial_Check.inv_serial_info ( p_from_serial_number => p_from_serial_number,
371 p_to_serial_number => p_to_serial_number,
372 x_prefix => l_prefix,
373 x_quantity => l_quantity,
374 x_from_number => l_from_number,
375 x_to_number => l_to_number,
376 x_errorcode => l_errorcode
377 )
378 ) THEN
379 FND_MESSAGE.SET_NAME ( 'WMS', 'WMS_CONT_INVALID_SER' );
380 FND_MSG_PUB.ADD;
381 RAISE FND_API.G_EXC_ERROR;
382 END IF;
383
384 -- Check that in the case of a range of serial numbers, that the
385 -- inputted p_count_quantity equals the amount of items in the serial range.
386 IF ( ( p_count_quantity <> l_quantity )
387 AND ( p_count_quantity <> 0 )
388 ) THEN
389 FND_MESSAGE.SET_NAME ( 'WMS', 'WMS_CONT_INVALID_X_QTY' );
390 FND_MSG_PUB.ADD;
391 RAISE FND_API.G_EXC_ERROR;
392 END IF;
393
394 -- Get the serial number length.
395 -- Note that the from and to serial numbers must be of the same length.
396 l_length := LENGTH ( p_from_serial_number );
397 -- Initialize the current pointer variables
398 l_current_serial := p_from_serial_number;
399 l_current_number := l_from_number;
400
401 LOOP
402 -- For each serial number check if a cycle count entry for it already
403 -- exists or not
404 OPEN cc_entry_cursor;
405 FETCH cc_entry_cursor INTO g_cc_entry;
406
407 IF ( cc_entry_cursor%FOUND ) THEN
408 -- Entry already exists so update the row
409 pre_update ( );
410 update_row ( );
411 ELSE
412 -- Get the serial and container discrepancy options for the cycle count
413 SELECT NVL ( serial_discrepancy_option, 2 ),
414 NVL ( container_discrepancy_option, 2 )
415 INTO l_serial_discrepancy,
416 l_container_discrepancy
417 FROM mtl_cycle_count_headers
418 WHERE cycle_count_header_id = p_cycle_count_header_id
419 AND organization_id = p_organization_id;
420
421 -- Check to see if the serial entry exists but is in
422 -- a discrepant location, i.e. different sub/loc
423 -- Bug# 2708133
424 -- Use cc_discrepant_serial_cursor instead which will also
425 -- allow for rev, lot, and LPN discrepancies for serials
426 OPEN cc_discrepant_serial_cursor;
427 FETCH cc_discrepant_serial_cursor INTO g_cc_entry;
428
429 -- Allow discrepancies if serial discrepancy is allowed
430 -- Bug# 2708133
431 -- We only care if serial discrepancies are allowed now
432 IF ( cc_discrepant_serial_cursor%FOUND
433 AND l_serial_discrepancy = 1
434 ) THEN
435 -- Discrepant serial entry exists so process it
436 IF ( l_debug = 1 ) THEN
437 print_debug ( 'Discrepant single serial entry exists' );
438 END IF;
439
440 -- Update the sub and loc information
441 -- Bug# 2708133
442 -- Also update the rev, lot, and LPN
443 g_cc_entry.subinventory := p_subinventory;
444 g_cc_entry.locator_id := p_locator_id;
445 g_cc_entry.revision := p_revision;
446 g_cc_entry.lot_number := p_lot_number;
447 g_cc_entry.parent_lpn_id := p_parent_lpn_id;
448 pre_update ( );
449 update_row ( );
450 ELSE
451 -- Entry does not exist at all
452 IF ( p_unscheduled_count_entry = 1 ) THEN
453 -- Unscheduled entries are allowed so insert the record
454 IF ( l_debug = 1 ) THEN
455 print_debug ( 'Unscheduled single serial entry to be inserted'
456 );
457 END IF;
458
459 -- Call this procedure to calculate and update the next
460 -- value for the count list sequence
461 --print_debug('Calling update_count_list_sequence');
462 -- Bug# 2386128
463 -- Dont call this anymore. Similar to Bug# 1803246 for
464 -- the desktop forms, when doing an unscheduled cycle
465 -- count, we will use the cycle count entry ID as the
466 -- value for the count list sequence
467 /*update_count_list_sequence
468 (p_organization_id => p_organization_id,
469 p_cycle_count_header_id => p_cycle_count_header_id,
470 x_count_list_sequence => l_count_list_sequence);*/
471
472 -- Get the cost group ID for this entry
473 get_cost_group_id ( p_organization_id => p_organization_id,
474 p_subinventory => p_subinventory,
475 p_locator_id => p_locator_id,
476 p_parent_lpn_id => p_parent_lpn_id,
477 p_inventory_item_id => p_inventory_item_id,
478 p_revision => p_revision,
479 p_lot_number => p_lot_number,
480 p_serial_number => l_current_serial,
481 x_out => l_cost_group_id
482 );
483
484 -- Bug# 2607187
485 -- Do not get the default cost group ID. If the item is
486 -- new and does not exist in onhand, pass a NULL value
487 -- for the cost group ID. The transaction manager will
488 -- call the cost group rules engine for that if the
489 -- cost group ID passed into MMTT is null.
490 IF ( l_cost_group_id = -999 ) THEN
491 l_cost_group_id := NULL;
492 END IF;
493
494 -- Get the default cost group ID based on the given org
495 -- and sub if cost group ID was not retrieved successfully
496 /*IF (l_cost_group_id = -999) THEN
497 get_default_cost_group_id
498 (p_organization_id => p_organization_id,
499 p_subinventory => p_subinventory,
500 x_out => l_cost_group_id);
501 END IF;
502 -- Default the cost group ID to 1 if nothing can be found
503 IF (l_cost_group_id = -999) THEN
504 l_cost_group_id := 1;
505 END IF;*/
506
507 -- First prepare the entry record
508 g_cc_entry.cycle_count_entry_id := NULL;
509 g_cc_entry.cycle_count_header_id :=
510 p_cycle_count_header_id;
511 g_cc_entry.organization_id := p_organization_id;
512 g_cc_entry.subinventory := p_subinventory;
513 g_cc_entry.locator_id := p_locator_id;
514 g_cc_entry.inventory_item_id := p_inventory_item_id;
515 g_cc_entry.revision := p_revision;
516 g_cc_entry.lot_number := p_lot_number;
517 g_cc_entry.serial_number := l_current_serial;
518 g_cc_entry.parent_lpn_id := p_parent_lpn_id;
519 g_cc_entry.cost_group_id := l_cost_group_id;
520 g_cc_entry.entry_status_code := 1;
521 g_cc_entry.last_update_date := SYSDATE;
522 g_cc_entry.last_updated_by := p_user_id;
523 g_cc_entry.creation_date := SYSDATE;
524 g_cc_entry.created_by := p_user_id;
525 g_cc_entry.last_update_login := g_login_id;
526 g_cc_entry.count_list_sequence := NULL;
527 g_cc_entry.count_type_code := 2;
528 g_cc_entry.number_of_counts := 0;
529 -- Now insert the record
530 pre_insert ( );
531 insert_row ( );
532 ELSE
533 -- Unscheduled entries are not allowed
534 IF ( l_debug = 1 ) THEN
535 print_debug ( 'Unscheduled entries are not allowed' );
536 END IF;
537 --FND_MESSAGE.SET_NAME('INV', 'INV_NO_UNSCHED_COUNTS');
538 --FND_MSG_PUB.ADD;
539 --RAISE FND_API.G_EXC_ERROR;
540 END IF;
541 END IF;
542
543 CLOSE cc_discrepant_serial_cursor;
544 END IF;
545
546 CLOSE cc_entry_cursor;
547 EXIT WHEN l_current_serial = p_to_serial_number;
548 -- Increment the current serial number
549 l_current_number := l_current_number + 1;
550 l_padded_length := l_length - LENGTH ( l_current_number );
551 l_current_serial :=
552 RPAD ( l_prefix, l_padded_length, '0' )
553 || l_current_number;
554 END LOOP;
555 -- This is for multiple serial count option
556 ELSIF ( p_count_quantity IS NULL ) THEN
557 IF ( l_debug = 1 ) THEN
558 print_debug ( 'Multiple serial controlled item' );
559 END IF;
560
561 -- Set a savepoint
562 SAVEPOINT save_serial_detail;
563 -- For the inputted entries, see if a multiple serial
564 -- cycle count entry for it exists
565 OPEN cc_multiple_serial_cursor;
566 FETCH cc_multiple_serial_cursor INTO g_cc_entry;
567
568 IF ( cc_multiple_serial_cursor%FOUND ) THEN
569 -- The entry exists so process all of the multiple
570 -- serial cycle count entries associated with it
571 ok_proc ( );
572 pre_update ( );
573 update_row ( );
574 ELSE
575 -- Get the serial and container discrepancy options for the cycle count
576 SELECT NVL ( serial_discrepancy_option, 2 ),
577 NVL ( container_discrepancy_option, 2 )
578 INTO l_serial_discrepancy,
579 l_container_discrepancy
580 FROM mtl_cycle_count_headers
581 WHERE cycle_count_header_id = p_cycle_count_header_id
582 AND organization_id = p_organization_id;
583
584 -- Check to see if the multiple serial entry exists but
585 -- is in a discrepant location, i.e. different sub/loc
586 OPEN cc_discrepant_multiple_cursor;
587 FETCH cc_discrepant_multiple_cursor INTO g_cc_entry;
588
589 -- Allow discrepancies if container discrepancy is allowed and
590 -- there is an LPN, or serial discrepancy is allowed and there
591 -- is no LPN
592 IF ( cc_discrepant_multiple_cursor%FOUND
593 AND ( ( l_container_discrepancy = 1
594 AND p_parent_lpn_id IS NOT NULL
595 )
596 OR ( l_serial_discrepancy = 1
597 AND p_parent_lpn_id IS NULL
598 )
599 )
600 ) THEN
601 -- Discrepant multiple serial entry exists so process it
602 IF ( l_debug = 1 ) THEN
603 print_debug ( 'Discrepant multiple serial entry exists' );
604 END IF;
605
606 -- Update the sub and loc information
607 g_cc_entry.subinventory := p_subinventory;
608 g_cc_entry.locator_id := p_locator_id;
609 ok_proc ( );
610 pre_update ( );
611 update_row ( );
612 ELSE
613 -- Unscheduled multiple count entried are
614 -- not being supported right now
615 IF ( l_debug = 1 ) THEN
616 print_debug ( 'Unscheduled multiple serial count' );
617 END IF;
618 END IF;
619
620 CLOSE cc_discrepant_multiple_cursor;
621 END IF;
622
623 CLOSE cc_multiple_serial_cursor;
624 ELSE -- Item is not serial controlled
625 IF ( l_debug = 1 ) THEN
626 print_debug ( 'Non serial controlled item' );
627 END IF;
628
629 OPEN cc_entry_cursor;
630 FETCH cc_entry_cursor INTO g_cc_entry;
631
632 IF ( cc_entry_cursor%FOUND ) THEN
633 pre_update ( );
634 update_row ( );
635 ELSE
636 -- Get the container discrepancy option for the cycle count
637 SELECT NVL ( container_discrepancy_option, 2 )
638 INTO l_container_discrepancy
639 FROM mtl_cycle_count_headers
640 WHERE cycle_count_header_id = p_cycle_count_header_id
641 AND organization_id = p_organization_id;
642
643 -- Check to see if the entry exists but
644 -- is in a discrepant location, i.e. different sub/loc
645 OPEN cc_discrepant_cursor;
646 FETCH cc_discrepant_cursor INTO g_cc_entry;
647
648 -- Allow discrepancies if container discrepancy is allowed and
649 -- there is an LPN
650 IF ( cc_discrepant_cursor%FOUND
651 AND ( l_container_discrepancy = 1
652 AND p_parent_lpn_id IS NOT NULL
653 )
654 ) THEN
655 -- Discrepant containerized entry exists so process it
656 IF ( l_debug = 1 ) THEN
657 print_debug ( 'Discrepant non-serial entry exists' );
658 END IF;
659
660 -- Update the sub and loc information
661 g_cc_entry.subinventory := p_subinventory;
662 g_cc_entry.locator_id := p_locator_id;
663 pre_update ( );
664 update_row ( );
665 ELSE
666 -- Entry does not exist at all
667 IF ( p_unscheduled_count_entry = 1 ) THEN
668 -- Unscheduled entries are allowed so insert the record
669 IF ( l_debug = 1 ) THEN
670 print_debug ( 'Unscheduled non-serial entry to be inserted'
671 );
672 END IF;
673
674 -- Call this procedure to calculate and update the next
675 -- value for the count list sequence
676 --print_debug('Calling update_count_list_sequence');
677 -- Bug# 2386128
678 -- Don't call this anymore. Similar to Bug# 1803246 for
679 -- the desktop forms, when doing an unscheduled cycle
680 -- count, we will use the cycle count entry ID as the
681 -- value for the count list sequence
682 /*update_count_list_sequence
683 (p_organization_id => p_organization_id,
684 p_cycle_count_header_id => p_cycle_count_header_id,
685 x_count_list_sequence => l_count_list_sequence);*/
686
687 -- Get the cost group ID for this entry
688 get_cost_group_id ( p_organization_id => p_organization_id,
689 p_subinventory => p_subinventory,
690 p_locator_id => p_locator_id,
691 p_parent_lpn_id => p_parent_lpn_id,
692 p_inventory_item_id => p_inventory_item_id,
693 p_revision => p_revision,
694 p_lot_number => p_lot_number,
695 p_serial_number => NULL,
696 x_out => l_cost_group_id
697 );
698
699 -- Bug# 2607187
700 -- Do not get the default cost group ID. If the item is
701 -- new and does not exist in onhand, pass a NULL value
702 -- for the cost group ID. The transaction manager will
703 -- call the cost group rules engine for that if the
704 -- cost group ID passed into MMTT is null.
705 IF ( l_cost_group_id = -999 ) THEN
706 l_cost_group_id := NULL;
707 END IF;
708
709 -- Get the default cost group ID based on the given org
710 -- and sub if cost group ID was not retrieved successfully
711 /*IF (l_cost_group_id = -999) THEN
712 get_default_cost_group_id
713 (p_organization_id => p_organization_id,
714 p_subinventory => p_subinventory,
715 x_out => l_cost_group_id);
716 END IF;
717 -- Default the cost group ID to 1 if nothing can be found
718 IF (l_cost_group_id = -999) THEN
719 l_cost_group_id := 1;
720 END IF;*/
721
722 -- First prepare the entry record
723 g_cc_entry.cycle_count_entry_id := NULL;
724 g_cc_entry.cycle_count_header_id := p_cycle_count_header_id;
725 g_cc_entry.organization_id := p_organization_id;
726 g_cc_entry.subinventory := p_subinventory;
727 g_cc_entry.locator_id := p_locator_id;
728 g_cc_entry.inventory_item_id := p_inventory_item_id;
729 g_cc_entry.revision := p_revision;
730 g_cc_entry.lot_number := p_lot_number;
731 g_cc_entry.serial_number := NULL;
732 g_cc_entry.parent_lpn_id := p_parent_lpn_id;
733 g_cc_entry.cost_group_id := l_cost_group_id;
734 g_cc_entry.entry_status_code := 1;
735 g_cc_entry.last_update_date := SYSDATE;
736 g_cc_entry.last_updated_by := p_user_id;
737 g_cc_entry.creation_date := SYSDATE;
738 g_cc_entry.created_by := p_user_id;
739 g_cc_entry.last_update_login := g_login_id;
740 g_cc_entry.count_list_sequence := NULL;
741 g_cc_entry.count_type_code := 2;
742 g_cc_entry.number_of_counts := 0;
743 -- Now insert the record
744 pre_insert ( );
745 insert_row ( );
746 ELSE
747 -- Unscheduled entries are not allowed
748 IF ( l_debug = 1 ) THEN
749 print_debug ( 'Unscheduled entries are not allowed' );
750 END IF;
751 --FND_MESSAGE.SET_NAME('INV', 'INV_NO_UNSCHED_COUNTS');
752 --FND_MSG_PUB.ADD;
753 --RAISE FND_API.G_EXC_ERROR;
754 END IF;
755 END IF;
756
757 CLOSE cc_discrepant_cursor;
758 END IF;
759
760 CLOSE cc_entry_cursor;
761 END IF;
762
763 /* Bug 4891916 -Calling the label printing api if the profile value corresponds to
764 At Entry(1) or At Entry and Approval(3) */
765
766 IF (l_print_label IN (1,3) ) THEN
767
768 IF ( l_debug = 1 ) THEN
769 print_debug ( 'Values of parameters passed to label printing API:' );
770 print_debug ( 'Values of l_business_flow_code'|| l_business_flow_code );
771 print_debug ( 'Values of g_cc_entry.cycle_count_entry_id'|| g_cc_entry.cycle_count_entry_id );
772 END IF;
773 /* Calling with the value of p_transaction_identifier as 4.
774 In the label printing code, this value will indicate
775 that the call is at the time of performing a cycle count entry
776 The value of p_transaction_identifier 5 in the label printing api
777 indicates that the call is at the time of approving counts.*/
778
779 inv_label.print_label_wrap
780 ( x_return_status => l_return_status ,
781 x_msg_count => l_msg_count ,
782 x_msg_data => l_msg_data ,
783 x_label_status => l_label_status ,
784 p_business_flow_code => l_business_flow_code ,
785 p_transaction_id => g_cc_entry.cycle_count_entry_id ,
786 p_transaction_identifier => 4);
787
788 IF ( l_debug = 1 ) THEN
789 print_debug ( 'Values of l_return_status:'|| l_return_status );
790 print_debug ( 'Values of l_msg_count:'|| l_msg_count );
791 print_debug ( 'Values of l_label_status'|| l_label_status );
792 END IF;
793
794 IF (l_return_status <> fnd_api.g_ret_sts_success) THEN
795 IF (l_debug = 1) THEN
796 print_debug('**Label Printing returned error:' || l_return_status);
797 END IF;
798 END IF;
799
800 END IF ; --End of check for l_print_label value
801
802 /* End of fix for Bug 4891916 */
803
804
805 IF ( l_debug = 1 ) THEN
806 print_debug ( '***End of process_entry***' );
807 END IF;
808 EXCEPTION
809 WHEN e_Task_Dispatched THEN
810 FND_MESSAGE.SET_NAME ( 'WMS', 'WMS_TD_CYC_TASK_ERROR' );
811 FND_MSG_PUB.ADD;
812
813 IF ( l_debug = 1 ) THEN
814 print_debug ( '***End of process_entry***' );
815 END IF;
816 END process_entry;
817
818 /* start of fix for 4539926 */
819 PROCEDURE delete_wdt(
820 p_cycle_count_header_id IN NUMBER ,
821 p_organization_id IN NUMBER ,
822 p_subinventory IN VARCHAR2 ,
823 p_locator_id IN NUMBER ,
824 p_parent_lpn_id IN NUMBER ,
825 p_inventory_item_id IN NUMBER ,
826 p_revision IN VARCHAR2 ,
827 p_lot_number IN VARCHAR2 ,
828 p_from_serial_number IN VARCHAR2 ,
829 p_to_serial_number IN VARCHAR2 ,
830 p_count_quantity IN NUMBER ,
831 p_count_uom IN VARCHAR2 ,
832 p_unscheduled_count_entry IN NUMBER ,
833 p_user_id IN NUMBER ,
834 p_cost_group_id IN NUMBER )
835
836 IS
837 l_cycle_count_entry_id NUMBER;
838 l_debug NUMBER := NVL ( FND_PROFILE.VALUE ( 'INV_DEBUG_TRACE' ), 0 );
839
840 CURSOR cc_entry_cursor
841 IS
842 SELECT cycle_count_entry_id
843 FROM mtl_cycle_count_entries mcce, wms_dispatched_tasks wdt
844 WHERE mcce.cycle_count_header_id = p_cycle_count_header_id
845 AND mcce.cycle_count_entry_id = wdt.transaction_temp_id
846 AND mcce.organization_id = p_organization_id
847 AND mcce.subinventory = p_subinventory
848 AND mcce.locator_id = p_locator_id
849 AND NVL (mcce.parent_lpn_id, -99999) = NVL ( p_parent_lpn_id, -99999)
850 AND mcce.inventory_item_id = NVL (p_inventory_item_id, mcce.inventory_item_id)
851 AND NVL (mcce.revision, '@@@@@' ) = NVL (p_revision , '@@@@@' )
852 AND NVL (mcce.lot_number, '@@@@@' ) = NVL ( p_lot_number, '@@@@@' )
853 AND NVL (mcce.serial_number, '@@@@@' ) = NVL ( p_from_serial_number, '@@@@@' )
854 AND NVL (mcce.serial_number, '@@@@@' ) = NVL ( p_to_serial_number, '@@@@@' )
855 AND mcce.entry_status_code IN (2, 4, 5 );
856
857 BEGIN
858 IF ( l_debug = 1 ) THEN
859 print_debug ( '***In delete_wdt ***');
860 print_debug ( 'p_cycle_count_header_id: ===> '
861 || p_cycle_count_header_id);
862 print_debug ( 'p_organization_id: =========> ' || p_organization_id );
863 print_debug ( 'p_subinventory: ============> ' || p_subinventory );
864 print_debug ( 'p_locator_id: ==============> ' || p_locator_id );
865 print_debug ( 'p_parent_lpn_id: ===========> ' || p_parent_lpn_id );
866 print_debug ( 'p_inventory_item_id: =======> ' || p_inventory_item_id );
867 print_debug ( 'p_revision: ================> ' || p_revision );
868 print_debug ( 'p_lot_number: ==============> ' || p_lot_number );
869 print_debug ( 'p_from_serial_number: ======> '
870 || p_from_serial_number);
871 print_debug ( 'p_to_serial_number: ========> ' || p_to_serial_number );
872 print_debug ( 'p_count_quantity: ==========> ' || p_count_quantity );
873 print_debug ( 'p_count_uom: ===============> ' || p_count_uom );
874 print_debug ( 'p_unscheduled_count_entry: => '
875 || p_unscheduled_count_entry);
876 print_debug ( 'p_user_id: =================> ' || p_user_id );
877 print_debug ( 'p_cost_group_id: ===========> ' || p_cost_group_id );
878 END IF;
879
880 -- Initialize the message stack
881 FND_MSG_PUB.initialize;
882
883 -- To fetch the cycle count entry ids which are in status 2,4,5.
884 -- for these entries if a record in wms_dispatched_tasks exists,
885 -- it has to be deleted
886
887 OPEN cc_entry_cursor;
888 LOOP
889
890 FETCH cc_entry_cursor INTO l_cycle_count_entry_id;
891 IF ( cc_entry_cursor%FOUND ) THEN
892 IF ( l_debug = 1 ) THEN
893 print_debug ( 'Approval Pending/ Rejected/ Completed cycle count entries found' );
894 print_debug( 'Cycle count Entry Id: ' || l_cycle_count_entry_id);
895 END IF;
896 BEGIN
897 DELETE FROM wms_dispatched_tasks wdt
898 WHERE wdt.transaction_temp_id = l_cycle_count_entry_id;
899 IF ( l_debug = 1 ) THEN
900 print_debug('** Deleted wms_dispatched_tasks record with transaction_temp_id : ' || l_cycle_count_entry_id);
901 END IF;
902 EXCEPTION
903 WHEN OTHERS THEN
904 IF ( l_debug = 1 ) THEN
905 print_debug('Deleting wms_dispatched_tasks record failed');
906 END IF;
907 END;
908 ELSE
909 IF ( l_debug = 1 ) THEN
910 print_debug ( 'No Approval Pending/ Rejected/ Completed cycle count entries found');
911 END IF;
912 EXIT; -- Bug No 5068178, moved this exit outside the if condition.
913 END IF;
914 END LOOP;
915 CLOSE cc_entry_cursor;
916 IF ( l_debug = 1 ) THEN
917 print_debug ( 'Exiting delete_wdt');
918 END IF;
919
920 END delete_wdt;
921
922 /* end of fix for 4539926 */
923
924
925
926
927
928
929 PROCEDURE insert_row
930 IS
931 l_return_status VARCHAR2 ( 300 );
932 l_msg_count NUMBER;
933 l_msg_data VARCHAR2 ( 300 );
934 l_lpn_list WMS_Container_PUB.LPN_Table_Type;
935 l_debug NUMBER := NVL ( FND_PROFILE.VALUE ( 'INV_DEBUG_TRACE' ), 0 );
936 BEGIN
937 IF ( l_debug = 1 ) THEN
938 print_debug ( '***insert_row***' );
939 END IF;
940
941 -- Get the outermost LPN ID if this entry contains an LPN
942 IF ( g_cc_entry.parent_lpn_id IS NOT NULL ) THEN
943 --Bug2935754 starts
944 /*
945 WMS_Container_PUB.Get_Outermost_LPN ( p_api_version => 1.0,
946 x_return_status => l_return_status,
947 x_msg_count => l_msg_count,
948 x_msg_data => l_msg_data,
949 p_lpn_id => g_cc_entry.parent_lpn_id,
950 x_lpn_list => l_lpn_list
951 );
952 g_cc_entry.outermost_lpn_id := l_lpn_list ( 1 ).lpn_id;
953 */
954 BEGIN
955 SELECT outermost_lpn_id
956 INTO g_cc_entry.outermost_lpn_id
957 FROM WMS_LICENSE_PLATE_NUMBERS
958 WHERE lpn_id = g_cc_entry.parent_lpn_id;
959 EXCEPTION
960 WHEN OTHERS THEN
961 IF(l_debug = 1) THEN
962 print_debug('Unable to get the Outermost LPN ID for: ' || g_cc_entry.parent_lpn_id);
963 END IF;
964 RAISE FND_API.G_EXC_ERROR;
965 END;
966 --Bug2935754 ends
967 ELSE
968 g_cc_entry.outermost_lpn_id := NULL;
969 END IF;
970
971 INSERT INTO mtl_cycle_count_entries
972 ( cycle_count_entry_id,
973 last_update_date,
974 last_updated_by,
975 creation_date,
976 created_by,
977 last_update_login,
978 count_list_sequence,
979 count_date_first,
980 count_date_current,
981 count_date_prior,
982 count_date_dummy,
983 counted_by_employee_id_first,
984 counted_by_employee_id_current,
985 counted_by_employee_id_prior,
986 counted_by_employee_id_dummy,
987 count_uom_first,
988 count_uom_current,
989 count_uom_prior,
990 count_quantity_first,
991 count_quantity_current,
992 count_quantity_prior,
993 inventory_item_id,
994 subinventory,
995 entry_status_code,
996 count_due_date,
997 organization_id,
998 cycle_count_header_id,
999 number_of_counts,
1000 locator_id,
1001 adjustment_quantity,
1002 adjustment_date,
1003 adjustment_amount,
1004 item_unit_cost,
1005 inventory_adjustment_account,
1006 approval_date,
1007 approver_employee_id,
1008 revision,
1009 lot_number,
1010 lot_control,
1011 system_quantity_first,
1012 system_quantity_current,
1013 system_quantity_prior,
1014 reference_first,
1015 reference_current,
1016 reference_prior,
1017 primary_uom_quantity_first,
1018 primary_uom_quantity_current,
1019 primary_uom_quantity_prior,
1020 count_type_code,
1021 transaction_reason_id,
1022 request_id,
1023 program_application_id,
1024 program_id,
1025 program_update_date,
1026 approval_type,
1027 attribute_category,
1028 attribute1,
1029 attribute2,
1030 attribute3,
1031 attribute4,
1032 attribute5,
1033 attribute6,
1034 attribute7,
1035 attribute8,
1036 attribute9,
1037 attribute10,
1038 attribute11,
1039 attribute12,
1040 attribute13,
1041 attribute14,
1042 attribute15,
1043 serial_number,
1044 serial_detail,
1045 approval_condition,
1046 neg_adjustment_quantity,
1047 neg_adjustment_amount,
1048 export_flag,
1049 task_priority,
1050 standard_operation_id,
1051 parent_lpn_id,
1052 outermost_lpn_id,
1053 cost_group_id
1054 -- INVCONV, NSRIVAST
1055 ,secondary_uom_quantity_first
1056 ,secondary_uom_quantity_current
1057 ,secondary_uom_quantity_prior
1058 ,count_secondary_uom_first
1059 ,count_secondary_uom_current
1060 ,count_secondary_uom_prior
1061 -- INVCONV, NSRIVAST
1062 )
1063 VALUES ( g_cc_entry.cycle_count_entry_id,
1064 g_cc_entry.last_update_date,
1065 g_cc_entry.last_updated_by,
1066 g_cc_entry.creation_date,
1067 g_cc_entry.created_by,
1068 g_cc_entry.last_update_login,
1069 g_cc_entry.count_list_sequence,
1070 g_cc_entry.count_date_first,
1071 g_cc_entry.count_date_current,
1072 g_cc_entry.count_date_prior,
1073 g_cc_entry.count_date_dummy,
1074 g_cc_entry.counted_by_employee_id_first,
1075 g_cc_entry.counted_by_employee_id_current,
1076 g_cc_entry.counted_by_employee_id_prior,
1077 g_cc_entry.counted_by_employee_id_dummy,
1078 g_cc_entry.count_uom_first,
1079 g_cc_entry.count_uom_current,
1080 g_cc_entry.count_uom_prior,
1081 g_cc_entry.count_quantity_first,
1082 g_cc_entry.count_quantity_current,
1083 g_cc_entry.count_quantity_prior,
1084 g_cc_entry.inventory_item_id,
1085 g_cc_entry.subinventory,
1086 g_cc_entry.entry_status_code,
1087 g_cc_entry.count_due_date,
1088 g_cc_entry.organization_id,
1089 g_cc_entry.cycle_count_header_id,
1090 g_cc_entry.number_of_counts,
1091 g_cc_entry.locator_id,
1092 g_cc_entry.adjustment_quantity,
1093 g_cc_entry.adjustment_date,
1094 g_cc_entry.adjustment_amount,
1095 g_cc_entry.item_unit_cost,
1096 g_cc_entry.inventory_adjustment_account,
1097 g_cc_entry.approval_date,
1098 g_cc_entry.approver_employee_id,
1099 g_cc_entry.revision,
1100 g_cc_entry.lot_number,
1101 g_cc_entry.lot_control,
1102 g_cc_entry.system_quantity_first,
1103 g_cc_entry.system_quantity_current,
1104 g_cc_entry.system_quantity_prior,
1105 g_cc_entry.reference_first,
1106 g_cc_entry.reference_current,
1107 g_cc_entry.reference_prior,
1108 g_cc_entry.primary_uom_quantity_first,
1109 g_cc_entry.primary_uom_quantity_current,
1110 g_cc_entry.primary_uom_quantity_prior,
1111 g_cc_entry.count_type_code,
1112 g_cc_entry.transaction_reason_id,
1113 g_cc_entry.request_id,
1114 g_cc_entry.program_application_id,
1115 g_cc_entry.program_id,
1116 g_cc_entry.program_update_date,
1117 g_cc_entry.approval_type,
1118 g_cc_entry.attribute_category,
1119 g_cc_entry.attribute1,
1120 g_cc_entry.attribute2,
1121 g_cc_entry.attribute3,
1122 g_cc_entry.attribute4,
1123 g_cc_entry.attribute5,
1124 g_cc_entry.attribute6,
1125 g_cc_entry.attribute7,
1126 g_cc_entry.attribute8,
1127 g_cc_entry.attribute9,
1128 g_cc_entry.attribute10,
1129 g_cc_entry.attribute11,
1130 g_cc_entry.attribute12,
1131 g_cc_entry.attribute13,
1132 g_cc_entry.attribute14,
1133 g_cc_entry.attribute15,
1134 LTRIM ( RTRIM ( g_cc_entry.serial_number ) ),
1135 /* BUG2842145*/
1136 g_cc_entry.serial_detail,
1137 g_cc_entry.approval_condition,
1138 g_cc_entry.neg_adjustment_quantity,
1139 g_cc_entry.neg_adjustment_amount,
1140 g_cc_entry.export_flag,
1141 g_cc_entry.task_priority,
1142 g_cc_entry.standard_operation_id,
1143 g_cc_entry.parent_lpn_id,
1144 g_cc_entry.outermost_lpn_id,
1145 g_cc_entry.cost_group_id
1146 -- INVCONV, NSRIVAST
1147 ,g_cc_entry.secondary_uom_quantity_first
1148 ,g_cc_entry.secondary_uom_quantity_current
1149 ,g_cc_entry.secondary_uom_quantity_prior
1150 ,g_cc_entry.count_secondary_uom_first
1151 ,g_cc_entry.count_secondary_uom_current
1152 ,g_cc_entry.count_secondary_uom_prior
1153 -- INVCONV, NSRIVAST
1154 );
1155
1156 IF ( SQL%NOTFOUND ) THEN
1157 RAISE NO_DATA_FOUND;
1158 END IF;
1159 END insert_row;
1160
1161 PROCEDURE update_row
1162 IS
1163 l_return_status VARCHAR2 ( 300 );
1164 l_msg_count NUMBER;
1165 l_msg_data VARCHAR2 ( 300 );
1166 l_lpn_list WMS_Container_PUB.LPN_Table_Type;
1167 l_debug NUMBER := NVL ( FND_PROFILE.VALUE ( 'INV_DEBUG_TRACE' ), 0 );
1168 BEGIN
1169 IF ( l_debug = 1 ) THEN
1170 print_debug ( '***update_row***' );
1171 END IF;
1172
1173 -- Set the WHO column information
1174 g_cc_entry.last_update_date := SYSDATE;
1175 g_cc_entry.last_updated_by := g_user_id;
1176 g_cc_entry.last_update_login := g_login_id;
1177
1178 -- Get the outermost LPN ID if this entry contains an LPN
1179 IF ( g_cc_entry.parent_lpn_id IS NOT NULL ) THEN
1180 --Bug2935754
1181 /*
1182 WMS_Container_PUB.Get_Outermost_LPN ( p_api_version => 1.0,
1183 x_return_status => l_return_status,
1184 x_msg_count => l_msg_count,
1185 x_msg_data => l_msg_data,
1186 p_lpn_id => g_cc_entry.parent_lpn_id,
1187 x_lpn_list => l_lpn_list
1188 );
1189 g_cc_entry.outermost_lpn_id := l_lpn_list ( 1 ).lpn_id;*/
1190 BEGIN
1191 SELECT outermost_lpn_id
1192 INTO g_cc_entry.outermost_lpn_id
1193 FROM WMS_LICENSE_PLATE_NUMBERS
1194 WHERE lpn_id = g_cc_entry.parent_lpn_id;
1195 EXCEPTION
1196 WHEN OTHERS THEN
1197 IF(l_debug = 1) THEN
1198 print_debug('Unable to get the Outermost LPN ID for: ' || g_cc_entry.parent_lpn_id);
1199 END IF;
1200 RAISE FND_API.G_EXC_ERROR;
1201 END;
1202 --Bug2935754 ends
1203 ELSE
1204 g_cc_entry.outermost_lpn_id := NULL;
1205 END IF;
1206
1207 UPDATE mtl_cycle_count_entries
1208 SET last_update_date = g_cc_entry.last_update_date,
1209 last_updated_by = g_cc_entry.last_updated_by,
1210 last_update_login = g_cc_entry.last_update_login,
1211 count_list_sequence = g_cc_entry.count_list_sequence,
1212 count_date_first = g_cc_entry.count_date_first,
1213 count_date_current = g_cc_entry.count_date_current,
1214 count_date_prior = g_cc_entry.count_date_prior,
1215 count_date_dummy = g_cc_entry.count_date_dummy,
1216 counted_by_employee_id_first =
1217 g_cc_entry.counted_by_employee_id_first,
1218 counted_by_employee_id_current =
1219 g_cc_entry.counted_by_employee_id_current,
1220 counted_by_employee_id_prior =
1221 g_cc_entry.counted_by_employee_id_prior,
1222 counted_by_employee_id_dummy =
1223 g_cc_entry.counted_by_employee_id_dummy,
1224 count_uom_first = g_cc_entry.count_uom_first,
1225 count_uom_current = g_cc_entry.count_uom_current,
1226 count_uom_prior = g_cc_entry.count_uom_prior,
1227 count_quantity_first = g_cc_entry.count_quantity_first,
1228 count_quantity_current = g_cc_entry.count_quantity_current,
1229 count_quantity_prior = g_cc_entry.count_quantity_prior,
1230 inventory_item_id = g_cc_entry.inventory_item_id,
1231 subinventory = g_cc_entry.subinventory,
1232 entry_status_code = g_cc_entry.entry_status_code,
1233 count_due_date = g_cc_entry.count_due_date,
1234 organization_id = g_cc_entry.organization_id,
1235 cycle_count_header_id = g_cc_entry.cycle_count_header_id,
1236 number_of_counts = g_cc_entry.number_of_counts,
1237 locator_id = g_cc_entry.locator_id,
1238 adjustment_quantity = g_cc_entry.adjustment_quantity,
1239 adjustment_date = g_cc_entry.adjustment_date,
1240 adjustment_amount = g_cc_entry.adjustment_amount,
1241 item_unit_cost = g_cc_entry.item_unit_cost,
1242 inventory_adjustment_account =
1243 g_cc_entry.inventory_adjustment_account,
1244 approval_date = g_cc_entry.approval_date,
1245 approver_employee_id = g_cc_entry.approver_employee_id,
1246 revision = g_cc_entry.revision,
1247 lot_number = g_cc_entry.lot_number,
1248 lot_control = g_cc_entry.lot_control,
1249 system_quantity_first = g_cc_entry.system_quantity_first,
1250 system_quantity_current = g_cc_entry.system_quantity_current,
1251 system_quantity_prior = g_cc_entry.system_quantity_prior,
1252 reference_first = g_cc_entry.reference_first,
1253 reference_current = g_cc_entry.reference_current,
1254 reference_prior = g_cc_entry.reference_prior,
1255 primary_uom_quantity_first = g_cc_entry.primary_uom_quantity_first,
1256 primary_uom_quantity_current =
1257 g_cc_entry.primary_uom_quantity_current,
1258 primary_uom_quantity_prior = g_cc_entry.primary_uom_quantity_prior,
1259 count_type_code = g_cc_entry.count_type_code,
1260 transaction_reason_id = g_cc_entry.transaction_reason_id,
1261 approval_type = g_cc_entry.approval_type,
1262 attribute_category = g_cc_entry.attribute_category,
1263 attribute1 = g_cc_entry.attribute1,
1264 attribute2 = g_cc_entry.attribute2,
1265 attribute3 = g_cc_entry.attribute3,
1266 attribute4 = g_cc_entry.attribute4,
1267 attribute5 = g_cc_entry.attribute5,
1268 attribute6 = g_cc_entry.attribute6,
1269 attribute7 = g_cc_entry.attribute7,
1270 attribute8 = g_cc_entry.attribute8,
1271 attribute9 = g_cc_entry.attribute9,
1272 attribute10 = g_cc_entry.attribute10,
1273 attribute11 = g_cc_entry.attribute11,
1274 attribute12 = g_cc_entry.attribute12,
1275 attribute13 = g_cc_entry.attribute13,
1276 attribute14 = g_cc_entry.attribute14,
1277 attribute15 = g_cc_entry.attribute15,
1278 serial_number = g_cc_entry.serial_number,
1279 serial_detail = g_cc_entry.serial_detail,
1280 approval_condition = g_cc_entry.approval_condition,
1281 neg_adjustment_quantity = g_cc_entry.neg_adjustment_quantity,
1282 neg_adjustment_amount = g_cc_entry.neg_adjustment_amount,
1283 parent_lpn_id = g_cc_entry.parent_lpn_id,
1284 outermost_lpn_id = g_cc_entry.outermost_lpn_id,
1285 cost_group_id = g_cc_entry.cost_group_id
1286 -- INVCONV, NSRIVAST
1287 ,secondary_uom_quantity_first = g_cc_entry.secondary_uom_quantity_first ,
1288 secondary_uom_quantity_current = g_cc_entry.secondary_uom_quantity_current,
1289 secondary_uom_quantity_prior = g_cc_entry.secondary_uom_quantity_prior ,
1290 count_secondary_uom_first = g_cc_entry.count_secondary_uom_first,
1291 count_secondary_uom_current = g_cc_entry.count_secondary_uom_current,
1292 count_secondary_uom_prior = g_cc_entry.count_secondary_uom_prior,
1293 -- INVCONV, NSRIVAST
1294 -- nsinghi Bug#6052831 START
1295 secondary_adjustment_quantity = g_cc_entry.secondary_adjustment_quantity,
1296 secondary_system_qty_current = g_cc_entry.secondary_system_qty_current,
1297 secondary_system_qty_first = g_cc_entry.secondary_system_qty_first,
1298 secondary_system_qty_prior = g_cc_entry.secondary_system_qty_prior
1299 -- nsinghi Bug#6052831 END
1300 WHERE cycle_count_entry_id = g_cc_entry.cycle_count_entry_id;
1301
1302 IF ( SQL%NOTFOUND ) THEN
1303 RAISE NO_DATA_FOUND;
1304 END IF;
1305 END update_row;
1306
1307 PROCEDURE current_to_prior
1308 IS
1309 l_debug NUMBER := NVL ( FND_PROFILE.VALUE ( 'INV_DEBUG_TRACE' ), 0 );
1310 BEGIN
1311 IF ( l_debug = 1 ) THEN
1312 print_debug ( '***current_to_prior***' );
1313 END IF;
1314
1315 -- Set all of the prior fields equal to the current fields
1316 g_cc_entry.count_date_prior := g_cc_entry.count_date_current;
1317 g_cc_entry.counted_by_employee_id_prior :=
1318 g_cc_entry.counted_by_employee_id_current;
1319 g_cc_entry.count_uom_prior := g_cc_entry.count_uom_current;
1320 g_cc_entry.count_quantity_prior := g_cc_entry.count_quantity_current;
1321 g_cc_entry.system_quantity_prior := g_cc_entry.system_quantity_current;
1322 g_cc_entry.secondary_system_qty_prior := g_cc_entry.secondary_system_qty_current; -- nsinghi Bug#6052831 Added this line.
1323 g_cc_entry.reference_prior := g_cc_entry.reference_current;
1324 g_cc_entry.primary_uom_quantity_prior :=
1325 g_cc_entry.primary_uom_quantity_current;
1326 -- INVCONV, NSRIVAST
1327 g_cc_entry.count_secondary_uom_prior := g_cc_entry.count_secondary_uom_current ;
1328 g_cc_entry.secondary_uom_quantity_prior := g_cc_entry.secondary_uom_quantity_current ;
1329 -- INVCONV, NSRIVAST
1330 END current_to_prior;
1331
1332 PROCEDURE current_to_first
1333 IS
1334 l_debug NUMBER := NVL ( FND_PROFILE.VALUE ( 'INV_DEBUG_TRACE' ), 0 );
1335 BEGIN
1336 IF ( l_debug = 1 ) THEN
1337 print_debug ( '***current_to_first***' );
1338 END IF;
1339
1340 -- Set all of the first fields equal to the current fields
1341 g_cc_entry.count_date_first := g_cc_entry.count_date_current;
1342 g_cc_entry.counted_by_employee_id_first :=
1343 g_cc_entry.counted_by_employee_id_current;
1344 g_cc_entry.count_uom_first := g_cc_entry.count_uom_current;
1345 g_cc_entry.count_quantity_first := g_cc_entry.count_quantity_current;
1346 g_cc_entry.system_quantity_first := g_cc_entry.system_quantity_current;
1347 g_cc_entry.secondary_system_qty_first := g_cc_entry.secondary_system_qty_current; -- nsinghi Bug#6052831 Added this line.
1348 g_cc_entry.reference_first := g_cc_entry.reference_current;
1349 g_cc_entry.primary_uom_quantity_first :=
1350 g_cc_entry.primary_uom_quantity_current;
1351 -- INVCONV, NSRIVAST
1352 g_cc_entry.count_secondary_uom_first := g_cc_entry.count_secondary_uom_current ;
1353 g_cc_entry.secondary_uom_quantity_first := g_cc_entry.secondary_uom_quantity_current ;
1354 -- INVCONV, NSRIVAST
1355 END current_to_first;
1356
1357 -- nsinghi bug#6052831
1358 PROCEDURE entry_to_current (
1359 p_count_date IN DATE,
1360 p_counted_by_employee_id IN NUMBER,
1361 p_system_quantity IN NUMBER,
1362 p_reference IN VARCHAR2,
1363 p_primary_uom_quantity IN NUMBER,
1364 p_sec_system_quantity IN NUMBER DEFAULT NULL -- nsinghi Bug#6052831 Added this parameter.
1365 )
1366 IS
1367 l_debug NUMBER := NVL ( FND_PROFILE.VALUE ( 'INV_DEBUG_TRACE' ), 0 );
1368 BEGIN
1369 IF ( l_debug = 1 ) THEN
1370 print_debug ( '***entry_to_current***' );
1371 END IF;
1372
1373 -- Set all of the current fields equal to the given entries
1374 g_cc_entry.count_date_current := p_count_date;
1375 g_cc_entry.counted_by_employee_id_current := p_counted_by_employee_id;
1376 g_cc_entry.count_uom_current := g_count_uom;
1377 g_cc_entry.count_quantity_current := g_count_quantity;
1378 g_cc_entry.system_quantity_current := p_system_quantity;
1379 g_cc_entry.secondary_system_qty_current := p_sec_system_quantity; -- nsinghi Bug#6052831 Added this line.
1380 g_cc_entry.reference_current := p_reference;
1381 g_cc_entry.primary_uom_quantity_current := p_primary_uom_quantity;
1382 -- INVCONV, NSRIVAST
1383 g_cc_entry.count_secondary_uom_current := g_count_secondary_uom ;
1384 g_cc_entry.secondary_uom_quantity_current := g_count_secondary_quantity ;
1385 -- INVCONV, NSRIVAST
1386 END entry_to_current;
1387
1388 PROCEDURE zero_count_logic
1389 IS
1390 l_primary_uom_quantity NUMBER;
1391 l_primary_uom VARCHAR2 ( 3 );
1392 l_debug NUMBER := NVL ( FND_PROFILE.VALUE ( 'INV_DEBUG_TRACE' ), 0 );
1393 BEGIN
1394 IF ( l_debug = 1 ) THEN
1395 print_debug ( '***zero_count_logic***' );
1396 END IF;
1397
1398 -- Set the default values for a zero count entry
1399 g_cc_entry.system_quantity_current := 0;
1400 g_cc_entry.number_of_counts := 1;
1401 g_cc_entry.entry_status_code := 5;
1402 g_cc_entry.approval_type := 1;
1403 g_cc_entry.approver_employee_id := g_employee_id;
1404 g_cc_entry.approval_date := SYSDATE;
1405
1406 -- Get the item primary uom code
1407 SELECT primary_uom_code
1408 INTO l_primary_uom
1409 FROM MTL_SYSTEM_ITEMS
1410 WHERE inventory_item_id = g_cc_entry.inventory_item_id
1411 AND organization_id = g_cc_entry.organization_id;
1412
1413 -- Convert the count quantity into the item primary uom quantity
1414 l_primary_uom_quantity :=
1415 inv_convert.inv_um_convert ( g_cc_entry.inventory_item_id,
1416 6,
1417 g_count_quantity,
1418 g_count_uom,
1419 l_primary_uom,
1420 NULL,
1421 NULL
1422 );
1423 -- Set the entry values to the current fields
1424 entry_to_current ( p_count_date => SYSDATE,
1425 p_counted_by_employee_id => g_employee_id,
1426 p_system_quantity => 0,
1427 p_reference => NULL,
1428 p_primary_uom_quantity => l_primary_uom_quantity,
1429 p_sec_system_quantity => 0 -- nsinghi Bug#6052831 Added this line.
1430 );
1431 -- Set the current values to the first fields.
1432 current_to_first ( );
1433 END zero_count_logic;
1434
1435 -- Since approval tolerances can be defined at the cycle count header,
1436 -- item, and class level, we need to choose the appropriate one.
1437 -- Similarly, cost tolerances can be defined at the cycle count header
1438 -- and class level.
1439 PROCEDURE get_tolerances (
1440 pre_approve_flag IN VARCHAR2,
1441 x_approval_tolerance_positive OUT NOCOPY NUMBER,
1442 x_approval_tolerance_negative OUT NOCOPY NUMBER,
1443 x_cost_tolerance_positive OUT NOCOPY NUMBER,
1444 x_cost_tolerance_negative OUT NOCOPY NUMBER
1445 )
1446 IS
1447 l_item_app_tol_pos NUMBER;
1448 l_item_app_tol_neg NUMBER;
1449 l_class_app_tol_pos NUMBER;
1450 l_class_app_tol_neg NUMBER;
1451 l_head_app_tol_pos NUMBER;
1452 l_head_app_tol_neg NUMBER;
1453 l_class_cost_tol_pos NUMBER;
1454 l_class_cost_tol_neg NUMBER;
1455 l_head_cost_tol_pos NUMBER;
1456 l_head_cost_tol_neg NUMBER;
1457 l_inventory_item_id NUMBER;
1458 l_organization_id NUMBER;
1459 l_cycle_count_header_id NUMBER;
1460 l_abc_class_id NUMBER;
1461 l_debug NUMBER := NVL ( FND_PROFILE.VALUE ( 'INV_DEBUG_TRACE' ), 0 );
1462 BEGIN
1463 IF ( l_debug = 1 ) THEN
1464 print_debug ( '***get_tolerances***' );
1465 END IF;
1466
1467 -- Get the required information from the cycle count entry record
1468 -- which will serve as the primary keys to get the tolerances from
1469 -- the various cycle count tables
1470 l_inventory_item_id := g_cc_entry.inventory_item_id;
1471 l_organization_id := g_cc_entry.organization_id;
1472 l_cycle_count_header_id := g_cc_entry.cycle_count_header_id;
1473
1474 BEGIN
1475 SELECT abc_class_id
1476 INTO l_abc_class_id
1477 FROM mtl_cycle_count_items
1478 WHERE cycle_count_header_id = l_cycle_count_header_id
1479 AND inventory_item_id = l_inventory_item_id;
1480 EXCEPTION
1481 WHEN NO_DATA_FOUND THEN
1482 l_abc_class_id := NULL;
1483 END;
1484
1485 -- Get all of the values of the tolerances
1486 IF ( l_abc_class_id IS NOT NULL ) THEN
1487 SELECT approval_tolerance_positive,
1488 approval_tolerance_negative
1489 INTO l_item_app_tol_pos,
1490 l_item_app_tol_neg
1491 FROM mtl_cycle_count_items
1492 WHERE cycle_count_header_id = l_cycle_count_header_id
1493 AND inventory_item_id = l_inventory_item_id;
1494 ELSE
1495 l_item_app_tol_pos := NULL;
1496 l_item_app_tol_neg := NULL;
1497 END IF;
1498
1499 IF ( l_abc_class_id IS NOT NULL ) THEN
1500 SELECT approval_tolerance_positive,
1501 approval_tolerance_negative,
1502 cost_tolerance_positive,
1503 cost_tolerance_negative
1504 INTO l_class_app_tol_pos,
1505 l_class_app_tol_neg,
1506 l_class_cost_tol_pos,
1507 l_class_cost_tol_neg
1508 FROM mtl_cycle_count_classes
1509 WHERE abc_class_id = l_abc_class_id
1510 AND cycle_count_header_id = l_cycle_count_header_id;
1511 ELSE
1512 l_class_app_tol_pos := NULL;
1513 l_class_app_tol_neg := NULL;
1514 l_class_cost_tol_pos := NULL;
1515 l_class_cost_tol_neg := NULL;
1516 END IF;
1517
1518 SELECT NVL ( approval_tolerance_positive, -1 ),
1519 NVL ( approval_tolerance_negative, -1 ),
1520 NVL ( cost_tolerance_positive, -1 ),
1521 NVL ( cost_tolerance_negative, -1 )
1522 INTO l_head_app_tol_pos,
1523 l_head_app_tol_neg,
1524 l_head_cost_tol_pos,
1525 l_head_cost_tol_neg
1526 FROM mtl_cycle_count_headers
1527 WHERE cycle_count_header_id = l_cycle_count_header_id
1528 AND organization_id = l_organization_id;
1529
1530 /* Approval Tolerance Positive */
1531 IF l_item_app_tol_pos IS NULL THEN
1532 IF l_class_app_tol_pos IS NULL THEN
1533 x_approval_tolerance_positive := l_head_app_tol_pos;
1534 ELSE
1535 x_approval_tolerance_positive := l_class_app_tol_pos;
1536 END IF;
1537 ELSE
1538 x_approval_tolerance_positive := l_item_app_tol_pos;
1539 END IF;
1540
1541 /* Approval Tolerance Negative */
1542 IF l_item_app_tol_neg IS NULL THEN
1543 IF l_class_app_tol_neg IS NULL THEN
1544 x_approval_tolerance_negative := l_head_app_tol_neg;
1545 ELSE
1546 x_approval_tolerance_negative := l_class_app_tol_neg;
1547 END IF;
1548 ELSE
1549 x_approval_tolerance_negative := l_item_app_tol_neg;
1550 END IF;
1551
1552 /* Cost Tolerance Positive */
1553 IF l_class_cost_tol_pos IS NULL THEN
1554 x_cost_tolerance_positive := l_head_cost_tol_pos;
1555 ELSE
1556 x_cost_tolerance_positive := l_class_cost_tol_pos;
1557 END IF;
1558
1559 /* Cost Tolerance Negative */
1560 IF l_class_cost_tol_neg IS NULL THEN
1561 x_cost_tolerance_negative := l_head_cost_tol_neg;
1562 ELSE
1563 x_cost_tolerance_negative := l_class_cost_tol_neg;
1564 END IF;
1565
1566 /* Check the status of the pre approve flag */
1567 IF ( l_debug = 1 ) THEN
1568 print_debug ( 'Preapprove flag is: ============>' || pre_approve_flag
1569 );
1570 print_debug ( 'Tolerances retrieved are:' );
1571 print_debug ( 'x_approval_tolerance_positive: => '
1572 || x_approval_tolerance_positive
1573 );
1574 print_debug ( 'x_approval_tolerance_negative: => '
1575 || x_approval_tolerance_negative
1576 );
1577 print_debug ( 'x_cost_tolerance_positive: =====> '
1578 || x_cost_tolerance_positive
1579 );
1580 print_debug ( 'x_cost_tolerance_negative: =====> '
1581 || x_cost_tolerance_negative
1582 );
1583 END IF;
1584
1585 IF pre_approve_flag <> 'SERIAL' THEN
1586 IF pre_approve_flag <> 'TRUE' THEN
1587 recount_logic ( p_approval_tolerance_positive => x_approval_tolerance_positive,
1588 p_approval_tolerance_negative => x_approval_tolerance_negative,
1589 p_cost_tolerance_positive => x_cost_tolerance_positive,
1590 p_cost_tolerance_negative => x_cost_tolerance_negative
1591 );
1592 ELSE
1593 tolerance_logic ( p_approval_tolerance_positive => x_approval_tolerance_positive,
1594 p_approval_tolerance_negative => x_approval_tolerance_negative,
1595 p_cost_tolerance_positive => x_cost_tolerance_positive,
1596 p_cost_tolerance_negative => x_cost_tolerance_negative
1597 );
1598 END IF;
1599 END IF;
1600 END get_tolerances;
1601
1602 PROCEDURE recount_logic (
1603 p_approval_tolerance_positive IN NUMBER,
1604 p_approval_tolerance_negative IN NUMBER,
1605 p_cost_tolerance_positive IN NUMBER,
1606 p_cost_tolerance_negative IN NUMBER
1607 )
1608 IS
1609 l_debug NUMBER := NVL ( FND_PROFILE.VALUE ( 'INV_DEBUG_TRACE' ), 0 );
1610 BEGIN
1611 IF ( l_debug = 1 ) THEN
1612 print_debug ( '***recount_logic***' );
1613 END IF;
1614
1615 -- IF count entry has a status of RECOUNT, THEN call
1616 -- current_to_prior to set up the next count
1617 IF ( g_cc_entry.entry_status_code = 3 ) AND g_updated_prior = FALSE THEN -- Modified for Bug 6371673
1618 current_to_prior ( );
1619 END IF;
1620
1621 tolerance_logic ( p_approval_tolerance_positive => p_approval_tolerance_positive,
1622 p_approval_tolerance_negative => p_approval_tolerance_negative,
1623 p_cost_tolerance_positive => p_cost_tolerance_positive,
1624 p_cost_tolerance_negative => p_cost_tolerance_negative
1625 );
1626 END recount_logic;
1627
1628 PROCEDURE tolerance_logic (
1629 p_approval_tolerance_positive IN NUMBER,
1630 p_approval_tolerance_negative IN NUMBER,
1631 p_cost_tolerance_positive IN NUMBER,
1632 p_cost_tolerance_negative IN NUMBER
1633 )
1634 IS
1635 l_adjustment_quantity NUMBER;
1636 l_sec_adjustment_quantity NUMBER; -- nsinghi Bug#6052831
1637 l_system_quantity NUMBER;
1638 l_sec_system_quantity NUMBER; -- nsinghi Bug#6052831
1639 l_pos_meas_err NUMBER;
1640 l_neg_meas_err NUMBER;
1641 l_app_tol_pos NUMBER := p_approval_tolerance_positive;
1642 l_app_tol_neg NUMBER := p_approval_tolerance_negative;
1643 l_cost_tol_pos NUMBER := p_cost_tolerance_positive;
1644 l_cost_tol_neg NUMBER := p_cost_tolerance_negative;
1645 l_adjustment_value NUMBER;
1646 l_approval_option_code NUMBER;
1647 l_parent_lpn_id NUMBER;
1648 l_container_enabled_flag NUMBER;
1649 l_container_adjustment_option NUMBER;
1650 l_container_discrepancy_option NUMBER;
1651 l_primary_uom VARCHAR2 ( 3 );
1652 l_debug NUMBER := NVL ( FND_PROFILE.VALUE ( 'INV_DEBUG_TRACE' ), 0 );
1653 BEGIN
1654 IF ( l_debug = 1 ) THEN
1655 print_debug ( '***tolerance_logic***' );
1656 END IF;
1657
1658 -- Get the item system quantity
1659 system_quantity ( x_system_quantity => l_system_quantity
1660 , x_sec_system_quantity => l_sec_system_quantity ); -- nsinghi Bug#6052831. Call overloaded API.
1661
1662 -- Get the item primary uom code
1663 SELECT primary_uom_code
1664 INTO l_primary_uom
1665 FROM MTL_SYSTEM_ITEMS
1666 WHERE inventory_item_id = g_cc_entry.inventory_item_id
1667 AND organization_id = g_cc_entry.organization_id;
1668
1669 -- Convert the system quantity into the count uom
1670 /*2977228l_system_quantity :=
1671 inv_convert.inv_um_convert ( g_cc_entry.inventory_item_id,
1672 6,
1673 l_system_quantity,
1674 l_primary_uom,
1675 g_count_uom,
1676 NULL,
1677 NULL
1678 );*/
1679 -- Get the adjustment quantity and adjustment value
1680 l_adjustment_quantity := g_count_quantity - l_system_quantity;
1681 l_sec_adjustment_quantity := g_count_secondary_quantity - l_sec_system_quantity; -- nsinghi Bug#6052831. Added this line.
1682 g_cc_entry.adjustment_quantity := l_adjustment_quantity;
1683 g_cc_entry.secondary_adjustment_quantity := l_sec_adjustment_quantity; -- nsinghi Bug#6052831. Added this line.
1684 g_cc_entry.adjustment_date := SYSDATE;
1685
1686 value_variance ( x_value_variance => l_adjustment_value );
1687 g_cc_entry.adjustment_amount := l_adjustment_value;
1688
1689
1690 /* Bug 4495880 - Checking the value of the global parameter to set the adjustment quantity
1691 and adjustment value to 0*/
1692
1693 IF g_condition=TRUE THEN
1694
1695 IF ( l_debug = 1 ) THEN
1696 print_debug ( 'In tolerance_logic in the condition for g_condition=TRUE' );
1697 END IF;
1698 l_adjustment_quantity := 0;
1699 l_adjustment_value := 0;
1700 g_cc_entry.adjustment_quantity := l_adjustment_quantity;
1701 g_cc_entry.adjustment_amount := l_adjustment_value;
1702 -- nsinghi Bug#6052831. START
1703 l_sec_adjustment_quantity := 0;
1704 g_cc_entry.secondary_adjustment_quantity := 0;
1705 -- nsinghi Bug#6052831. END.
1706
1707 END IF;
1708
1709 /* End of fix for Bug 4495880 */
1710
1711
1712 -- Get the required information from the cycle count record.
1713 -- Need to use the view rather than the table to get the measurement
1714 -- error values
1715 BEGIN
1716 SELECT positive_measurement_error,
1717 negative_measurement_error,
1718 parent_lpn_id
1719 INTO l_pos_meas_err,
1720 l_neg_meas_err,
1721 l_parent_lpn_id
1722 FROM mtl_cycle_count_entries_v
1723 WHERE cycle_count_entry_id = g_cc_entry.cycle_count_entry_id
1724 AND organization_id = g_cc_entry.organization_id;
1725 EXCEPTION
1726 WHEN NO_DATA_FOUND THEN
1727 l_pos_meas_err := 0;
1728 l_neg_meas_err := 0;
1729 l_parent_lpn_id := g_cc_entry.parent_lpn_id;
1730 END;
1731
1732 -- Get the container specific information
1733 SELECT NVL ( container_enabled_flag, 2 ),
1734 NVL ( container_adjustment_option, 2 ),
1735 NVL ( container_discrepancy_option, 2 )
1736 INTO l_container_enabled_flag,
1737 l_container_adjustment_option,
1738 l_container_discrepancy_option
1739 FROM mtl_cycle_count_headers
1740 WHERE cycle_count_header_id = g_cc_entry.cycle_count_header_id
1741 AND organization_id = g_cc_entry.organization_id;
1742
1743 -- Get the cycle count header approval option code
1744 SELECT NVL ( approval_option_code, 1 )
1745 INTO l_approval_option_code
1746 FROM mtl_cycle_count_headers
1747 WHERE cycle_count_header_id = g_cc_entry.cycle_count_header_id
1748 AND organization_id = g_cc_entry.organization_id;
1749
1750 IF ( l_debug = 1 ) THEN
1751 print_debug ( 'Adjustment quantity: ===> ' || l_adjustment_quantity );
1752 print_debug ( 'System quantity : ======> ' || l_system_quantity );
1753 print_debug ( 'Pos Measurement error: => ' || l_pos_meas_err );
1754 print_debug ( 'Neg Measurement error: => ' || l_neg_meas_err );
1755 print_debug ( 'App Tolerance pos: =====> ' || l_app_tol_pos );
1756 print_debug ( 'App Tolernace neg: =====> ' || l_app_tol_neg );
1757 print_debug ( 'Cost Tolerance pos: ====> ' || l_cost_tol_pos );
1758 print_debug ( 'Cost Tolerance neg: ====> ' || l_cost_tol_neg );
1759 print_debug ( 'Adjustment value: =====> ' || l_adjustment_value );
1760 print_debug ( 'Approval option code: ==> ' || l_approval_option_code );
1761 END IF;
1762
1763 -- Approval required for all adjustments
1764 IF ( l_approval_option_code = 1 AND l_parent_lpn_id IS NULL )
1765 OR ( l_approval_option_code = 1 AND l_parent_lpn_id IS NOT NULL
1766 AND l_container_enabled_flag = 1
1767 AND ( l_container_adjustment_option = 2
1768 OR l_container_discrepancy_option = 2
1769 )
1770 ) THEN
1771 IF l_adjustment_quantity <> 0 THEN
1772 IF l_system_quantity <> 0 THEN
1773 IF l_adjustment_quantity < 0 THEN
1774 IF l_neg_meas_err IS NOT NULL
1775 AND ABS ( l_adjustment_quantity / l_system_quantity )
1776 * 100 < l_neg_meas_err THEN
1777 no_adj_req ( );
1778 ELSE
1779 out_tolerance ( );
1780 END IF;
1781 ELSE
1782 IF l_pos_meas_err IS NOT NULL
1783 AND ABS ( l_adjustment_quantity / l_system_quantity )
1784 * 100 < l_pos_meas_err THEN
1785 no_adj_req ( );
1786 ELSE
1787 out_tolerance ( );
1788 END IF;
1789 END IF;
1790 ELSE /* system qty = 0 */
1791 out_tolerance ( );
1792 END IF;
1793 ELSE /* adjustment_qty = 0 */
1794 no_adj_req ( );
1795 END IF;
1796 ELSE /* IF optional_option = required IF out of tolerance */
1797 IF l_adjustment_quantity <> 0 THEN
1798 IF l_system_quantity <> 0 THEN
1799 IF l_adjustment_quantity < 0 THEN
1800 IF l_neg_meas_err IS NOT NULL
1801 AND ABS ( l_adjustment_quantity / l_system_quantity )
1802 * 100 < l_neg_meas_err THEN
1803 no_adj_req ( );
1804 ELSE
1805 IF ( ( l_app_tol_neg IS NOT NULL
1806 AND l_app_tol_neg >= 0
1807 )
1808 AND ( ABS ( ( l_adjustment_quantity
1809 / l_system_quantity
1810 )
1811 * 100
1812 ) > l_app_tol_neg
1813 )
1814 ) THEN
1815 out_tolerance ( );
1816 ELSE
1817 IF ( ( l_cost_tol_neg IS NOT NULL
1818 AND l_cost_tol_neg >= 0
1819 )
1820 AND ( ABS ( l_adjustment_value ) > l_cost_tol_neg
1821 )
1822 ) THEN
1823 out_tolerance ( );
1824 ELSE
1825 in_tolerance ( );
1826 END IF;
1827 END IF;
1828 END IF;
1829 ELSE /* l_adjustment_quantity >= 0 */
1830 IF l_pos_meas_err IS NOT NULL
1831 AND ABS ( l_adjustment_quantity / l_system_quantity )
1832 * 100 < l_pos_meas_err THEN
1833 no_adj_req ( );
1834 ELSE
1835 IF ( ( l_app_tol_pos IS NOT NULL
1836 AND l_app_tol_pos >= 0
1837 )
1838 AND ( ABS ( ( l_adjustment_quantity
1839 / l_system_quantity
1840 )
1841 * 100
1842 ) > l_app_tol_pos
1843 )
1844 ) THEN
1845 out_tolerance ( );
1846 ELSE
1847 IF ( ( l_cost_tol_pos IS NOT NULL
1848 AND l_cost_tol_pos >= 0
1849 )
1850 AND ( ABS ( l_adjustment_value ) > l_cost_tol_pos
1851 )
1852 ) THEN
1853 out_tolerance ( );
1854 ELSE
1855 in_tolerance ( );
1856 END IF;
1857 END IF;
1858 END IF;
1859 END IF;
1860 ELSE /* system quantity = 0 */
1861 IF ( l_app_tol_pos IS NOT NULL AND l_app_tol_pos >= 0 ) THEN
1862 out_tolerance ( );
1863 ELSE
1864 IF ( ( l_cost_tol_pos IS NOT NULL
1865 AND l_cost_tol_pos >= 0 )
1866 AND ( l_adjustment_value > l_cost_tol_pos )
1867 ) THEN
1868 out_tolerance ( );
1869 ELSE
1870 in_tolerance ( );
1871 END IF;
1872 END IF;
1873 END IF;
1874 ELSE /* adjustment qty = 0 */
1875 no_adj_req ( );
1876 END IF;
1877 END IF;
1878 END tolerance_logic;
1879
1880 PROCEDURE valids
1881 IS
1882 l_debug NUMBER := NVL ( FND_PROFILE.VALUE ( 'INV_DEBUG_TRACE' ), 0 );
1883 BEGIN
1884 IF ( l_debug = 1 ) THEN
1885 print_debug ( '***valids***' );
1886 END IF;
1887 print_debug('calling from valids ');
1888 final_preupdate_logic ( );
1889 END valids;
1890
1891 PROCEDURE in_tolerance
1892 IS
1893 l_approval_option_code NUMBER;
1894 l_parent_lpn_id NUMBER;
1895 l_container_enabled_flag NUMBER;
1896 l_container_adjustment_option NUMBER;
1897 l_container_discrepancy_option NUMBER;
1898 l_debug NUMBER := NVL ( FND_PROFILE.VALUE ( 'INV_DEBUG_TRACE' ), 0 );
1899 BEGIN
1900 IF ( l_debug = 1 ) THEN
1901 print_debug ( '***in_tolerance***' );
1902 END IF;
1903
1904 -- Get the required fields
1905 SELECT NVL ( approval_option_code, 1 )
1906 INTO l_approval_option_code
1907 FROM mtl_cycle_count_headers
1908 WHERE cycle_count_header_id = g_cc_entry.cycle_count_header_id
1909 AND organization_id = g_cc_entry.organization_id;
1910
1911 l_parent_lpn_id := g_cc_entry.parent_lpn_id;
1912
1913 -- Get the container specific information
1914 SELECT NVL ( container_enabled_flag, 2 ),
1915 NVL ( container_adjustment_option, 2 ),
1916 NVL ( container_discrepancy_option, 2 )
1917 INTO l_container_enabled_flag,
1918 l_container_adjustment_option,
1919 l_container_discrepancy_option
1920 FROM mtl_cycle_count_headers
1921 WHERE cycle_count_header_id = g_cc_entry.cycle_count_header_id
1922 AND organization_id = g_cc_entry.organization_id;
1923
1924 -- Approval is required for all adjustments
1925 IF ( l_approval_option_code = 1 AND l_parent_lpn_id IS NULL )
1926 OR ( l_approval_option_code = 1 --Bug 5917964 -Added the check for approval code for lpn counts also
1927 AND l_parent_lpn_id IS NOT NULL
1928 AND l_container_enabled_flag = 1
1929 AND l_container_adjustment_option = 2
1930 AND l_container_discrepancy_option = 2
1931 ) THEN
1932 g_cc_entry.entry_status_code := 2;
1933 ELSE
1934 -- Approval is not required so complete the count entry
1935 g_cc_entry.entry_status_code := 5;
1936 g_cc_entry.approval_type := 1;
1937 END IF;
1938
1939 valids ( );
1940 END in_tolerance;
1941
1942 PROCEDURE out_tolerance
1943 IS
1944 l_approval_option_code NUMBER;
1945 l_auto_recount_flag NUMBER;
1946 l_max_recounts NUMBER;
1947 l_garbage NUMBER;
1948 l_parent_lpn_id NUMBER := g_cc_entry.parent_lpn_id;
1949 l_container_enabled_flag NUMBER;
1950 l_container_adjustment_option NUMBER;
1951 l_container_discrepancy_option NUMBER;
1952 l_days_until_late NUMBER;
1953 l_debug NUMBER := NVL ( FND_PROFILE.VALUE ( 'INV_DEBUG_TRACE' ), 0 );
1954
1955 l_serial_count_option NUMBER; --Bug 5186993
1956 l_serial_number_ctrl_code NUMBER; --Bug 5186993
1957
1958 BEGIN
1959 IF ( l_debug = 1 ) THEN
1960 print_debug ( '***out_tolerance***' );
1961 END IF;
1962
1963 -- Get the required values
1964 SELECT NVL ( approval_option_code, 1 ),
1965 NVL ( automatic_recount_flag, 2 ),
1966 NVL ( maximum_auto_recounts, 0 ),
1967 NVL ( days_until_late, 0 ),
1968 NVL ( serial_count_option, 1 )
1969 INTO l_approval_option_code,
1970 l_auto_recount_flag,
1971 l_max_recounts,
1972 l_days_until_late,
1973 l_serial_count_option
1974 FROM mtl_cycle_count_headers
1975 WHERE cycle_count_header_id = g_cc_entry.cycle_count_header_id
1976 AND organization_id = g_cc_entry.organization_id;
1977
1978 -- Get the container specific information
1979 SELECT NVL ( container_enabled_flag, 2 ),
1980 NVL ( container_adjustment_option, 2 ),
1981 NVL ( container_discrepancy_option, 2 )
1982 INTO l_container_enabled_flag,
1983 l_container_adjustment_option,
1984 l_container_discrepancy_option
1985 FROM mtl_cycle_count_headers
1986 WHERE cycle_count_header_id = g_cc_entry.cycle_count_header_id
1987 AND organization_id = g_cc_entry.organization_id;
1988
1989 -- Bug 5186993
1990 SELECT serial_number_control_code
1991 INTO l_serial_number_ctrl_code
1992 FROM mtl_system_items
1993 WHERE inventory_item_id = g_cc_entry.inventory_item_id
1994 AND organization_id = g_cc_entry.organization_id;
1995
1996
1997 -- Do more checks/validations IF the item is serial controlled
1998 is_serial_entered ( event => 'OUT-TOLERANCE', entered => l_garbage );
1999
2000 -- No automatic recounts for this cycle count
2001 IF l_auto_recount_flag <> 1 THEN
2002 -- Approvals are not required for adjustments
2003 IF ( l_approval_option_code = 2 AND l_parent_lpn_id IS NULL )
2004 OR ( l_approval_option_code = 2 --Bug 5917964 -Added the check for approval code for lpn counts also
2005 AND l_parent_lpn_id IS NOT NULL
2006 AND l_container_enabled_flag = 1
2007 AND l_container_adjustment_option = 1
2008 AND l_container_discrepancy_option = 1
2009 ) THEN
2010 -- Complete the count AND automatically approve it
2011 g_cc_entry.entry_status_code := 5;
2012 g_cc_entry.approval_type := 1;
2013 ELSE
2014 -- Approval is required for this adjustment
2015 g_cc_entry.entry_status_code := 2;
2016 END IF;
2017 ELSE
2018 -- Automatic recounts are allowed for this cycle count
2019 -- Bug# 2356835, change the < to <= since in mobile, we are updating
2020 -- the number of counts field in the cycle count entry beforehand
2021 -- in the pre_update method. In the desktop library, this is done
2022 -- at the final_preupdate_logic stage which occurs after the
2023 -- tolerance/recount logic is done.
2024
2025 -- Bug 5186993, do not set for recount for serialized items for multiple
2026 -- per request option.
2027 if (l_serial_number_ctrl_code in (1,6) OR l_serial_count_option <> 3) then
2028 IF NVL ( g_cc_entry.number_of_counts, 0 ) <= l_max_recounts THEN
2029 g_cc_entry.entry_status_code := 3;
2030 g_cc_entry.count_due_date := SYSDATE + l_days_until_late;
2031 ELSE
2032 -- Maximum number of recounts has already been met
2033 g_cc_entry.entry_status_code := 2;
2034 END IF;
2035 end if;
2036 END IF;
2037
2038 valids ( );
2039 END out_tolerance;
2040
2041 PROCEDURE no_adj_req
2042 IS
2043 l_debug NUMBER := NVL ( FND_PROFILE.VALUE ( 'INV_DEBUG_TRACE' ), 0 );
2044 BEGIN
2045 IF ( l_debug = 1 ) THEN
2046 print_debug ( '***no_adj_req***' );
2047 END IF;
2048
2049 g_cc_entry.entry_status_code := 5;
2050 g_cc_entry.adjustment_quantity := 0;
2051 g_cc_entry.secondary_adjustment_quantity := 0; -- nsinghi Bug#6052831
2052 g_cc_entry.adjustment_date := NULL; --Bug#3640622
2053 valids ( );
2054 END no_adj_req;
2055
2056 PROCEDURE pre_insert
2057 IS
2058 l_number_of_counts NUMBER := NVL ( g_cc_entry.number_of_counts, 0 );
2059 l_count_quantity NUMBER := g_count_quantity;
2060 l_count_type_code NUMBER := g_cc_entry.count_type_code;
2061 l_pre_approve_flag VARCHAR2 ( 20 ) := g_pre_approve_flag;
2062 l_cc_entry_id NUMBER;
2063 l_serial_number_ctrl_code NUMBER;
2064 l_serial_detail NUMBER;
2065 l_serial_entered NUMBER;
2066 l_serial_detail_option NUMBER;
2067 l_serial_count_option NUMBER;
2068 l_entry_status_code NUMBER := g_cc_entry.entry_status_code;
2069 l_total_serial_num_cnt NUMBER;
2070 l_cc_header_id NUMBER := g_cc_entry.cycle_count_header_id;
2071 l_success BOOLEAN;
2072 l_locator_id NUMBER := g_cc_entry.locator_id;
2073 l_approval_tolerance_positive NUMBER;
2074 l_approval_tolerance_negative NUMBER;
2075 l_cost_tolerance_positive NUMBER;
2076 l_cost_tolerance_negative NUMBER;
2077 l_system_quantity NUMBER;
2078 l_sec_system_quantity NUMBER; -- nsinghi Bug#6052831.
2079 l_primary_uom_quantity NUMBER;
2080 l_primary_uom VARCHAR2 ( 3 );
2081 l_adjustment_quantity NUMBER := 0;
2082 l_sec_adjustment_quantity NUMBER := 0; -- nsinghi Bug#6052831
2083 l_adjustment_value NUMBER := 0;
2084 l_debug NUMBER := NVL ( FND_PROFILE.VALUE ( 'INV_DEBUG_TRACE' ), 0 );
2085 BEGIN
2086 IF ( l_debug = 1 ) THEN
2087 print_debug ( '***pre_insert***' );
2088 END IF;
2089 duplicate_entries() ;
2090
2091 -- Get the required variable values
2092 SELECT serial_number_control_code
2093 INTO l_serial_number_ctrl_code
2094 FROM mtl_system_items
2095 WHERE inventory_item_id = g_cc_entry.inventory_item_id
2096 AND organization_id = g_cc_entry.organization_id;
2097
2098 SELECT NVL ( serial_detail_option, 1 ),
2099 NVL ( serial_count_option, 1 )
2100 INTO l_serial_detail_option,
2101 l_serial_count_option
2102 FROM mtl_cycle_count_headers
2103 WHERE cycle_count_header_id = g_cc_entry.cycle_count_header_id
2104 AND organization_id = g_cc_entry.organization_id;
2105
2106 -- Set the serial detail option for the new entry
2107 l_serial_detail := l_serial_detail_option;
2108 g_cc_entry.serial_detail := l_serial_detail;
2109
2110 IF ( g_cc_entry.cycle_count_entry_id IS NULL ) THEN
2111 SELECT mtl_cycle_count_entries_s.NEXTVAL
2112 INTO l_cc_entry_id
2113 FROM DUAL;
2114
2115 g_cc_entry.cycle_count_entry_id := l_cc_entry_id;
2116 -- Bug# 2386128
2117 -- For unscheduled cycle count entries, the count list sequence
2118 -- number is the same as the cycle count entry ID
2119 g_cc_entry.count_list_sequence := l_cc_entry_id;
2120 END IF;
2121
2122 IF ( l_count_type_code = 4 ) THEN
2123 -- Zero Count
2124 zero_count_logic;
2125 ELSE
2126 IF ( l_serial_number_ctrl_code IN ( 1, 6 ) ) THEN
2127 -- Not serial controlled
2128 l_number_of_counts := ( NVL ( l_number_of_counts, 0 ) + 1 );
2129 g_cc_entry.number_of_counts := l_number_of_counts;
2130 -- Get the system quantity
2131 system_quantity ( x_system_quantity => l_system_quantity
2132 , x_sec_system_quantity => l_sec_system_quantity ); -- nsinghi Bug#6052831. Call overloaded API.
2133
2134 -- Get the item primary uom code
2135 SELECT primary_uom_code
2136 INTO l_primary_uom
2137 FROM MTL_SYSTEM_ITEMS
2138 WHERE inventory_item_id = g_cc_entry.inventory_item_id
2139 AND organization_id = g_cc_entry.organization_id;
2140
2141 -- Convert the system quantity into the count uom
2142 /*2977228l_system_quantity :=
2143 inv_convert.inv_um_convert ( g_cc_entry.inventory_item_id,
2144 6,
2145 l_system_quantity,
2146 l_primary_uom,
2147 g_count_uom,
2148 NULL,
2149 NULL
2150 );*/
2151 -- Convert the count quantity into the item primary uom quantity
2152 l_primary_uom_quantity :=
2153 inv_convert.inv_um_convert ( g_cc_entry.inventory_item_id,
2154 6,
2155 g_count_quantity,
2156 g_count_uom,
2157 l_primary_uom,
2158 NULL,
2159 NULL
2160 );
2161
2162 IF ( l_number_of_counts = 1 ) THEN
2163 entry_to_current ( p_count_date => SYSDATE,
2164 p_counted_by_employee_id => g_employee_id,
2165 p_system_quantity => l_system_quantity,
2166 p_reference => NULL,
2167 p_primary_uom_quantity => l_primary_uom_quantity,
2168 p_sec_system_quantity => l_sec_system_quantity -- nsinghi bug#6052831 Pass sec qty.
2169 );
2170 current_to_first ( );
2171 ELSE
2172 current_to_prior ( );
2173 entry_to_current ( p_count_date => SYSDATE,
2174 p_counted_by_employee_id => g_employee_id,
2175 p_system_quantity => l_system_quantity,
2176 p_reference => NULL,
2177 p_primary_uom_quantity => l_primary_uom_quantity,
2178 p_sec_system_quantity => l_sec_system_quantity -- nsinghi bug#6052831 Pass sec qty.
2179 );
2180 END IF;
2181
2182 IF ( l_pre_approve_flag = 'TRUE' ) THEN
2183 g_cc_entry.entry_status_code := 5;
2184 g_cc_entry.approval_type := 3;
2185 g_cc_entry.approver_employee_id := g_employee_id;
2186 print_debug('Called from pre_insert ');
2187 final_preupdate_logic ( );
2188 ELSE
2189 get_tolerances ( pre_approve_flag => l_pre_approve_flag,
2190 x_approval_tolerance_positive => l_approval_tolerance_positive,
2191 x_approval_tolerance_negative => l_approval_tolerance_negative,
2192 x_cost_tolerance_positive => l_cost_tolerance_positive,
2193 x_cost_tolerance_negative => l_cost_tolerance_negative
2194 );
2195 END IF;
2196 ELSIF ( l_serial_number_ctrl_code IN ( 2, 5 ) ) THEN
2197 -- Item is serial controlled
2198
2199 IF ( l_serial_count_option = 3 ) THEN
2200 -- Multiple serial count option
2201
2202 -- If serial details are entered, the adjustment txn should
2203 -- have already handled in the serial detail level or
2204 -- if serial detail does not entered, then get the tolerance
2205 is_serial_entered ( 'WHEN-VALIDATE-RECORD', l_serial_entered );
2206
2207 IF ( l_serial_entered = 0 ) THEN
2208 get_tolerances ( pre_approve_flag => l_pre_approve_flag,
2209 x_approval_tolerance_positive => l_approval_tolerance_positive,
2210 x_approval_tolerance_negative => l_approval_tolerance_negative,
2211 x_cost_tolerance_positive => l_cost_tolerance_positive,
2212 x_cost_tolerance_negative => l_cost_tolerance_negative
2213 );
2214 ELSIF ( l_serial_entered = 1 ) THEN
2215 IF ( l_entry_status_code = 5 ) THEN
2216 -- Completed count entries
2217 g_cc_entry.approval_date := SYSDATE;
2218 END IF;
2219
2220 l_number_of_counts := ( NVL ( l_number_of_counts, 0 ) + 1 );
2221 g_cc_entry.number_of_counts := l_number_of_counts;
2222 -- Get the system quantity
2223 system_quantity ( x_system_quantity => l_system_quantity
2224 , x_sec_system_quantity => l_sec_system_quantity ); -- nsinghi Bug#6052831. Call overloaded API.
2225
2226 -- Get the item primary uom code
2227 SELECT primary_uom_code
2228 INTO l_primary_uom
2229 FROM MTL_SYSTEM_ITEMS
2230 WHERE inventory_item_id = g_cc_entry.inventory_item_id
2231 AND organization_id = g_cc_entry.organization_id;
2232
2233 -- Convert the system quantity into the count uom
2234 /*2977228l_system_quantity :=
2235 inv_convert.inv_um_convert ( g_cc_entry.inventory_item_id,
2236 6,
2237 l_system_quantity,
2238 l_primary_uom,
2239 g_count_uom,
2240 NULL,
2241 NULL
2242 );*/
2243 -- Convert the count quantity into the item primary uom quantity
2244 l_primary_uom_quantity :=
2245 inv_convert.inv_um_convert ( g_cc_entry.inventory_item_id,
2246 6,
2247 g_count_quantity,
2248 g_count_uom,
2249 l_primary_uom,
2250 NULL,
2251 NULL
2252 );
2253
2254 IF ( l_number_of_counts = 1 ) THEN
2255 entry_to_current ( p_count_date => SYSDATE,
2256 p_counted_by_employee_id => g_employee_id,
2257 p_system_quantity => l_system_quantity,
2258 p_reference => NULL,
2259 p_primary_uom_quantity => l_primary_uom_quantity,
2260 p_sec_system_quantity => l_sec_system_quantity -- nsinghi bug#6052831 Pass sec qty.
2261 );
2262 current_to_first ( );
2263 ELSE
2264 current_to_prior ( );
2265 entry_to_current ( p_count_date => SYSDATE,
2266 p_counted_by_employee_id => g_employee_id,
2267 p_system_quantity => l_system_quantity,
2268 p_reference => NULL,
2269 p_primary_uom_quantity => l_primary_uom_quantity,
2270 p_sec_system_quantity => l_sec_system_quantity -- nsinghi bug#6052831 Pass sec qty.
2271 );
2272 END IF;
2273
2274 UPDATE MTL_MATERIAL_TRANSACTIONS_TEMP
2275 SET LOCATOR_ID = l_locator_id
2276 WHERE CYCLE_COUNT_ID = l_cc_entry_id
2277 AND TRANSACTION_SOURCE_ID = l_cc_header_id
2278 AND LOCATOR_ID = -1;
2279
2280 -- Bug 5186993, if recount unmarking the serials and re-setting serials in MCSN.
2281 if (l_entry_status_code = 3) then
2282 unmark(l_cc_entry_id);
2283 UPDATE MTL_CC_SERIAL_NUMBERS
2284 SET
2285 UNIT_STATUS_CURRENT = DECODE((NVL(POS_ADJUSTMENT_QTY,0) -
2286 NVL(NEG_ADJUSTMENT_QTY,0)), 1, 2, -1, 1, UNIT_STATUS_CURRENT),
2287 POS_ADJUSTMENT_QTY = 0,
2288 NEG_ADJUSTMENT_QTY = 0,
2289 APPROVAL_CONDITION = NULL
2290 WHERE CYCLE_COUNT_ENTRY_ID = l_cc_entry_id;
2291 end if;
2292
2293 END IF;
2294 -- Single serial count
2295 ELSIF ( l_serial_count_option = 2 ) THEN
2296 -- Check if an adjustment txn is necessary
2297 -- Get the system quantity
2298 system_quantity ( x_system_quantity => l_system_quantity
2299 , x_sec_system_quantity => l_sec_system_quantity ); -- nsinghi Bug#6052831. Call overloaded API.
2300
2301 IF ( l_system_quantity <> 0 ) THEN
2302 g_serial_out_tolerance := FALSE;
2303 ELSE
2304 g_serial_out_tolerance := TRUE;
2305 END IF;
2306
2307 -- Get and set the adjustment quantity and adjustment value
2308 l_adjustment_quantity := g_count_quantity - l_system_quantity;
2309 g_cc_entry.adjustment_quantity := l_adjustment_quantity;
2310 -- nsinghi bug#6052831 START.
2311 IF g_count_secondary_quantity IS NOT NULL AND l_sec_system_quantity IS NOT NULL THEN
2312 l_sec_adjustment_quantity := g_count_secondary_quantity - l_sec_system_quantity;
2313 g_cc_entry.secondary_adjustment_quantity := l_sec_adjustment_quantity;
2314 END IF;
2315 -- nsinghi bug#6052831 END.
2316 g_cc_entry.adjustment_date := SYSDATE;
2317 value_variance ( x_value_variance => l_adjustment_value );
2318 g_cc_entry.adjustment_amount := l_adjustment_value;
2319 -- Update the number of counts
2320 l_number_of_counts := ( NVL ( l_number_of_counts, 0 ) + 1 );
2321 g_cc_entry.number_of_counts := l_number_of_counts;
2322
2323 -- Get the item primary uom code
2324 SELECT primary_uom_code
2325 INTO l_primary_uom
2326 FROM MTL_SYSTEM_ITEMS
2327 WHERE inventory_item_id = g_cc_entry.inventory_item_id
2328 AND organization_id = g_cc_entry.organization_id;
2329
2330 -- Convert the system quantity into the count uom
2331 /*2977228l_system_quantity :=
2332 inv_convert.inv_um_convert ( g_cc_entry.inventory_item_id,
2333 6,
2334 l_system_quantity,
2335 l_primary_uom,
2336 g_count_uom,
2337 NULL,
2338 NULL
2339 );*/
2340 -- Convert the count quantity into the item primary uom quantity
2341 l_primary_uom_quantity :=
2342 inv_convert.inv_um_convert ( g_cc_entry.inventory_item_id,
2343 6,
2344 g_count_quantity,
2345 g_count_uom,
2346 l_primary_uom,
2347 NULL,
2348 NULL
2349 );
2350
2351 IF ( l_number_of_counts = 1 ) THEN
2352 entry_to_current ( p_count_date => SYSDATE,
2353 p_counted_by_employee_id => g_employee_id,
2354 p_system_quantity => l_system_quantity,
2355 p_reference => NULL,
2356 p_primary_uom_quantity => l_primary_uom_quantity,
2357 p_sec_system_quantity => l_sec_system_quantity -- nsinghi bug#6052831 Pass sec qty.
2358 );
2359 current_to_first ( );
2360 ELSE
2361 current_to_prior ( );
2362 entry_to_current ( p_count_date => SYSDATE,
2363 p_counted_by_employee_id => g_employee_id,
2364 p_system_quantity => l_system_quantity,
2365 p_reference => NULL,
2366 p_primary_uom_quantity => l_primary_uom_quantity,
2367 p_sec_system_quantity => l_sec_system_quantity -- nsinghi bug#6052831 Pass sec qty.
2368 );
2369 END IF;
2370
2371 -- Calling new_serial_number which in turn will call
2372 -- final_preupdate_logic to process any adjustments if necessary
2373 new_serial_number ( );
2374 END IF;
2375 END IF;
2376 END IF;
2377 END pre_insert;
2378
2379 PROCEDURE pre_update
2380 IS
2381 l_number_of_counts NUMBER := NVL ( g_cc_entry.number_of_counts, 0 );
2382 l_count_quantity NUMBER := g_count_quantity;
2383 l_count_type_code NUMBER := g_cc_entry.count_type_code;
2384 l_pre_approve_flag VARCHAR2 ( 20 ) := g_pre_approve_flag;
2385 l_cc_entry_id NUMBER := g_cc_entry.cycle_count_entry_id;
2386 l_old_num_counts NUMBER;
2387 l_serial_number_ctrl_code NUMBER;
2388 l_serial_detail NUMBER := g_cc_entry.serial_detail;
2389 l_serial_entered NUMBER := 0;
2390 l_serial_detail_option NUMBER;
2391 l_serial_count_option NUMBER;
2392 l_entry_status_code NUMBER := g_cc_entry.entry_status_code;
2393 l_total_serial_num_cnt NUMBER;
2394 l_approval_tolerance_positive NUMBER;
2395 l_approval_tolerance_negative NUMBER;
2396 l_cost_tolerance_positive NUMBER;
2397 l_cost_tolerance_negative NUMBER;
2398 l_system_quantity NUMBER;
2399 l_sec_system_quantity NUMBER; -- nsinghi bug#6052831
2400 l_primary_uom_quantity NUMBER;
2401 l_primary_uom VARCHAR2 ( 3 );
2402 l_debug NUMBER := NVL ( FND_PROFILE.VALUE ( 'INV_DEBUG_TRACE' ), 0 );
2403
2404
2405 /* Bug 4495880 -Added the local variables for the lpn details from wlpn*/
2406
2407 l_lpn_subinv VARCHAR2(10) ;
2408 l_lpn_locator_id NUMBER ;
2409 l_lpn_context NUMBER;
2410
2411 /* End of fix for Bug 4495880 */
2412
2413 /* Added tbe below 2 variables for Bug#5604139 */
2414 l_adjustment_quantity NUMBER := 0;
2415 l_adjustment_value NUMBER := 0;
2416 /* End of fix for Bug 5604139 */
2417 l_sec_adjustment_quantity NUMBER; -- nsinghi Bug#6052831
2418
2419 BEGIN
2420 IF ( l_debug = 1 ) THEN
2421 print_debug ( '***pre_update***' );
2422 END IF;
2423
2424 /* Bug 4495880-Added the debug messages to check the values of the global constants */
2425
2426 IF ( l_debug = 1 ) THEN
2427 print_debug ( 'Value of g_cc_entry.subinventory:'|| g_cc_entry.subinventory );
2428 print_debug ( 'Value of g_cc_entry.locator_id:' || g_cc_entry.locator_id );
2429 print_debug ( 'Value of g_cc_entry.parent_lpn_id ' || g_cc_entry.parent_lpn_id );
2430 print_debug ( 'Value of g_count_quantity ' || g_count_quantity );
2431 END IF;
2432
2433 /* End of fix for Bug 4495880 */
2434
2435 /* Bug 4495880 -For counts with lpns, checking if there is a discrepancy in location
2436 of the lpn from mcce and wlpn . Further for the context 1 lpns, if
2437 a count quantity of 0 is entered, setting the global constant to TRUE */
2438
2439 IF ( g_cc_entry.parent_lpn_id IS NOT NULL ) THEN
2440
2441 SELECT NVL ( subinventory_code, '###' ),
2442 NVL ( locator_id, -99 ),
2443 lpn_context
2444 INTO l_lpn_subinv,
2445 l_lpn_locator_id,
2446 l_lpn_context
2447 FROM WMS_LICENSE_PLATE_NUMBERS
2448 WHERE lpn_id = g_cc_entry.parent_lpn_id ;
2449
2450 IF ( l_debug = 1 ) THEN
2451 print_debug ( 'l_lpn_subinv: ===> ' || l_lpn_subinv );
2452 print_debug ( 'l_lpn_locator_id: => ' || l_lpn_locator_id );
2453 print_debug ( 'l_lpn_context: => ' || l_lpn_context );
2454 END IF;
2455
2456
2457 IF (l_lpn_subinv <> g_cc_entry.subinventory
2458 OR l_lpn_locator_id <> g_cc_entry.locator_id ) THEN
2459
2460 IF ( l_debug = 1 ) THEN
2461 print_debug ( 'Location from wlpn does not match that of mcce' );
2462 END IF;
2463
2464 IF l_lpn_context=1 and g_count_quantity = 0 THEN
2465
2466 IF ( l_debug = 1 ) THEN
2467 print_debug ( 'LPN context is 1 and quantity entered is 0 so setting the paramter g_condition to TRUE' );
2468 END IF;
2469
2470 g_condition:=TRUE ;
2471
2472 END IF;
2473
2474 END IF;
2475
2476 END IF;
2477
2478 /* End of fix for Bug 4495880 */
2479
2480
2481 -- Get the required variable values
2482 SELECT serial_number_control_code
2483 INTO l_serial_number_ctrl_code
2484 FROM mtl_system_items
2485 WHERE inventory_item_id = g_cc_entry.inventory_item_id
2486 AND organization_id = g_cc_entry.organization_id;
2487
2488 SELECT NVL ( serial_detail_option, 1 ),
2489 NVL ( serial_count_option, 1 )
2490 INTO l_serial_detail_option,
2491 l_serial_count_option
2492 FROM mtl_cycle_count_headers
2493 WHERE cycle_count_header_id = g_cc_entry.cycle_count_header_id
2494 AND organization_id = g_cc_entry.organization_id;
2495
2496 -- Compare the current entry's number of counts with the value
2497 -- in the record stored in the table
2498 SELECT NVL ( number_of_counts, 0 )
2499 INTO l_old_num_counts
2500 FROM mtl_cycle_count_entries
2501 WHERE cycle_count_entry_id = l_cc_entry_id;
2502
2503 IF ( l_old_num_counts > l_number_of_counts ) THEN
2504 FND_MESSAGE.SET_NAME ( 'INV', 'INV_DUPLICATE_COUNT_UPDATE' );
2505 FND_MSG_PUB.ADD;
2506 RAISE FND_API.G_EXC_ERROR;
2507 END IF;
2508
2509 IF ( l_count_type_code = 4 ) THEN
2510 -- Zero Count
2511 zero_count_logic ( );
2512 ELSE
2513 IF ( l_serial_number_ctrl_code IN ( 1, 6 ) ) THEN
2514 -- Not serial controlled
2515
2516 l_number_of_counts := ( NVL ( l_number_of_counts, 0 ) + 1 );
2517 g_cc_entry.number_of_counts := l_number_of_counts;
2518 -- Get the system quantity
2519 -- nsinghi bug#6052831. Call the overloaded procedure.
2520 -- system_quantity ( x_system_quantity => l_system_quantity );
2521 system_quantity (x_system_quantity => l_system_quantity
2522 , x_sec_system_quantity => l_sec_system_quantity);
2523
2524 -- Get the item primary uom code
2525 SELECT primary_uom_code
2526 INTO l_primary_uom
2527 FROM MTL_SYSTEM_ITEMS
2528 WHERE inventory_item_id = g_cc_entry.inventory_item_id
2529 AND organization_id = g_cc_entry.organization_id;
2530
2531 -- Convert the system quantity into the count uom
2532 /*2977228l_system_quantity :=
2533 inv_convert.inv_um_convert ( g_cc_entry.inventory_item_id,
2534 6,
2535 l_system_quantity,
2536 l_primary_uom,
2537 g_count_uom,
2538 NULL,
2539 NULL
2540 );*/
2541 -- Convert the count quantity into the item primary uom quantity
2542 l_primary_uom_quantity :=
2543 inv_convert.inv_um_convert ( g_cc_entry.inventory_item_id,
2544 6,
2545 g_count_quantity,
2546 g_count_uom,
2547 l_primary_uom,
2548 NULL,
2549 NULL
2550 );
2551
2552 IF ( l_number_of_counts = 1 ) THEN
2553 entry_to_current ( p_count_date => SYSDATE,
2554 p_counted_by_employee_id => g_employee_id,
2555 p_system_quantity => l_system_quantity,
2556 p_reference => NULL,
2557 p_primary_uom_quantity => l_primary_uom_quantity,
2558 p_sec_system_quantity => l_sec_system_quantity -- nsinghi bug#6052831 Pass sec qty.
2559 );
2560 current_to_first ( );
2561 ELSE
2562 current_to_prior ( );
2563 g_updated_prior := TRUE; -- Bug 6371673
2564 entry_to_current ( p_count_date => SYSDATE,
2565 p_counted_by_employee_id => g_employee_id,
2566 p_system_quantity => l_system_quantity,
2567 p_reference => NULL,
2568 p_primary_uom_quantity => l_primary_uom_quantity,
2569 p_sec_system_quantity => l_sec_system_quantity -- nsinghi bug#6052831 Pass sec qty.
2570 );
2571 END IF;
2572
2573 IF ( l_pre_approve_flag = 'TRUE' ) THEN
2574 g_cc_entry.entry_status_code := 5;
2575 g_cc_entry.approval_type := 3;
2576 g_cc_entry.approver_employee_id := g_employee_id;
2577 print_debug('from pre_update : 1');
2578 final_preupdate_logic ( );
2579 ELSE
2580 get_tolerances ( pre_approve_flag => l_pre_approve_flag,
2581 x_approval_tolerance_positive => l_approval_tolerance_positive,
2582 x_approval_tolerance_negative => l_approval_tolerance_negative,
2583 x_cost_tolerance_positive => l_cost_tolerance_positive,
2584 x_cost_tolerance_negative => l_cost_tolerance_negative
2585 );
2586 END IF;
2587 g_updated_prior := FALSE; -- Bug 6371673
2588 ELSIF ( l_serial_number_ctrl_code IN ( 2, 5 ) ) THEN
2589 -- Serial controlled item
2590 IF ( l_serial_count_option = 3 ) THEN
2591 -- Multiple serial per request
2592 is_serial_entered ( 'WHEN-VALIDATE-RECORD', l_serial_entered );
2593
2594 --Added the or condition in the below if statement for bug#4424743
2595 IF ( l_serial_entered = 0 or (l_serial_entered = 1 and g_count_quantity = 0)) THEN
2596 IF ( l_debug = 1 ) THEN
2597 print_debug ( 'Serial entered: ' || l_serial_entered );
2598 END IF;
2599
2600 get_tolerances ( pre_approve_flag => l_pre_approve_flag,
2601 x_approval_tolerance_positive => l_approval_tolerance_positive,
2602 x_approval_tolerance_negative => l_approval_tolerance_negative,
2603 x_cost_tolerance_positive => l_cost_tolerance_positive,
2604 x_cost_tolerance_negative => l_cost_tolerance_negative
2605 );
2606 ELSIF ( l_serial_entered = 1 ) THEN
2607 -- If the serial number was entered, then make sure that the number
2608 -- of serial_number marked present matches the quantity entered.
2609 IF ( l_debug = 1 ) THEN
2610 print_debug ( 'Serial entered: ' || l_serial_entered );
2611 END IF;
2612
2613 SELECT SUM ( DECODE ( UNIT_STATUS_CURRENT, 1, 1, 0 ) )
2614 INTO l_total_serial_num_cnt
2615 FROM MTL_CC_SERIAL_NUMBERS
2616 WHERE CYCLE_COUNT_ENTRY_ID = l_cc_entry_id;
2617
2618 IF ( l_total_serial_num_cnt <> l_count_quantity ) THEN
2619 FND_MESSAGE.SET_NAME ( 'INV',
2620 'INV_CC_SERIAL_DETAIL_MISMATCH'
2621 );
2622 FND_MSG_PUB.ADD;
2623 RAISE FND_API.G_EXC_ERROR;
2624 END IF;
2625
2626 IF ( l_entry_status_code = 5 ) THEN
2627 -- Completed count entries
2628 g_cc_entry.approval_date := SYSDATE;
2629
2630 IF ( l_debug = 1 ) THEN
2631 print_debug ( 'Multiple entry has been completed so call final_preupdate_logic'
2632 );
2633 END IF;
2634
2635 -- Call this to process LPN discrepancies if any
2636 IF ( l_debug = 1 ) THEN
2637 print_debug ( 'This is to process LPN discrepancy if any exist'
2638 );
2639 END IF;
2640 print_debug('from pre_update : 2');
2641 final_preupdate_logic ( );
2642 END IF;
2643 END IF;
2644
2645 -- Bug# 2379128
2646 -- The following code before was only called when
2647 -- l_serial_entered was equal to 1. We need to do this
2648 -- updating even if l_serial_entered is equal to 0
2649 l_number_of_counts := ( NVL ( l_number_of_counts, 0 ) + 1 );
2650 g_cc_entry.number_of_counts := l_number_of_counts;
2651 -- Get the system quantity
2652 system_quantity ( x_system_quantity => l_system_quantity
2653 , x_sec_system_quantity => l_sec_system_quantity ); -- nsinghi Bug#6052831. Call overloaded API.
2654
2655 -- Get the item primary uom code
2656 SELECT primary_uom_code
2657 INTO l_primary_uom
2658 FROM MTL_SYSTEM_ITEMS
2659 WHERE inventory_item_id = g_cc_entry.inventory_item_id
2660 AND organization_id = g_cc_entry.organization_id;
2661
2662 -- Convert the system quantity into the count uom
2663 /*2977228l_system_quantity :=
2664 inv_convert.inv_um_convert ( g_cc_entry.inventory_item_id,
2665 6,
2666 l_system_quantity,
2667 l_primary_uom,
2668 g_count_uom,
2669 NULL,
2670 NULL
2671 );*/
2672 -- Convert the count quantity into the item primary uom quantity
2673 l_primary_uom_quantity :=
2674 inv_convert.inv_um_convert ( g_cc_entry.inventory_item_id,
2675 6,
2676 g_count_quantity,
2677 g_count_uom,
2678 l_primary_uom,
2679 NULL,
2680 NULL
2681 );
2682
2683 IF ( l_number_of_counts = 1 ) THEN
2684 entry_to_current ( p_count_date => SYSDATE,
2685 p_counted_by_employee_id => g_employee_id,
2686 p_system_quantity => l_system_quantity,
2687 p_reference => NULL,
2688 p_primary_uom_quantity => l_primary_uom_quantity,
2689 p_sec_system_quantity => l_sec_system_quantity -- nsinghi bug#6052831 Pass sec qty.
2690 );
2691 current_to_first ( );
2692 ELSE
2693 current_to_prior ( );
2694 entry_to_current ( p_count_date => SYSDATE,
2695 p_counted_by_employee_id => g_employee_id,
2696 p_system_quantity => l_system_quantity,
2697 p_reference => NULL,
2698 p_primary_uom_quantity => l_primary_uom_quantity,
2699 p_sec_system_quantity => l_sec_system_quantity -- nsinghi bug#6052831 Pass sec qty.
2700 );
2701 END IF;
2702 -- Bug 5186993, if recount unmarking the serials and re-setting serials in MCSN.
2703 if (l_entry_status_code = 3) then
2704 unmark(l_cc_entry_id);
2705 UPDATE MTL_CC_SERIAL_NUMBERS
2706 SET
2707 UNIT_STATUS_CURRENT = DECODE((NVL(POS_ADJUSTMENT_QTY,0) -
2708 NVL(NEG_ADJUSTMENT_QTY,0)), 1, 2, -1, 1, UNIT_STATUS_CURRENT),
2709 POS_ADJUSTMENT_QTY = 0,
2710 NEG_ADJUSTMENT_QTY = 0,
2711 APPROVAL_CONDITION = NULL
2712 WHERE CYCLE_COUNT_ENTRY_ID = l_cc_entry_id;
2713 end if;
2714 ELSIF ( l_serial_count_option = 2 ) THEN
2715 -- Single serial per request
2716 g_serial_out_tolerance := FALSE;
2717 -- Update the number of counts
2718 l_number_of_counts := ( NVL ( l_number_of_counts, 0 ) + 1 );
2719 g_cc_entry.number_of_counts := l_number_of_counts;
2720 -- Get the system quantity
2721 system_quantity ( x_system_quantity => l_system_quantity
2722 , x_sec_system_quantity => l_sec_system_quantity ); -- nsinghi Bug#6052831. Call overloaded API.
2723
2724
2725 /* Added tbe below code for bug#5604139 */
2726 -- Get and set the adjustment quantity and adjustment value
2727 l_adjustment_quantity := g_count_quantity - l_system_quantity;
2728 g_cc_entry.adjustment_quantity := l_adjustment_quantity;
2729 -- nsinghi bug#6052831 START.
2730 IF g_count_secondary_quantity IS NOT NULL AND l_sec_system_quantity IS NOT NULL THEN
2731 l_sec_adjustment_quantity := g_count_secondary_quantity - l_sec_system_quantity;
2732 g_cc_entry.secondary_adjustment_quantity := l_sec_adjustment_quantity;
2733 END IF;
2734 -- nsinghi bug#6052831 END.
2735 g_cc_entry.adjustment_date := SYSDATE;
2736 value_variance ( x_value_variance => l_adjustment_value );
2737 g_cc_entry.adjustment_amount := l_adjustment_value;
2738 /* End of fix for Bug 5604139*/
2739
2740
2741 -- Get the item primary uom code
2742 SELECT primary_uom_code
2743 INTO l_primary_uom
2744 FROM MTL_SYSTEM_ITEMS
2745 WHERE inventory_item_id = g_cc_entry.inventory_item_id
2746 AND organization_id = g_cc_entry.organization_id;
2747
2748 -- Convert the system quantity into the count uom
2749 /*2977228l_system_quantity :=
2750 inv_convert.inv_um_convert ( g_cc_entry.inventory_item_id,
2751 6,
2752 l_system_quantity,
2753 l_primary_uom,
2754 g_count_uom,
2755 NULL,
2756 NULL
2757 );*/
2758 -- Convert the count quantity into the item primary uom quantity
2759 l_primary_uom_quantity :=
2760 inv_convert.inv_um_convert ( g_cc_entry.inventory_item_id,
2761 6,
2762 g_count_quantity,
2763 g_count_uom,
2764 l_primary_uom,
2765 NULL,
2766 NULL
2767 );
2768
2769 IF ( l_count_quantity <> l_system_quantity ) THEN
2770 mark ( );
2771 END IF;
2772
2773 IF ( l_number_of_counts = 1 ) THEN
2774 entry_to_current ( p_count_date => SYSDATE,
2775 p_counted_by_employee_id => g_employee_id,
2776 p_system_quantity => l_system_quantity,
2777 p_reference => NULL,
2778 p_primary_uom_quantity => l_primary_uom_quantity,
2779 p_sec_system_quantity => l_sec_system_quantity -- nsinghi bug#6052831 Pass sec qty.
2780 );
2781 current_to_first ( );
2782 ELSE
2783 current_to_prior ( );
2784 entry_to_current ( p_count_date => SYSDATE,
2785 p_counted_by_employee_id => g_employee_id,
2786 p_system_quantity => l_system_quantity,
2787 p_reference => NULL,
2788 p_primary_uom_quantity => l_primary_uom_quantity,
2789 p_sec_system_quantity => l_sec_system_quantity -- nsinghi bug#6052831 Pass sec qty.
2790 );
2791 END IF;
2792
2793 -- Call existing serial number which in turn will call
2794 -- final_preupdate_logic if an adjustment is needed
2795 existing_serial_number ( );
2796
2797 IF ( l_entry_status_code = 5 ) THEN
2798 -- Completed count entries
2799 g_cc_entry.approval_date := SYSDATE;
2800 END IF;
2801 END IF;
2802 END IF;
2803 END IF;
2804 EXCEPTION
2805 WHEN NO_DATA_FOUND THEN
2806 RAISE FND_API.G_EXC_ERROR;
2807 END pre_update;
2808
2809 PROCEDURE final_preupdate_logic
2810 IS
2811 l_entry_status_code NUMBER := g_cc_entry.entry_status_code;
2812 l_number_of_counts NUMBER := g_cc_entry.number_of_counts;
2813 l_adjustment_quantity NUMBER := g_cc_entry.adjustment_quantity;
2814 l_sec_adjustment_quantity NUMBER := g_cc_entry.secondary_adjustment_quantity; -- nsinghi bug#6052831
2815 l_transaction_id NUMBER;
2816 l_org_id NUMBER := g_cc_entry.organization_id;
2817 l_cc_header_id NUMBER := g_cc_entry.cycle_count_header_id;
2818 l_item_id NUMBER := g_cc_entry.inventory_item_id;
2819 l_sub VARCHAR2 ( 10 ) := g_cc_entry.subinventory;
2820 l_txn_quantity NUMBER := g_cc_entry.adjustment_quantity;
2821 l_txn_uom VARCHAR2 ( 3 ) := g_cc_entry.count_uom_current;
2822 l_lot_num VARCHAR2 ( 30 ) := g_cc_entry.lot_number;
2823 l_lot_exp_date DATE;
2824 l_rev VARCHAR2 ( 3 ) := g_cc_entry.revision;
2825 l_locator_id NUMBER := g_cc_entry.locator_id;
2826 l_txn_ref VARCHAR2 ( 240 ) := NULL;
2827 l_reason_id NUMBER := g_cc_entry.transaction_reason_id;
2828 l_txn_header_id NUMBER := NVL ( g_txn_header_id, -2 );
2829 l_txn_temp_id NUMBER;
2830 l_user_id NUMBER := g_user_id;
2831 l_login_id NUMBER := g_login_id;
2832 l_txn_proc_mode NUMBER := g_txn_proc_mode;
2833 l_txn_acct_id NUMBER;
2834 l_success_flag NUMBER;
2835 l_p_uom_qty NUMBER;
2836 l_cycle_count_entry_id NUMBER := g_cc_entry.cycle_count_entry_id;
2837 l_from_uom VARCHAR2 ( 3 );
2838 l_to_uom VARCHAR2 ( 3 );
2839 l_txn_date DATE := SYSDATE;
2840 l_serial_number VARCHAR2 ( 30 ) := g_cc_entry.serial_number;
2841 l_serial_prefix VARCHAR2 ( 30 );
2842 l_lpn_id NUMBER := g_cc_entry.parent_lpn_id;
2843 l_cost_group_id NUMBER := g_cc_entry.cost_group_id;
2844 l_system_quantity NUMBER;
2845 l_primary_uom_quantity NUMBER;
2846 -- Variables used for handling serial discrepancies
2847 l_msn_subinv VARCHAR2 ( 10 );
2848 l_msn_lot_number VARCHAR2 ( 30 );
2849 l_msn_locator_id NUMBER;
2850 l_msn_revision VARCHAR2 ( 3 );
2851 l_current_status NUMBER;
2852 l_adj_qty NUMBER;
2853 l_msn_lpn_id NUMBER;
2854 l_serial_number_ctrl_code NUMBER;
2855 l_serial_count_option NUMBER;
2856 -- Variables used for handling lpn discrepancies
2857 l_lpn_subinv VARCHAR2 ( 10 );
2858 l_lpn_locator_id NUMBER;
2859 l_lpn_discrepancy_flag NUMBER := 0;
2860 l_temp_lpn_count NUMBER;
2861 l_item_name VARCHAR2 ( 100 );
2862 -- Bug # 2743382
2863
2864 v_available_quantity NUMBER;
2865 v_entry_status_code NUMBER;
2866 x_return_status VARCHAR2 ( 10 );
2867 x_qoh NUMBER;
2868 x_att NUMBER;
2869 v_ser_code NUMBER;
2870 v_lot_code NUMBER;
2871 v_rev_code NUMBER;
2872 v_is_ser_controlled BOOLEAN := FALSE;
2873 v_is_lot_controlled BOOLEAN := FALSE;
2874 v_is_rev_controlled BOOLEAN := FALSE;
2875 l_rqoh NUMBER;
2876 l_qr NUMBER;
2877 l_qs NUMBER;
2878 l_atr NUMBER;
2879 l_msg_count NUMBER;
2880 l_msg_data VARCHAR2 ( 2000 );
2881 l_parent_lpn_id NUMBER;
2882 l_neg_inv_rcpt_code NUMBER;
2883 l_debug NUMBER := NVL ( FND_PROFILE.VALUE ( 'INV_DEBUG_TRACE' ), 0 );
2884 l_allow_neg_onhand_prof_val NUMBER;-- 4870490
2885 l_sec_uom VARCHAR2(3) := g_count_secondary_uom ; -- INVCONV,NSRIVAST
2886 l_sec_qty NUMBER := g_count_secondary_quantity ; -- INVCONV,NSRIVAST
2887 -- nsinghi bug#6052831
2888 l_sqoh NUMBER;
2889 l_srqoh NUMBER;
2890 l_sqr NUMBER;
2891 l_sqs NUMBER;
2892 l_satt NUMBER;
2893 l_satr NUMBER;
2894 -- nsinghi bug#6052831
2895 BEGIN
2896 IF ( l_debug = 1 ) THEN
2897 print_debug ( '***final_preupdate_logic***' );
2898 END IF;
2899
2900 /* Bug 5704910*/
2901 --Clearing the quantity tree cache
2902 inv_quantity_tree_pub.clear_quantity_cache;
2903
2904 -- Get the required variable values
2905 -- Get the item primary uom code
2906 SELECT primary_uom_code
2907 INTO l_to_uom
2908 FROM MTL_SYSTEM_ITEMS
2909 WHERE inventory_item_id = g_cc_entry.inventory_item_id
2910 AND organization_id = g_cc_entry.organization_id;
2911
2912 SELECT serial_number_control_code
2913 INTO l_serial_number_ctrl_code
2914 FROM mtl_system_items
2915 WHERE inventory_item_id = g_cc_entry.inventory_item_id
2916 AND organization_id = g_cc_entry.organization_id;
2917
2918 SELECT NVL ( serial_count_option, 1 ),
2919 NVL ( inventory_adjustment_account, -1 )
2920 INTO l_serial_count_option,
2921 l_txn_acct_id
2922 FROM mtl_cycle_count_headers
2923 WHERE cycle_count_header_id = g_cc_entry.cycle_count_header_id
2924 AND organization_id = g_cc_entry.organization_id;
2925
2926 SELECT concatenated_segments
2927 INTO l_item_name
2928 FROM mtl_system_items_kfv
2929 WHERE inventory_item_id = l_item_id AND organization_id = l_org_id;
2930
2931 -- Bug 3296675, we need to delete cycle count reservations before checking for availability.
2932 IF ( l_entry_status_code = 5 ) THEN
2933 delete_reservation ( );
2934 END IF;
2935
2936 -- Bug # 2743382
2937
2938 SELECT negative_inv_receipt_code
2939 INTO l_neg_inv_rcpt_code --Negative Balance 1:Allowed 2:Disallowed
2940 FROM mtl_parameters
2941 WHERE organization_id = l_org_id;
2942
2943 --4870490
2944 l_allow_neg_onhand_prof_val := NVL(FND_PROFILE.VALUE('INV_ALLOW_CC_TXNS_ONHAND_NEG'),2);
2945
2946 print_debug ( 'l_neg_inv_rcpt_mode '||l_neg_inv_rcpt_code );
2947 print_debug ( 'l_allow_neg_onhand_prof_val '||l_allow_neg_onhand_prof_val );
2948
2949
2950 -- Bug number 4469742 commented the IF clause here AS per the discussion WITH the PM
2951 -- for the complete opinion from the PM please refer to the update in the bug
2952 --*** JSHERMAN 07/01/05 02:44 pm ***
2953 -- after this the check IF (v_available_quantity + v_adjustment_quantity < 0) will happen
2954 -- irrespective of the the l_neg_inv_rcpt_code flag value
2955
2956 --IF ( l_neg_inv_rcpt_code = 2 ) THEN
2957
2958 -- print_debug ( 'l_neg_inv_rcpt_mode = 2' );
2959 SELECT serial_number_control_code,
2960 lot_control_code,
2961 revision_qty_control_code
2962 INTO v_ser_code,
2963 v_lot_code,
2964 v_rev_code
2965 FROM mtl_system_items
2966 WHERE inventory_item_id = l_item_id AND organization_id = l_org_id;
2967
2968 IF ( v_ser_code <> 1 ) THEN
2969 v_is_ser_controlled := TRUE;
2970 END IF;
2971
2972 IF ( v_lot_code <> 1 ) THEN
2973 v_is_lot_controlled := TRUE;
2974 END IF;
2975
2976 IF ( v_rev_code <> 1 ) THEN
2977 v_is_rev_controlled := TRUE;
2978 END IF;
2979
2980 /* Bug 5725198-Checking if the count is for an LPN, in that case, query quantity tree
2981 for the LPN along with it's subinventory/location. */
2982
2983 IF ( l_lpn_id IS NOT NULL ) THEN
2984 SELECT NVL ( subinventory_code, '###' ),
2985 NVL ( locator_id, -99 )
2986 INTO l_lpn_subinv,
2987 l_lpn_locator_id
2988 FROM WMS_LICENSE_PLATE_NUMBERS
2989 WHERE lpn_id = l_lpn_id;
2990
2991 IF ( l_debug = 1 ) THEN
2992 print_debug ( 'l_lpn_subinv: ===> ' || l_lpn_subinv );
2993 print_debug ( 'l_lpn_locator_id: => ' || l_lpn_locator_id );
2994 END IF;
2995
2996 IF ( l_lpn_subinv <> '###' AND l_lpn_locator_id <> -99 ) THEN
2997
2998 inv_quantity_tree_pub.query_quantities ( p_api_version_number => 1.0,
2999 p_init_msg_lst => 'F',
3000 x_return_status => x_return_status,
3001 x_msg_count => l_msg_count,
3002 x_msg_data => l_msg_data,
3003 p_organization_id => l_org_id,
3004 p_inventory_item_id => l_item_id,
3005 p_tree_mode => 1,
3006 p_is_revision_control => v_is_rev_controlled,
3007 p_is_lot_control => v_is_lot_controlled,
3008 p_is_serial_control => v_is_ser_controlled,
3009 p_demand_source_type_id => NULL,
3010 p_revision => l_rev,
3011 p_lot_number => l_lot_num,
3012 p_lot_expiration_date => l_lot_exp_date,
3013 p_subinventory_code => l_lpn_subinv,
3014 p_locator_id => l_lpn_locator_id,
3015 p_onhand_source => 3,
3016 p_lpn_id => l_lpn_id,
3017 x_qoh => x_qoh,
3018 x_rqoh => l_rqoh,
3019 x_qr => l_qr,
3020 x_qs => l_qs,
3021 x_att => x_att,
3022 x_atr => l_atr
3023 );
3024
3025 v_available_quantity:= x_att;
3026
3027 ELSE
3028 v_available_quantity:= 0;
3029
3030 END IF ;
3031
3032 print_debug ( 'After querying with lpn and lpn location');
3033 print_debug ( 'v_available_quantity: '||v_available_quantity);
3034 print_debug ( 'x_qoh:'|| x_qoh );
3035 print_debug ( 'l_rqoh:'|| l_rqoh );
3036 print_debug ( 'l_qr:'|| l_qr );
3037 print_debug ( 'l_qs:'|| l_qs );
3038 print_debug ( 'l_atr:'||l_atr );
3039 print_debug ( 'l_adjustment_quantity '||l_adjustment_quantity );
3040 print_debug ( 'l_sec_adjustment_quantity '||l_sec_adjustment_quantity ); -- nsinghi bug#6052831
3041 print_debug ( 'v_entry_status_code '||v_entry_status_code );
3042 print_debug ( 'l_entry_status_code '||l_entry_status_code );
3043
3044 ELSE --Querying qty tree as before
3045 /*
3046 End of Bug 5725198
3047 */
3048
3049 inv_quantity_tree_pub.query_quantities ( p_api_version_number => 1.0,
3050 p_init_msg_lst => 'F',
3051 x_return_status => x_return_status,
3052 x_msg_count => l_msg_count,
3053 x_msg_data => l_msg_data,
3054 p_organization_id => l_org_id,
3055 p_inventory_item_id => l_item_id,
3056 p_tree_mode => 1,
3057 p_is_revision_control => v_is_rev_controlled,
3058 p_is_lot_control => v_is_lot_controlled,
3059 p_is_serial_control => v_is_ser_controlled,
3060 p_demand_source_type_id => NULL,
3061 p_revision => l_rev,
3062 p_lot_number => l_lot_num,
3063 p_lot_expiration_date => l_lot_exp_date,
3064 p_subinventory_code => l_sub,
3065 p_locator_id => l_locator_id,
3066 p_onhand_source => 3,
3067 x_qoh => x_qoh,
3068 x_rqoh => l_rqoh,
3069 x_qr => l_qr,
3070 x_qs => l_qs,
3071 x_att => x_att,
3072 x_atr => l_atr
3073 );
3074 v_available_quantity := x_att;
3075
3076 print_debug ( 'v_available_quantity '||v_available_quantity);
3077 print_debug ( 'x_qoh '|| x_qoh);
3078 print_debug ( 'l_rqoh '|| l_rqoh);
3079 print_debug ( 'l_qr '|| l_qr);
3080 print_debug ( 'l_qs '|| l_qs);
3081 print_debug ( 'l_atr '||l_atr );
3082 print_debug ( 'l_adjustment_quantity '||l_adjustment_quantity );
3083 print_debug ( 'l_sec_adjustment_quantity '||l_sec_adjustment_quantity ); -- nsinghi bug#6052831
3084 print_debug ( 'v_entry_status_code '||v_entry_status_code );
3085 print_debug ( 'l_entry_status_code '||l_entry_status_code );
3086
3087 /* End of fix for Bug 5725198 */
3088 END IF;
3089 /* End of fix for Bug 5725198 */
3090
3091
3092 /*Bug Number 4870490
3093 Profile Value : Yes-1
3094 No/NUll- 2
3095 l_neg_rcpt_code 1- Allow
3096 2-Disallow
3097
3098 Approval Option L-Neg_rcpot Code Profile Value Behaviour
3099
3100 Always 1 1 Allows Approval
3101 Always 1 2 On Approval Error is shown
3102 Always 2 1 On Approval Error is shown
3103 Always 2 2 On Approval Error is shown
3104
3105
3106 Approval Option L-Neg_rcpot Code Profile Value Behaviour
3107
3108 Never 1 1 Adjustments happen at entry
3109 Never 1 2 Adjustments Deferrred to Approval
3110 Never 2 1 Adjustments Deferrred to Approval
3111 Never 2 2 Adjustments Deferrred to Approval
3112
3113 */
3114
3115 --Bug 6601010 - Added a condition to check if it is a subxfer of the LPN. Otherwise earlier check
3116 IF ( (l_lpn_subinv <> '###' AND l_lpn_locator_id <> -99) AND
3117 (l_lpn_subinv <> g_cc_entry.subinventory OR l_lpn_locator_id <> g_cc_entry.locator_id ))
3118 THEN
3119 print_debug ( 'In condition for discrepancy');
3120
3121 IF x_qoh <> v_available_quantity AND l_entry_status_code = 5 THEN
3122 g_cc_entry.approval_type := NULL;
3123 g_cc_entry.approver_employee_id := NULL;
3124 g_cc_entry.approval_date := NULL;
3125 -- Reset the entry status code to 2: Approval required
3126 -- Do this for both the local variable as well as the global cycle count
3127 -- entry record
3128 g_cc_entry.entry_status_code := 2;
3129 l_entry_status_code := 2;
3130 END IF;
3131 ELSE
3132 --Bug 5095970, changing l_atr to x_att since for non-reservable subs l_atr will be 0
3133 IF ( v_available_quantity + l_adjustment_quantity < 0 AND l_entry_status_code = 5 )
3134 AND (l_allow_neg_onhand_prof_val = 2 OR l_neg_inv_rcpt_code =2 )
3135 THEN
3136 -- The cycle count adjustment should not be processed since it will
3137 -- invalidate an existing reservation/allocation.
3138
3139 -- Reset the approval related colums in the cycle count entry record
3140 g_cc_entry.approval_type := NULL;
3141 g_cc_entry.approver_employee_id := NULL;
3142 g_cc_entry.approval_date := NULL;
3143 -- Reset the entry status code to 2: Approval required
3144 -- Do this for both the local variable as well as the global cycle count
3145 -- entry record
3146 g_cc_entry.entry_status_code := 2;
3147 l_entry_status_code := 2;
3148 END IF;
3149 END IF; --Bug 6601010- End of check
3150
3151 -- Bug number 4469742 moved the IF clause here AS per the discussion WITH the PM
3152 -- for the complete opinion from the PM please refer to the update in the bug
3153 --*** JSHERMAN 07/01/05 02:44 pm ***
3154 -- after this the check IF (v_available_quantity + v_adjustment_quantity < 0) will happen
3155 -- irrespective of the the l_neg_inv_rcpt_code flag value
3156
3157 IF ( l_neg_inv_rcpt_code = 2 ) THEN
3158
3159 /* Bug 5725198-Added the check for LPN being counted to update quantity tree */
3160 IF (( l_lpn_id IS NOT NULL ) AND (l_lpn_subinv <> '###' AND l_lpn_locator_id <> -99)) THEN
3161 inv_quantity_tree_pub.update_quantities ( p_api_version_number => 1.0,
3162 p_init_msg_lst => 'F',
3163 x_return_status => x_return_status,
3164 x_msg_count => l_msg_count,
3165 x_msg_data => l_msg_data,
3166 p_organization_id => l_org_id,
3167 p_inventory_item_id => l_item_id,
3168 p_tree_mode => 1,
3169 p_is_revision_control => v_is_rev_controlled,
3170 p_is_lot_control => v_is_lot_controlled,
3171 p_is_serial_control => v_is_ser_controlled,
3172 p_demand_source_type_id => NULL,
3173 p_revision => l_rev,
3174 p_lot_number => l_lot_num,
3175 p_subinventory_code => l_lpn_subinv,
3176 p_locator_id => l_lpn_locator_id,
3177 p_onhand_source => 3,
3178 p_containerized => 0,
3179 p_primary_quantity => ABS ( l_adjustment_quantity
3180 ),
3181 p_secondary_quantity => ABS ( l_sec_adjustment_quantity ), -- nsinghi bug#6052831
3182 p_quantity_type => 5,
3183 x_qoh => x_qoh,
3184 x_rqoh => l_rqoh,
3185 x_qr => l_qr,
3186 x_qs => l_qs,
3187 x_att => x_att,
3188 x_atr => l_atr,
3189 p_lpn_id => l_lpn_id,
3190 -- nsinghi bug#6052831 START
3191 x_sqoh => l_sqoh,
3192 x_srqoh => l_srqoh,
3193 x_sqr => l_sqr,
3194 x_sqs => l_sqs,
3195 x_satt => l_satt,
3196 x_satr => l_satr
3197 -- nsinghi bug#6052831 END
3198 );
3199 print_debug ( 'Values after updating quantity tree for LPN ');
3200 print_debug ( 'x_qoh '|| x_qoh );
3201 print_debug ( 'l_rqoh '|| l_rqoh );
3202 print_debug ( 'l_qr '|| l_qr );
3203 print_debug ( 'l_qs '|| l_qs );
3204 print_debug ( 'x_att '||x_att );
3205 print_debug ( 'l_atr '||l_atr );
3206 print_debug ( 'l_adjustment_quantity '||l_adjustment_quantity );
3207 print_debug ( 'l_sec_adjustment_quantity '||l_sec_adjustment_quantity ); -- nsinghi bug#6052831
3208 ELSE
3209 /*
3210 End of Bug 5725198
3211 */
3212 inv_quantity_tree_pub.update_quantities ( p_api_version_number => 1.0,
3213 p_init_msg_lst => 'F',
3214 x_return_status => x_return_status,
3215 x_msg_count => l_msg_count,
3216 x_msg_data => l_msg_data,
3217 p_organization_id => l_org_id,
3218 p_inventory_item_id => l_item_id,
3219 p_tree_mode => 1,
3220 p_is_revision_control => v_is_rev_controlled,
3221 p_is_lot_control => v_is_lot_controlled,
3222 p_is_serial_control => v_is_ser_controlled,
3223 p_demand_source_type_id => NULL,
3224 p_revision => l_rev,
3225 p_lot_number => l_lot_num,
3226 p_subinventory_code => l_sub,
3227 p_locator_id => l_locator_id,
3228 p_onhand_source => 3,
3229 p_containerized => 0,
3230 p_primary_quantity => ABS ( l_adjustment_quantity
3231 ),
3232 p_secondary_quantity => ABS ( l_sec_adjustment_quantity ), -- nsinghi bug#6052831
3233 p_quantity_type => 5,
3234 x_qoh => x_qoh,
3235 x_rqoh => l_rqoh,
3236 x_qr => l_qr,
3237 x_qs => l_qs,
3238 x_att => x_att,
3239 x_atr => l_atr,
3240 p_lpn_id => NULL, --added for lpn reservation
3241 -- nsinghi bug#6052831 START
3242 x_sqoh => l_sqoh,
3243 x_srqoh => l_srqoh,
3244 x_sqr => l_sqr,
3245 x_sqs => l_sqs,
3246 x_satt => l_satt,
3247 x_satr => l_satr
3248 -- nsinghi bug#6052831 END
3249 );
3250 print_debug ( 'Values after updating quantity tree for loose quantity ');
3251 /*
3252 For Bug 5725198
3253 */
3254 print_debug ( 'x_qoh '|| x_qoh );
3255 print_debug ( 'l_rqoh '|| l_rqoh );
3256 print_debug ( 'l_qr '|| l_qr );
3257 print_debug ( 'l_qs '|| l_qs );
3258 print_debug ( 'x_att '||x_att );
3259 print_debug ( 'l_atr '||l_atr );
3260 print_debug ( 'l_adjustment_quantity '||l_adjustment_quantity );
3261 print_debug ( 'l_sec_adjustment_quantity '||l_sec_adjustment_quantity ); -- nsinghi bug#6052831
3262 END IF; --End of condition for counting for LPNs
3263 /* End of fix for Bug 5725198 */
3264
3265
3266 END IF;
3267
3268 IF ( l_entry_status_code = 5 ) THEN
3269 g_cc_entry.approval_date := SYSDATE;
3270 -- Delete the reservation
3271 -- Bug 3296675, moved the delete reservation call to final_preupdate_logic and perform_serial_adj_txn
3272 -- since we are checking for availability
3273 -- delete_reservation ( );
3274 END IF;
3275
3276 l_from_uom := g_cc_entry.count_uom_current;
3277 l_txn_uom := l_from_uom;
3278
3279 IF ( l_debug = 1 ) THEN
3280 print_debug ( 'Entry Status Code: ===> ' || l_entry_status_code );
3281 print_debug ( 'Adjustment Quantity: => ' || l_adjustment_quantity );
3282 END IF;
3283
3284 IF ( l_lpn_id IS NOT NULL ) THEN
3285
3286 /* Bug 5725198-Commenting this part since the LPN sub and loc has already been fetched
3287 before querying quantity tree */
3288
3289 -- Check to see if the LPN exists in a discrepant location
3290 /* SELECT NVL ( subinventory_code, '###' ),
3291 NVL ( locator_id, -99 )
3292 INTO l_lpn_subinv,
3293 l_lpn_locator_id
3294 FROM WMS_LICENSE_PLATE_NUMBERS
3295 WHERE lpn_id = l_lpn_id;
3296
3297 --Bug 4346071 Added debug message
3298 IF ( l_debug = 1 ) THEN
3299 print_debug ( 'l_lpn_subinv: ===> ' || l_lpn_subinv );
3300 print_debug ( 'l_lpn_locator_id: => ' || l_lpn_locator_id );
3301 END IF;
3302 --End of fix for Bug 4346071
3303 */
3304 /*
3305 End of commented code for Bug 5725198
3306 */
3307
3308 --Bug 4346071- Added the check for the valus of sub and locator selected from wlpn.
3309 IF l_lpn_subinv <> '###' AND l_lpn_locator_id <> -99 THEN
3310
3311 IF ( ( l_lpn_subinv <> g_cc_entry.subinventory
3312 OR l_lpn_locator_id <> g_cc_entry.locator_id
3313 ) AND (g_condition = FALSE) -- Bug 4495880- Added the check for g_condition also
3314 ) THEN
3315 l_lpn_discrepancy_flag := 1;
3316 ELSE
3317 l_lpn_discrepancy_flag := 0;
3318 END IF;
3319 END IF; --End of fox for Bug 4346071
3320 END IF;
3321
3322 -- Insert into MMTT if the count entry has been completed and
3323 -- either an adjustment needs to be made, or an LPN discrepancy
3324 -- exists in which case we'll need to insert a subinventory transfer
3325 -- record into MMTT
3326 IF ( l_entry_status_code = 5
3327 AND ( l_adjustment_quantity <> 0
3328 OR l_lpn_discrepancy_flag = 1 )
3329 ) THEN
3330
3331 IF ( l_txn_header_id = -2 ) THEN
3332 SELECT mtl_material_transactions_s.NEXTVAL
3333 INTO l_txn_header_id
3334 FROM DUAL;
3335
3336 g_txn_header_id := l_txn_header_id;
3337 print_debug ( 'l_txn_header_id '||l_txn_header_id );
3338 END IF;
3339
3340 IF ( l_serial_number IS NOT NULL ) THEN
3341 print_debug ( 'l_serial_number '||l_serial_number);
3342 SELECT mtl_material_transactions_s.NEXTVAL
3343 INTO l_txn_temp_id
3344 FROM DUAL;
3345
3346 SELECT auto_serial_alpha_prefix
3347 INTO l_serial_prefix
3348 FROM mtl_system_items
3349 WHERE inventory_item_id = l_item_id
3350 AND organization_id = l_org_id;
3351 END IF;
3352
3353 l_p_uom_qty :=
3354 inv_convert.inv_um_convert ( l_item_id,
3355 5,
3356 l_txn_quantity,
3357 l_from_uom,
3358 l_to_uom,
3359 NULL,
3360 NULL
3361 );
3362 l_txn_ref := g_cc_entry.reference_current;
3363
3364
3365
3366
3367
3368 -- This loop is for non multiple serial counts for a serial
3369 -- controlled item entry where the serial was found in a
3370 -- discrepant location. For multiple serials, this logic is
3371 -- taken care of already in the procedure perform_serial_adj_txn
3372 -- The serial number field is always null in the cycle count entries
3373 -- record for multiple serial count option
3374
3375 IF ( l_serial_number IS NOT NULL ) THEN
3376 -- Check to see if the serial number is found
3377 -- in a discrepant location or not
3378 SELECT NVL ( REVISION, 'XXX' ),
3379 NVL ( LOT_NUMBER, 'X' ),
3380 CURRENT_STATUS,
3381 CURRENT_SUBINVENTORY_CODE,
3382 NVL ( CURRENT_LOCATOR_ID, 0 ),
3383 NVL ( LPN_ID, -99 )
3384 INTO l_msn_revision,
3385 l_msn_lot_number,
3386 l_current_status,
3387 l_msn_subinv,
3388 l_msn_locator_id,
3389 l_msn_lpn_id
3390 FROM MTL_SERIAL_NUMBERS
3391 WHERE SERIAL_NUMBER = l_serial_number
3392 AND INVENTORY_ITEM_ID = g_cc_entry.inventory_item_id
3393 AND CURRENT_ORGANIZATION_ID = g_cc_entry.organization_id;
3394
3395 -- If serial number exist with status 3 but at a different loc or revision etc.
3396 -- than we first need to issue out the original serial number and then process
3397 -- the receipt transaction. Additionally, if the serial is found
3398 -- in a different LPN than what is in the system, it will also
3399 -- issue out the serial first before receiving it back into inventory
3400 IF ( l_current_status = 3
3401 AND l_adjustment_quantity = 1
3402 AND ( l_msn_lpn_id <> NVL ( g_cc_entry.parent_lpn_id, -99 )
3403 OR ( ( l_msn_revision <> g_cc_entry.revision
3404 OR l_msn_lot_number <>
3405 g_cc_entry.lot_number
3406 OR l_msn_subinv <> g_cc_entry.subinventory
3407 OR l_msn_locator_id <>
3408 g_cc_entry.locator_id
3409 )
3410 AND l_msn_lpn_id = -99
3411 AND g_cc_entry.parent_lpn_id IS NULL
3412 )
3413 )
3414 ) THEN
3415
3416 IF ( l_msn_revision = 'XXX' ) THEN
3417 l_msn_revision := NULL;
3418 END IF;
3419
3420 IF ( l_msn_lot_number = 'X' ) THEN
3421 l_msn_lot_number := NULL;
3422 END IF;
3423
3424 IF ( l_msn_locator_id = 0 ) THEN
3425 l_msn_locator_id := NULL;
3426 END IF;
3427
3428 IF ( l_msn_lpn_id = -99 ) THEN
3429 l_msn_lpn_id := NULL;
3430 END IF;
3431
3432 l_adj_qty := -1;
3433
3434 IF ( l_debug = 1 ) THEN
3435 print_debug ( 'Serial discrepancy exists so issue out the serial first'
3436 );
3437 print_debug ( 'Calling cc_transact with the following parameters: '
3438 );
3439 print_debug ( 'org_id: ========> ' || l_org_id );
3440 print_debug ( 'cc_header_id: ==> ' || l_cc_header_id );
3441 print_debug ( 'item_id: =======> ' || l_item_id );
3442 print_debug ( 'sub: ===========> ' || l_msn_subinv );
3443 print_debug ( 'puomqty: =======> ' || -l_p_uom_qty );
3444 print_debug ( 'txnqty: ========> ' || l_adj_qty );
3445 print_debug ( 'txnuom: ========> ' || l_txn_uom );
3446 print_debug ( 'txndate: =======> ' || l_txn_date );
3447 print_debug ( 'txnacctid: =====> ' || l_txn_acct_id );
3448 print_debug ( 'lotnum: ========> ' || l_msn_lot_number );
3449 print_debug ( 'lotexpdate: ====> ' || l_lot_exp_date );
3450 print_debug ( 'rev: ===========> ' || l_msn_revision );
3451 print_debug ( 'locator_id: ====> ' || l_msn_locator_id );
3452 print_debug ( 'txnref: ========> ' || l_txn_ref );
3453 print_debug ( 'reasonid: ======> ' || l_reason_id );
3454 print_debug ( 'userid: ========> ' || l_user_id );
3455 print_debug ( 'cc_entry_id: ===> ' || l_cycle_count_entry_id );
3456 print_debug ( 'loginid: =======> ' || l_login_id );
3457 print_debug ( 'txnprocmode: ===> ' || l_txn_proc_mode );
3458 print_debug ( 'txnheaderid: ===> ' || l_txn_header_id );
3459 print_debug ( 'serialnum: =====> ' || l_serial_number );
3460 print_debug ( 'txntempid: =====> ' || l_txn_temp_id );
3461 print_debug ( 'serialprefix: ==> ' || l_serial_prefix );
3462 print_debug ( 'lpn_id: ========> ' || l_msn_lpn_id );
3463 print_debug ( 'cost_group_id: => ' || l_cost_group_id );
3464 print_debug ( ' ' );
3465 END IF;
3466
3467 l_success_flag :=
3468 mtl_cc_transact_pkg.cc_transact ( org_id => l_org_id,
3469 cc_header_id => l_cc_header_id,
3470 item_id => l_item_id,
3471 sub => l_msn_subinv,
3472 puomqty => -l_p_uom_qty,
3473 txnqty => l_adj_qty,
3474 txnuom => l_txn_uom,
3475 txndate => l_txn_date,
3476 txnacctid => l_txn_acct_id,
3477 lotnum => l_msn_lot_number,
3478 lotexpdate => l_lot_exp_date,
3479 rev => l_msn_revision,
3480 locator_id => l_msn_locator_id,
3481 txnref => l_txn_ref,
3482 reasonid => l_reason_id,
3483 userid => l_user_id,
3484 cc_entry_id => l_cycle_count_entry_id,
3485 loginid => l_login_id,
3486 txnprocmode => l_txn_proc_mode,
3487 txnheaderid => l_txn_header_id,
3488 serialnum => l_serial_number,
3489 txntempid => l_txn_temp_id,
3490 serialprefix => l_serial_prefix,
3491 lpn_id => l_msn_lpn_id,
3492 cost_group_id => l_cost_group_id
3493 );
3494
3495 IF ( l_debug = 1 ) THEN
3496 print_debug ( 'success flag: ' || l_success_flag );
3497 END IF;
3498
3499 --If success flag is 2 or 3 then set the message for invalid
3500 --material status for the lot/serial and the item combination
3501 IF ( NVL ( l_success_flag, -1 ) < 0 ) THEN
3502 FND_MESSAGE.SET_NAME ( 'INV', 'INV_ADJ_TXN_FAILED' );
3503 FND_MSG_PUB.ADD;
3504 RAISE FND_API.G_EXC_ERROR;
3505 ELSIF NVL ( l_success_flag, -1 ) = 2 THEN
3506 FND_MESSAGE.SET_NAME ( 'INV', 'INV_TRX_LOT_NA_DUE_MS' );
3507 FND_MESSAGE.SET_TOKEN ( 'TOKEN1', l_msn_lot_number );
3508 FND_MESSAGE.SET_TOKEN ( 'TOKEN2', l_item_name );
3509 FND_MSG_PUB.ADD;
3510 RAISE FND_API.G_EXC_ERROR;
3511 ELSIF NVL ( l_success_flag, -1 ) = 3 THEN
3512 FND_MESSAGE.SET_NAME ( 'INV', 'INV_TRX_SER_NA_DUE_MS' );
3513 FND_MESSAGE.SET_TOKEN ( 'TOKEN1', l_serial_number );
3514 FND_MESSAGE.SET_TOKEN ( 'TOKEN2', l_item_name );
3515 FND_MSG_PUB.ADD;
3516 RAISE FND_API.G_EXC_ERROR;
3517 END IF;
3518
3519 -- Get a new txn temp ID for receiving the serial back into inventory
3520 SELECT mtl_material_transactions_s.NEXTVAL
3521 INTO l_txn_temp_id
3522 FROM DUAL;
3523 END IF;
3524 END IF;
3525
3526 -- This loop deals with processing LPN discrepancies and issuing
3527 -- a sub xfer for the LPN from where it should be on the system to
3528 -- where the LPN was found on the system
3529
3530 IF ( l_lpn_id IS NOT NULL ) THEN
3531 -- Check to see if the LPN exists in a discrepant location
3532 SELECT NVL ( subinventory_code, '###' ),
3533 NVL ( locator_id, -99 )
3534 INTO l_lpn_subinv,
3535 l_lpn_locator_id
3536 FROM WMS_LICENSE_PLATE_NUMBERS
3537 WHERE lpn_id = l_lpn_id;
3538
3539 --Bug4958692.sub and loc are missing in LPN.So no need of doing sub transfer.
3540 IF l_lpn_subinv <> '###' AND l_lpn_locator_id <> -99 THEN
3541
3542 -- If the LPN is found in a different location, then we will
3543 -- need to do an LPN subinventory transfer first
3544 IF ( l_lpn_subinv <> g_cc_entry.subinventory
3545 OR l_lpn_locator_id <> g_cc_entry.locator_id
3546 ) THEN
3547 IF ( l_lpn_subinv = '###' ) THEN
3548 l_lpn_subinv := NULL;
3549 END IF;
3550
3551 IF ( l_lpn_locator_id = -99 ) THEN
3552 l_lpn_locator_id := NULL;
3553 END IF;
3554
3555
3556 -- Check to see if a sub transfer record has already been
3557 -- inserted into MMTT for this LPN so that we only do this once
3558 SELECT COUNT ( * )
3559 INTO l_temp_lpn_count
3560 FROM mtl_material_transactions_temp
3561 WHERE transaction_header_id = l_txn_header_id
3562 AND inventory_item_id = -1
3563 AND content_lpn_id = l_lpn_id
3564 AND transaction_source_id = l_cc_header_id
3565 AND cycle_count_id IS NULL;
3566
3567 IF ( l_temp_lpn_count <> 0 ) THEN
3568 IF ( l_debug = 1 ) THEN
3569 print_debug ( 'The LPN sub xfer record has already been inserted into MMTT'
3570 );
3571 END IF;
3572 ELSE
3573 IF ( l_debug = 1 ) THEN
3574 print_debug ( 'LPN discrepancy exists so transfer the LPN first'
3575 );
3576 print_debug ( 'Calling cc_transact with the following parameters: '
3577 );
3578 print_debug ( 'org_id: ==========> ' || l_org_id );
3579 print_debug ( 'cc_header_id: ====> ' || l_cc_header_id );
3580 print_debug ( 'item_id: =========> ' || -1 );
3581 print_debug ( 'sub: =============> ' || l_lpn_subinv );
3582 print_debug ( 'puomqty: =========> ' || 1 );
3583 print_debug ( 'txnqty: ==========> ' || 1 );
3584 print_debug ( 'txnuom: ==========> ' || 'Ea' );
3585 print_debug ( 'txndate: =========> ' || l_txn_date );
3586 print_debug ( 'txnacctid: =======> ' || l_txn_acct_id );
3587 print_debug ( 'lotnum: ==========> ' || NULL );
3588 print_debug ( 'lotexpdate: ======> ' || NULL );
3589 print_debug ( 'rev: =============> ' || NULL );
3590 print_debug ( 'locator_id: ======> ' || l_lpn_locator_id );
3591 print_debug ( 'txnref: ==========> ' || l_txn_ref );
3592 print_debug ( 'reasonid: ========> ' || l_reason_id );
3593 print_debug ( 'userid: ==========> ' || l_user_id );
3594 print_debug ( 'cc_entry_id: =====> ' || l_cycle_count_entry_id );
3595 print_debug ( 'loginid: =========> ' || l_login_id );
3596 print_debug ( 'txnprocmode: =====> ' || l_txn_proc_mode );
3597 print_debug ( 'txnheaderid: =====> ' || l_txn_header_id );
3598 print_debug ( 'serialnum: =======> ' || NULL );
3599 print_debug ( 'txntempid: =======> ' || l_txn_temp_id );
3600 print_debug ( 'serialprefix: ====> ' || NULL );
3601 print_debug ( 'lpn_id: ==========> ' || l_lpn_id );
3602 print_debug ( 'transfer_sub: ====> '
3603 || g_cc_entry.subinventory
3604 );
3605 print_debug ( 'transfer_loc_id: => '
3606 || g_cc_entry.locator_id
3607 );
3608 print_debug ( 'lpn_discrepancy: => ' || 1 );
3609 print_debug ( ' ' );
3610 END IF;
3611
3612 l_success_flag :=
3613 mtl_cc_transact_pkg.cc_transact ( org_id => l_org_id,
3614 cc_header_id => l_cc_header_id,
3615 item_id => -1,
3616 sub => l_lpn_subinv,
3617 PUOMQty => 1,
3618 TxnQty => 1,
3619 TxnUOM => 'Ea',
3620 TxnDate => l_txn_date,
3621 TxnAcctId => l_txn_acct_id,
3622 LotNum => NULL,
3623 LotExpDate => NULL,
3624 rev => NULL,
3625 locator_id => l_lpn_locator_id,
3626 TxnRef => l_txn_ref,
3627 ReasonId => l_reason_id,
3628 UserId => l_user_id,
3629 cc_entry_id => l_cycle_count_entry_id,
3630 LoginId => l_login_id,
3631 TxnProcMode => l_txn_proc_mode,
3632 TxnHeaderId => l_txn_header_id,
3633 SerialNum => NULL,
3634 TxnTempId => l_txn_temp_id,
3635 SerialPrefix => NULL,
3636 Lpn_Id => l_lpn_id,
3637 transfer_sub => g_cc_entry.subinventory,
3638 transfer_loc_id => g_cc_entry.locator_id,
3639 lpn_discrepancy => 1
3640 );
3641
3642 IF ( l_debug = 1 ) THEN
3643 print_debug ( 'success_flag: ' || l_success_flag );
3644 END IF;
3645
3646 IF ( NVL ( l_success_flag, -1 ) < 0 ) THEN
3647 FND_MESSAGE.SET_NAME ( 'INV', 'INV_ADJ_TXN_FAILED' );
3648 FND_MSG_PUB.ADD;
3649 RAISE FND_API.G_EXC_ERROR;
3650 END IF;
3651
3652 -- Get a new txn temp ID for the next record into MMTT
3653 SELECT mtl_material_transactions_s.NEXTVAL
3654 INTO l_txn_temp_id
3655 FROM DUAL;
3656 END IF;
3657 END IF;
3658 END IF; --End of fix for bug#4958692
3659 END IF;
3660
3661 -- Note, since the procedure system_quantity doesn't consider the sub
3662 -- or loc when finding the quantity for items packed in an LPN, if
3663 -- the LPN is discrepant, a sub transfer for the LPN will be issued.
3664 -- Thus we can still safely insert into MMTT below since the
3665 -- adjustment was calculated based on what was packed in the LPN and
3666 -- didn't take into account the sub or the loc.
3667
3668
3669 IF ( l_txn_quantity <> 0
3670 AND ( l_serial_count_option <> 3
3671 OR l_serial_number_ctrl_code IN ( 1, 6 )
3672 )
3673 ) THEN
3674
3675 -- Insert into MMTT only if an adjustment needs to be made.
3676 -- Do not enter this loop if this was called from a multiple
3677 -- serial count with a serial controlled item that had an LPN
3678 -- discrepancy and needs a sub xfer to be processed for the LPN.
3679 -- The outer loop could have been entered if there was no adjustment
3680 -- to be made but there was an LPN discrepancy and a sub transfer
3681 -- record had to be inserted into MMTT
3682
3683 IF ( l_debug = 1 ) THEN
3684 print_debug ( 'Calling cc_transact with the following parameters: '
3685 );
3686 print_debug ( 'org_id: ========> ' || l_org_id );
3687 print_debug ( 'cc_header_id: ==> ' || l_cc_header_id );
3688 print_debug ( 'item_id: =======> ' || l_item_id );
3689 print_debug ( 'sub: ===========> ' || l_sub );
3690 print_debug ( 'puomqty: =======> ' || l_p_uom_qty );
3691 print_debug ( 'txnqty: ========> ' || l_txn_quantity );
3692 print_debug ( 'txnuom: ========> ' || l_txn_uom );
3693 print_debug ( 'txndate: =======> ' || l_txn_date );
3694 print_debug ( 'txnacctid: =====> ' || l_txn_acct_id );
3695 print_debug ( 'lotnum: ========> ' || l_lot_num );
3696 print_debug ( 'lotexpdate: ====> ' || l_lot_exp_date );
3697 print_debug ( 'rev: ===========> ' || l_rev );
3698 print_debug ( 'locator_id: ====> ' || l_locator_id );
3699 print_debug ( 'txnref: ========> ' || l_txn_ref );
3700 print_debug ( 'reasonid: ======> ' || l_reason_id );
3701 print_debug ( 'userid: ========> ' || l_user_id );
3702 print_debug ( 'cc_entry_id: ===> ' || l_cycle_count_entry_id );
3703 print_debug ( 'loginid: =======> ' || l_login_id );
3704 print_debug ( 'txnprocmode: ===> ' || l_txn_proc_mode );
3705 print_debug ( 'txnheaderid: ===> ' || l_txn_header_id );
3706 print_debug ( 'serialnum: =====> ' || l_serial_number );
3707 print_debug ( 'txntempid: =====> ' || l_txn_temp_id );
3708 print_debug ( 'serialprefix: ==> ' || l_serial_prefix );
3709 print_debug ( 'lpn_id: ========> ' || l_lpn_id );
3710 print_debug ( 'cost_group_id: => ' || l_cost_group_id );
3711 print_debug ( ' ' );
3712 END IF;
3713
3714 l_success_flag :=
3715 mtl_cc_transact_pkg.cc_transact ( org_id => l_org_id,
3716 cc_header_id => l_cc_header_id,
3717 item_id => l_item_id,
3718 sub => l_sub,
3719 puomqty => l_p_uom_qty,
3720 txnqty => l_txn_quantity,
3721 txnuom => l_txn_uom,
3722 txndate => l_txn_date,
3723 txnacctid => l_txn_acct_id,
3724 lotnum => l_lot_num,
3725 lotexpdate => l_lot_exp_date,
3726 rev => l_rev,
3727 locator_id => l_locator_id,
3728 txnref => l_txn_ref,
3729 reasonid => l_reason_id,
3730 userid => l_user_id,
3731 cc_entry_id => l_cycle_count_entry_id,
3732 loginid => l_login_id,
3733 txnprocmode => l_txn_proc_mode,
3734 txnheaderid => l_txn_header_id,
3735 serialnum => l_serial_number,
3736 txntempid => l_txn_temp_id,
3737 serialprefix => l_serial_prefix,
3738 lpn_id => l_lpn_id,
3739 cost_group_id => l_cost_group_id
3740 ,secUOM => l_sec_uom -- INVCONV,NSRIVAST
3741 ,secQty => l_sec_qty -- INVCONV,NSRIVAST
3742 );
3743
3744 IF ( l_debug = 1 ) THEN
3745 print_debug ( 'cc_transact API returned a success flag of: '
3746 || l_success_flag
3747 );
3748 END IF;
3749
3750 --If success flag is 2 or 3 then set the message for invalid
3751 --material status for the lot/serial and the item combination
3752 IF ( ( NVL ( l_txn_header_id, -1 ) < 0 )
3753 OR ( NVL ( l_success_flag, -1 ) < 0 )
3754 ) THEN
3755 FND_MESSAGE.SET_NAME ( 'INV', 'INV_ADJ_TXN_FAILED' );
3756 FND_MSG_PUB.ADD;
3757 RAISE FND_API.G_EXC_ERROR;
3758 ELSIF NVL ( l_success_flag, -1 ) = 2 THEN
3759 FND_MESSAGE.SET_NAME ( 'INV', 'INV_TRX_LOT_NA_DUE_MS' );
3760 FND_MESSAGE.SET_TOKEN ( 'TOKEN1', l_lot_num );
3761 FND_MESSAGE.SET_TOKEN ( 'TOKEN2', l_item_name );
3762 FND_MSG_PUB.ADD;
3763 RAISE FND_API.G_EXC_ERROR;
3764 ELSIF NVL ( l_success_flag, -1 ) = 3 THEN
3765 FND_MESSAGE.SET_NAME ( 'INV', 'INV_TRX_SER_NA_DUE_MS' );
3766 FND_MESSAGE.SET_TOKEN ( 'TOKEN1', l_serial_number );
3767 FND_MESSAGE.SET_TOKEN ( 'TOKEN2', l_item_name );
3768 FND_MSG_PUB.ADD;
3769 RAISE FND_API.G_EXC_ERROR;
3770 END IF;
3771 END IF;
3772 g_cc_entry.adjustment_date := SYSDATE;
3773 -- Set the commit status flag so that the TM will be called in the
3774 -- post commit procedure
3775 g_commit_status_flag := 1;
3776 g_cc_entry.inventory_adjustment_account := l_txn_acct_id;
3777 END IF;
3778 END final_preupdate_logic;
3779
3780 PROCEDURE delete_reservation
3781 IS
3782 l_mtl_reservation_rec INV_RESERVATION_GLOBAL.MTL_RESERVATION_REC_TYPE
3783 := INV_CC_RESERVATIONS_PVT.Define_Reserv_Rec_Type;
3784 l_init_msg_lst VARCHAR2 ( 1 );
3785 l_error_code NUMBER;
3786 l_return_status VARCHAR2 ( 1 );
3787 l_msg_count NUMBER;
3788 l_msg_data VARCHAR2 ( 240 );
3789 lmsg VARCHAR2 ( 2000 );
3790 l_debug NUMBER := NVL ( FND_PROFILE.VALUE ( 'INV_DEBUG_TRACE' ), 0 );
3791
3792 l_lpn_subinv VARCHAR2 ( 10 ); --Bug 6401621
3793 l_lpn_locator_id NUMBER; --Bug 6401621
3794 BEGIN
3795 IF ( l_debug = 1 ) THEN
3796 print_debug ( '***delete_reservation***' );
3797 END IF;
3798
3799 /* Passing input variable */
3800 /* Delete only cycle count reservation */
3801 l_mtl_reservation_rec.demand_source_type_id := 9;
3802 l_mtl_reservation_rec.organization_id := g_cc_entry.organization_id;
3803 l_mtl_reservation_rec.inventory_item_id := g_cc_entry.inventory_item_id;
3804 l_mtl_reservation_rec.subinventory_code := g_cc_entry.subinventory;
3805 l_mtl_reservation_rec.revision := g_cc_entry.revision;
3806 l_mtl_reservation_rec.locator_id := g_cc_entry.locator_id;
3807 l_mtl_reservation_rec.lot_number := g_cc_entry.lot_number;
3808
3809 --Start Bug 6401621 commented out the following line
3810 --l_mtl_reservation_rec.lpn_id := NULL;
3811
3812 -- Bug 6401621 Cycle Count reservation not getting deleted if reservation is stamped with lpn_id
3813 IF g_cc_entry.parent_lpn_id IS NOT NULL THEN
3814 l_mtl_reservation_rec.lpn_id := g_cc_entry.parent_lpn_id;
3815
3816 SELECT NVL (subinventory_code, '###' ),
3817 NVL (locator_id, -99 )
3818 INTO l_lpn_subinv,
3819 l_lpn_locator_id
3820 FROM WMS_LICENSE_PLATE_NUMBERS
3821 WHERE lpn_id = g_cc_entry.parent_lpn_id;
3822
3823 IF ( l_debug = 1 ) THEN
3824 print_debug ( '***l_lpn_subinv***' || l_lpn_subinv );
3825 print_debug ( '***l_lpn_locator_id***' || l_lpn_locator_id);
3826 END IF;
3827
3828 IF ( l_lpn_subinv <> '###' AND l_lpn_locator_id <> -99 ) THEN
3829 l_mtl_reservation_rec.subinventory_code := l_lpn_subinv;
3830 l_mtl_reservation_rec.locator_id := l_lpn_locator_id;
3831 END IF;
3832 ELSE
3833 l_mtl_reservation_rec.lpn_id := NULL;
3834 END IF;
3835 --End Bug 6401621
3836
3837 -- Delete all the reservations
3838 IF ( l_debug = 1 ) THEN
3839 print_debug ( 'Calling Delete_All_Reservation with the following values for the reservation record:'
3840 );
3841 print_debug ( 'demand_source_type_id: => ' || 9 );
3842 print_debug ( 'organization_id: =======> '
3843 || g_cc_entry.organization_id
3844 );
3845 print_debug ( 'inventory_item_id: =====> '
3846 || g_cc_entry.inventory_item_id
3847 );
3848 print_debug ( 'subinventory_code: =====> ' || g_cc_entry.subinventory );
3849 print_debug ( 'revision: ==============> ' || g_cc_entry.revision );
3850 print_debug ( 'locator_id: ============> ' || g_cc_entry.locator_id );
3851 print_debug ( 'lot_number: ============> ' || g_cc_entry.lot_number );
3852 print_debug ( 'lpn_id: ================> ' || NULL );
3853 END IF;
3854
3855 INV_CC_RESERVATIONS_PVT.Delete_All_Reservation ( p_api_version_number => 1.0,
3856 p_init_msg_lst => l_init_msg_lst,
3857 p_mtl_reservation_rec => l_mtl_reservation_rec,
3858 x_error_code => l_error_code,
3859 x_return_status => l_return_status,
3860 x_msg_count => l_msg_count,
3861 x_msg_data => l_msg_data
3862 );
3863
3864 IF ( l_return_status <> 'S' ) THEN
3865 FND_MSG_PUB.Count_AND_Get ( p_count => l_msg_count,
3866 p_data => l_msg_data
3867 );
3868 RAISE FND_API.G_EXC_ERROR;
3869 END IF;
3870 END delete_reservation;
3871
3872 PROCEDURE duplicate_entries
3873 IS
3874 l_count NUMBER;
3875 l_item_id NUMBER := g_cc_entry.inventory_item_id;
3876 l_revision VARCHAR2 ( 3 ) := g_cc_entry.revision;
3877 l_sub VARCHAR2 ( 10 ) := g_cc_entry.subinventory;
3878 l_locator_id NUMBER := g_cc_entry.locator_id;
3879 l_cost_group_id NUMBER := g_cc_entry.cost_group_id;
3880 l_lot VARCHAR2 ( 30 ) := g_cc_entry.lot_number;
3881 l_org_id NUMBER := g_cc_entry.organization_id;
3882 l_cc_header_id NUMBER := g_cc_entry.cycle_count_header_id;
3883 l_cc_serial_number VARCHAR2 ( 30 ) := g_cc_entry.serial_number;
3884 l_debug NUMBER := NVL ( FND_PROFILE.VALUE ( 'INV_DEBUG_TRACE' ), 0 );
3885 l_lpn_id NUMBER := g_cc_entry.parent_lpn_id;
3886
3887 BEGIN
3888 IF ( l_debug = 1 ) THEN
3889 print_debug ( '***duplicate_entries***' );
3890 END IF;
3891
3892 SELECT COUNT ( * )
3893 INTO l_count
3894 FROM mtl_cycle_count_entries
3895 WHERE cycle_count_header_id = l_cc_header_id
3896 AND organization_id = l_org_id
3897 AND inventory_item_id = l_item_id
3898 AND subinventory = l_sub
3899 AND entry_status_code IN ( 1, 2, 3 )
3900 -- AND nvl(export_flag,2) = 2
3901 AND ( l_locator_id IS NULL
3902 OR locator_id = l_locator_id )
3903 AND ( l_revision IS NULL
3904 OR revision = l_revision )
3905 AND ( l_lot IS NULL
3906 OR lot_NUMBER = l_lot )
3907 AND ( l_cc_serial_number IS NULL
3908 OR serial_number = l_cc_serial_number
3909 )
3910 AND ( l_cost_group_id IS NULL
3911 OR cost_group_id = l_cost_group_id)
3912
3913 AND NVL(parent_lpn_id,-1 ) = NVL(l_lpn_id, -1);
3914
3915 IF ( l_count > 0 ) THEN
3916 FND_MESSAGE.SET_NAME ( 'INV', 'INV_OPEN_REQUEST_EXISTS' );
3917 FND_MSG_PUB.ADD;
3918 RAISE FND_API.G_EXC_ERROR;
3919 END IF;
3920 END duplicate_entries;
3921
3922 PROCEDURE post_commit
3923 IS
3924 l_commit_status_flag NUMBER := g_commit_status_flag;
3925 l_txn_proc_mode NUMBER := g_txn_proc_mode;
3926 l_req_id NUMBER;
3927 l_txn_header_id NUMBER := g_txn_header_id;
3928 l_cc_header_id NUMBER := g_cc_entry.cycle_count_header_id;
3929 l_cc_entry_id NUMBER;
3930 l_entry_status_code NUMBER;
3931 l_inventory_item_id NUMBER;
3932 l_wms_installed BOOLEAN;
3933 l_return_status VARCHAR2 ( 3000 );
3934 l_msg_count NUMBER;
3935 l_msg_data VARCHAR2 ( 3000 );
3936 l_org_id NUMBER := g_cc_entry.organization_id;
3937 l_txn_return_status NUMBER;
3938 l_proc_msg VARCHAR2 ( 3000 );
3939 l_serial_count_option NUMBER;
3940
3941 CURSOR serial_control_cc_entry
3942 IS
3943 SELECT cycle_count_entry_id,
3944 entry_status_code,
3945 inventory_item_id
3946 FROM MTL_CYCLE_COUNT_ENTRIES_V
3947 WHERE cycle_count_header_id = l_cc_header_id
3948 -- AND nvl(export_flag,2) = 2
3949 AND serial_number_control_code IN ( 2, 5 );
3950
3951 -- Variables needed for calling the label printing API
3952 l_label_status VARCHAR2 ( 300 ) := NULL;
3953 l_business_flow_code NUMBER := 8;
3954 l_temp_count NUMBER;
3955 l_debug NUMBER := NVL ( FND_PROFILE.VALUE ( 'INV_DEBUG_TRACE' ), 0 );
3956 BEGIN
3957 IF ( l_debug = 1 ) THEN
3958 print_debug ( '***post_commit***' );
3959 print_debug ( 'Commit status flag: => ' || g_commit_status_flag );
3960 print_debug ( 'Txn Process mode: ===> ' || g_txn_proc_mode );
3961 print_debug ( 'Txn header ID: ======> ' || g_txn_header_id );
3962 print_debug ( 'CC header ID: =======> '
3963 || g_cc_entry.cycle_count_header_id
3964 );
3965 print_debug ( 'Organization ID: ====> ' || g_cc_entry.organization_id );
3966 END IF;
3967
3968 -- First make sure that if the commit status flag is 1,
3969 -- that there does indeed exist a record in MMTT for the transaction
3970 -- manager to process
3971 IF ( l_commit_status_flag = 1 ) THEN
3972 SELECT COUNT ( * )
3973 INTO l_temp_count
3974 FROM mtl_material_transactions_temp
3975 WHERE transaction_header_id = l_txn_header_id;
3976
3977 IF ( l_temp_count = 0 ) THEN
3978 IF ( l_debug = 1 ) THEN
3979 print_debug ( 'No record exists in MMTT to process so reset the status flag'
3980 );
3981 END IF;
3982
3983 g_commit_status_flag := 2;
3984 l_commit_status_flag := 2;
3985 END IF;
3986 END IF;
3987
3988 -- Bug# 2278521
3989 -- Don't need to unmark the serials anymore since if they were marked,
3990 -- that means they require an adjustment. The TM will unmark these
3991 -- serials when it has finished processing them.
3992
3993 -- Get the serial count option
3994 /*SELECT NVL(serial_count_option, 1)
3995 INTO l_serial_count_option
3996 FROM mtl_cycle_count_headers
3997 WHERE cycle_count_header_id = l_cc_header_id
3998 AND organization_id = l_org_id;
3999
4000 -- Unmark the serials that were marked previously
4001 -- since they will be processed here
4002 OPEN serial_control_cc_entry;
4003 LOOP
4004 FETCH serial_control_cc_entry INTO l_cc_entry_id,
4005 l_entry_status_code, l_inventory_item_id;
4006 IF (serial_control_cc_entry%NOTFOUND) THEN
4007 EXIT;
4008 END IF;
4009 IF (l_entry_status_code = 5 OR l_entry_status_code = 3) THEN
4010 IF (l_debug = 1) THEN
4011 print_debug('Unmarking the serials for cc_entry_id: ' || l_cc_entry_id);
4012 END IF;
4013 unmark(l_cc_entry_id);
4014 -- If the entry is a multiple serial entry,
4015 -- unmark the serial explicitly here since it was marked
4016 -- through a different process compared to single serial
4017 IF (l_serial_count_option = 3) THEN
4018 UPDATE mtl_serial_numbers
4019 SET group_mark_id = NULL
4020 WHERE inventory_item_id = l_inventory_item_id
4021 AND current_organization_id = l_org_id
4022 AND serial_number IN
4023 (SELECT serial_number
4024 FROM mtl_cc_serial_numbers
4025 WHERE cycle_count_entry_id = l_cc_entry_id);
4026 END IF;
4027 END IF;
4028 END LOOP;
4029 CLOSE serial_control_cc_entry;*/
4030 -- End of Bug# 2278521
4031
4032 IF NVL ( l_commit_status_flag, 2 ) = 1 THEN
4033 IF ( l_txn_proc_mode = 1 ) THEN
4034 /* txn usr exit */
4035
4036 -- Call the new WMS enabled transaction manager here
4037 -- Bug# 2328371
4038 -- Also pass in the business flow code so the TM will
4039 -- automatically print the labels
4040 IF ( l_debug = 1 ) THEN
4041 print_debug ( 'Calling the online TM here: ' || l_txn_header_id
4042 );
4043 END IF;
4044
4045 l_txn_return_status :=
4046 INV_LPN_TRX_PUB.PROCESS_LPN_TRX ( p_trx_hdr_id => l_txn_header_id,
4047 x_proc_msg => l_proc_msg,
4048 p_business_flow_code => l_business_flow_code
4049 );
4050
4051 -- Check if the Transaction Manager was successful or not
4052 IF ( l_debug = 1 ) THEN
4053 print_debug ( 'Txn return status: ' || l_txn_return_status );
4054 END IF;
4055
4056 IF ( l_txn_return_status <> 0 ) THEN
4057 -- This 'Transaction Failed' message is set on the java side
4058 --FND_MESSAGE.SET_NAME('INV', 'INV_FAILED');
4059 --FND_MSG_PUB.ADD;
4060 RAISE FND_API.G_EXC_ERROR;
4061 END IF;
4062
4063 FND_MESSAGE.SET_NAME ( 'INV', 'INV_ADJUSTMENTS_PROCESSED' );
4064 FND_MESSAGE.SET_TOKEN ( 'ENTITY', 'INV_CYCLE_COUNT', TRUE );
4065 FND_MSG_PUB.ADD;
4066 /* Call the label printing API. */
4067 -- Bug# 2328371
4068 -- Since we are passing in the business flow code to the TM,
4069 -- we don't need to explicitly call the label printing API anymore
4070 --print_debug('Calling print_label_wrap with the following input parameters');
4071 --print_debug('p_business_flow_code: => ' || l_business_flow_code);
4072 --print_debug('p_transaction_id: =====> ' || l_txn_header_id);
4073
4074 -- Bug# 2301732
4075 -- Make the call to the label printing API more robust
4076 -- by trapping for exceptions when calling it
4077 /*BEGIN
4078 inv_label.print_label_wrap
4079 ( x_return_status => l_return_status ,
4080 x_msg_count => l_msg_count ,
4081 x_msg_data => l_msg_data ,
4082 x_label_status => l_label_status ,
4083 p_business_flow_code => l_business_flow_code ,
4084 p_transaction_id => l_txn_header_id );
4085 EXCEPTION
4086 WHEN OTHERS THEN
4087 IF (l_debug = 1) THEN
4088 print_debug('Error while calling label printing API');
4089 END IF;
4090 FND_MESSAGE.SET_NAME('INV', 'INV_RCV_CRT_PRINT_LABEL_FAILE');
4091 FND_MSG_PUB.ADD;
4092 END;
4093 IF (l_debug = 1) THEN
4094 print_debug('After calling label printing API: ' || l_return_status || ', ' || l_label_status || ', ' || l_msg_data);
4095 END IF;
4096
4097 IF (l_return_status <> FND_API.G_RET_STS_SUCCESS) THEN
4098 FND_MESSAGE.SET_NAME('INV', 'INV_RCV_CRT_PRINT_LABEL_FAILE');
4099 FND_MSG_PUB.ADD;
4100 END IF;*/
4101 ELSIF ( l_txn_proc_mode = 2 ) THEN
4102 /* txn process concurrent program */
4103
4104 -- Call the new WMS enabled transaction manager here
4105 -- Bug# 2328371
4106 -- Also pass in the business flow code so the TM will
4107 -- automatically print the labels
4108 IF ( l_debug = 1 ) THEN
4109 print_debug ( 'Calling the concurrent TM here: '
4110 || l_txn_header_id
4111 );
4112 END IF;
4113
4114 l_txn_return_status :=
4115 INV_LPN_TRX_PUB.PROCESS_LPN_TRX ( p_trx_hdr_id => l_txn_header_id,
4116 x_proc_msg => l_proc_msg,
4117 p_business_flow_code => l_business_flow_code
4118 );
4119
4120 -- Check if the Transaction Manager was successful or not
4121 IF ( l_debug = 1 ) THEN
4122 print_debug ( 'Txn return status: ' || l_txn_return_status );
4123 END IF;
4124
4125 IF ( l_txn_return_status <> 0 ) THEN
4126 -- This 'Transaction Failed' message is set on the java side
4127 --FND_MESSAGE.SET_NAME('INV', 'INV_FAILED');
4128 --FND_MSG_PUB.ADD;
4129 RAISE FND_API.G_EXC_ERROR;
4130 END IF;
4131
4132 FND_MESSAGE.SET_NAME ( 'INV', 'INV_CONC_SUBMITTED' );
4133 FND_MESSAGE.SET_TOKEN ( 'REQUEST_ID', TO_CHAR ( l_req_id ), FALSE );
4134 FND_MSG_PUB.ADD;
4135 /* Call the label printing API. */
4136 -- Bug# 2328371
4137 -- Since we are passing in the business flow code to the TM,
4138 -- we don't need to explicitly call the label printing API anymore
4139 --print_debug('Calling print_label_wrap with the following input parameters');
4140 --print_debug('p_business_flow_code: => ' || l_business_flow_code);
4141 --print_debug('p_transaction_id: =====> ' || l_txn_header_id);
4142
4143 -- Bug# 2301732
4144 -- Make the call to the label printing API more robust
4145 -- by trapping for exceptions when calling it
4146 /*BEGIN
4147 inv_label.print_label_wrap
4148 ( x_return_status => l_return_status ,
4149 x_msg_count => l_msg_count ,
4150 x_msg_data => l_msg_data ,
4151 x_label_status => l_label_status ,
4152 p_business_flow_code => l_business_flow_code ,
4153 p_transaction_id => l_txn_header_id );
4154 EXCEPTION
4155 WHEN OTHERS THEN
4156 IF (l_debug = 1) THEN
4157 print_debug('Error while calling label printing API');
4158 END IF;
4159 FND_MESSAGE.SET_NAME('INV', 'INV_RCV_CRT_PRINT_LABEL_FAILE');
4160 FND_MSG_PUB.ADD;
4161 END;
4162 IF (l_debug = 1) THEN
4163 print_debug('After calling label printing API: ' || l_return_status || ', ' || l_label_status || ', ' || l_msg_data);
4164 END IF;
4165
4166 IF (l_return_status <> FND_API.G_RET_STS_SUCCESS) THEN
4167 FND_MESSAGE.SET_NAME('INV', 'INV_RCV_CRT_PRINT_LABEL_FAILE');
4168 FND_MSG_PUB.ADD;
4169 END IF;*/
4170 ELSE
4171 FND_MESSAGE.SET_NAME ( 'INV', 'INV_BACKGROUND_PENDING' );
4172 FND_MSG_PUB.ADD;
4173 END IF;
4174 END IF;
4175
4176 IF ( l_debug = 1 ) THEN
4177 print_debug ( 'Resetting the global values here after calling post_commit'
4178 );
4179 END IF;
4180
4181 -- Reset the global variables
4182 g_update_flag := 2;
4183 g_insert_flag := 2;
4184 g_commit_status_flag := 2;
4185 g_txn_header_id := NULL;
4186 /* Bug 4495880 -Resetting the global paramter to FALSE*/
4187 g_condition := FALSE;
4188 /* End of fix for Bug 4495880 */
4189
4190 END post_commit;
4191
4192 PROCEDURE system_quantity (
4193 x_system_quantity OUT NOCOPY NUMBER
4194 )
4195 IS
4196 /*
4197 l_conversion_qty NUMBER := 0;
4198 l_primary_sys_qty NUMBER := 0;
4199 l_loaded_sys_qty NUMBER := 0; -- bug 2640378
4200 l_item_id NUMBER := g_cc_entry.inventory_item_id;
4201 l_to_uom VARCHAR2 ( 3 ) := g_count_uom;
4202 l_from_uom VARCHAR2 ( 3 );
4203 l_org_id NUMBER := g_cc_entry.organization_id;
4204 l_sub VARCHAR2 ( 10 ) := g_cc_entry.subinventory;
4205 l_lot VARCHAR2 ( 30 ) := g_cc_entry.lot_number;
4206 l_rev VARCHAR2 ( 10 ) := g_cc_entry.revision;
4207 l_loc NUMBER := g_cc_entry.locator_id;
4208 l_cost_group_id NUMBER := g_cc_entry.cost_group_id;
4209 l_last_updated_by NUMBER := g_cc_entry.last_updated_by;
4210 l_last_update_login NUMBER := g_cc_entry.last_update_login;
4211 l_cycle_count_entry_id NUMBER := g_cc_entry.cycle_count_entry_id;
4212 l_lpn_id NUMBER := g_cc_entry.parent_lpn_id;
4213 l_current_sys_qty NUMBER := 0;
4214 l_serial_number VARCHAR2 ( 30 ) := g_cc_entry.serial_number;
4215 x_error_code NUMBER := 0;
4216 x_return_status VARCHAR2 ( 1 );
4217 x_init_msg_lst VARCHAR2 ( 1 );
4218 x_commit VARCHAR2 ( 1 );
4219 x_msg_count NUMBER := 0;
4220 x_msg_data VARCHAR2 ( 240 );
4221 l_serial_number_control_code NUMBER;
4222 l_serial_count_option NUMBER;
4223 l_debug NUMBER := NVL ( FND_PROFILE.VALUE ( 'INV_DEBUG_TRACE' ), 0 );
4224 -- Bug 4886188 -Added the local variables for the lpn details from wlpn
4225
4226 l_lpn_subinv VARCHAR2(10) ;
4227 l_lpn_locator_id NUMBER ;
4228 l_lpn_context NUMBER;
4229
4230 -- End of fix for Bug 4886188
4231 */
4232 x_sec_system_quantity NUMBER; -- nsinghi bug#6052831
4233 BEGIN
4234 -- nsinghi bug#6052831 START. Call the overriden method.
4235 system_quantity ( x_system_quantity => x_system_quantity
4236 , x_sec_system_quantity => x_sec_system_quantity ); -- nsinghi Bug#6052831. Call overloaded API.
4237 /*
4238 IF ( l_debug = 1 ) THEN
4239 print_debug ( '***system_quantity***' );
4240 END IF;
4241
4242
4243
4244 ****** Fix for bug 4886188
4245 ****** If the Lpn Context is 'Issued Out of Stores' or 'Intransit' or 'Packing Context' or 'Loaded to Dock'
4246 ****** system quantity should be shown as 0. Because, ideally the LPN will not be present in that location.
4247
4248
4249 IF ( l_lpn_id IS NOT NULL ) THEN
4250
4251 SELECT NVL ( subinventory_code, '###' ),
4252 NVL ( locator_id, -99 ),
4253 lpn_context
4254 INTO l_lpn_subinv,
4255 l_lpn_locator_id,
4256 l_lpn_context
4257 FROM WMS_LICENSE_PLATE_NUMBERS
4258 WHERE lpn_id = l_lpn_id ;
4259
4260 IF ( l_debug = 1 ) THEN
4261 print_debug ( 'l_lpn_subinv: ===> ' || l_lpn_subinv );
4262 print_debug ( 'l_lpn_locator_id: => ' || l_lpn_locator_id );
4263 print_debug ( 'l_lpn_context: => ' || l_lpn_context );
4264 END IF;
4265
4266 IF l_lpn_context = 8 or l_lpn_context = 9 or l_lpn_context = 4 or l_lpn_context = 6 THEN
4267 IF ( l_debug = 1 ) THEN
4268 print_debug ( 'Returning the system quantity as 0' );
4269 END IF;
4270 x_system_quantity := 0;
4271 g_condition:=TRUE ;
4272 return;
4273 END IF;
4274 END IF;
4275 -- End of fix for bug number 4886188
4276
4277
4278
4279
4280
4281 -- Get the required variable values from the fields
4282 SELECT primary_uom_code,
4283 serial_number_control_code
4284 INTO l_from_uom,
4285 l_serial_number_control_code
4286 FROM mtl_system_items
4287 WHERE inventory_item_id = g_cc_entry.inventory_item_id
4288 AND organization_id = g_cc_entry.organization_id;
4289
4290 SELECT NVL ( serial_count_option, 1 )
4291 INTO l_serial_count_option
4292 FROM mtl_cycle_count_headers
4293 WHERE cycle_count_header_id = g_cc_entry.cycle_count_header_id
4294 AND organization_id = g_cc_entry.organization_id;
4295
4296 IF ( l_debug = 1 ) THEN
4297 print_debug ( 'Serial count option: ' || l_serial_count_option );
4298 END IF;
4299
4300 IF ( l_serial_number_control_code IN ( 1, 6 )
4301 OR l_serial_count_option = 1
4302 ) THEN
4303 IF ( l_debug = 1 ) THEN
4304 print_debug ( 'Non serial controlled item' );
4305 END IF;
4306
4307 IF l_lpn_id IS NULL THEN
4308 IF ( l_debug = 1 ) THEN
4309 print_debug ( 'LPN ID is null' );
4310 END IF;
4311
4312 IF wms_is_installed ( l_org_id ) THEN
4313 IF ( l_debug = 1 ) THEN
4314 print_debug ( 'WMS is installed' );
4315 END IF;
4316
4317 SELECT NVL ( SUM ( primary_transaction_quantity ), 0 )
4318 INTO l_primary_sys_qty
4319 FROM MTL_ONHAND_QUANTITIES_DETAIL
4320 WHERE inventory_item_id = l_item_id
4321 AND organization_id = l_org_id
4322 AND NVL ( containerized_flag, 2 ) = 2
4323 AND subinventory_code = l_sub
4324 AND NVL ( lot_number, 'XX' ) = NVL ( l_lot, 'XX' )
4325 AND NVL ( revision, 'XXX' ) = NVL ( l_rev, 'XXX' )
4326 AND NVL ( locator_id, -2 ) = NVL ( l_loc, -2 )
4327 AND NVL ( cost_group_id, -9 ) = NVL ( l_cost_group_id, -9 );
4328
4329 SELECT NVL ( SUM ( quantity ), 0 )
4330 INTO l_loaded_sys_qty
4331 FROM WMS_LOADED_QUANTITIES_V
4332 WHERE inventory_item_id = l_item_id
4333 AND organization_id = l_org_id
4334 AND NVL ( containerized_flag, 2 ) = 2
4335 AND subinventory_code = l_sub
4336 AND NVL ( lot_number, 'XX' ) = NVL ( l_lot, 'XX' )
4337 AND NVL ( revision, 'XXX' ) = NVL ( l_rev, 'XXX' )
4338 AND NVL ( locator_id, -2 ) = NVL ( l_loc, -2 )
4339 --Bug# 3071372
4340 --AND NVL ( cost_group_id, -9 ) = NVL ( l_cost_group_id, -9 )
4341 AND qty_type = 'LOADED'
4342 AND lpn_id IS NULL
4343 AND content_lpn_id IS NULL; -- bug 2640378
4344 -- need lpn_id and content lpn id is null because there could be a
4345 -- row in wms_loaded_quantities_v which has these fields populated for the
4346 -- same items/sub.. combination and here we are processing loose
4347
4348 IF ( l_debug = 1 ) THEN
4349 print_debug ( 'Loaded qty is ' || l_loaded_sys_qty );
4350 END IF;
4351
4352 IF l_loaded_sys_qty > 0 THEN
4353 l_primary_sys_qty := l_primary_sys_qty - l_loaded_sys_qty;
4354 END IF; -- bug 2640378
4355 ELSE
4356 IF ( l_debug = 1 ) THEN
4357 print_debug ( 'WMS is not installed' );
4358 END IF;
4359
4360 SELECT NVL ( SUM ( primary_transaction_quantity ), 0 )
4361 INTO l_primary_sys_qty
4362 FROM MTL_ONHAND_QUANTITIES_DETAIL
4363 WHERE inventory_item_id = l_item_id
4364 AND organization_id = l_org_id
4365 AND NVL ( containerized_flag, 2 ) = 2
4366 AND subinventory_code = l_sub
4367 AND NVL ( lot_number, 'XX' ) = NVL ( l_lot, 'XX' )
4368 AND NVL ( revision, 'XXX' ) = NVL ( l_rev, 'XXX' )
4369 AND NVL ( locator_id, -2 ) = NVL ( l_loc, -2 );
4370 END IF;
4371 ELSE
4372 IF ( l_debug = 1 ) THEN
4373 print_debug ( 'LPN ID is not null' || l_lpn_id );
4374 END IF;
4375
4376 MTL_INV_UTIL_GRP.Get_LPN_Item_SysQty ( p_api_version => 0.9,
4377 p_init_msg_lst => NULL,
4378 p_commit => NULL,
4379 x_return_status => x_return_status,
4380 x_msg_count => x_msg_count,
4381 x_msg_data => x_msg_data,
4382 p_organization_id => l_org_id,
4383 p_lpn_id => l_lpn_id,
4384 p_inventory_item_id => l_item_id,
4385 p_lot_number => l_lot,
4386 p_revision => l_rev,
4387 p_serial_number => l_serial_number,
4388 p_cost_group_id => l_cost_group_id,
4389 x_lpn_systemqty => l_primary_sys_qty
4390 );
4391 END IF;
4392 ELSIF ( l_serial_number_control_code IN ( 2, 5 )
4393 AND l_serial_count_option > 1
4394 ) THEN
4395 IF ( l_debug = 1 ) THEN
4396 print_debug ( 'Serial controlled item' );
4397 END IF;
4398
4399 IF ( l_lpn_id IS NULL ) THEN
4400 IF ( l_debug = 1 ) THEN
4401 print_debug ( 'No LPN ID' );
4402 END IF;
4403
4404 -- Bug# 2386909
4405 -- Also make sure you query only serials which are loose
4406 SELECT NVL ( SUM ( DECODE ( msn.current_status, 3, 1, 0 ) ), 0 )
4407 INTO l_primary_sys_qty
4408 FROM mtl_serial_numbers msn
4409 WHERE msn.serial_number = NVL ( l_serial_number, serial_number )
4410 AND msn.inventory_item_id = l_item_id
4411 AND msn.current_organization_id = l_org_id
4412 AND msn.current_subinventory_code = l_sub
4413 AND NVL ( msn.lot_number, 'XX' ) = NVL ( l_lot, 'XX' )
4414 AND NVL ( msn.revision, 'XXX' ) = NVL ( l_rev, 'XXX' )
4415 AND NVL ( msn.current_locator_id, -2 ) = NVL ( l_loc, -2 )
4416 AND msn.lpn_id IS NULL
4417 AND is_serial_loaded ( l_org_id,
4418 l_item_id,
4419 NVL ( l_serial_number, serial_number ),
4420 NULL
4421 ) = 2;
4422 -- bug 2640378
4423 ELSE
4424 IF ( l_debug = 1 ) THEN
4425 print_debug ( 'LPN ID' || l_lpn_id );
4426 END IF;
4427
4428 MTL_INV_UTIL_GRP.Get_LPN_Item_SysQty ( p_api_version => 0.9,
4429 p_init_msg_lst => NULL,
4430 p_commit => NULL,
4431 x_return_status => x_return_status,
4432 x_msg_count => x_msg_count,
4433 x_msg_data => x_msg_data,
4434 p_organization_id => l_org_id,
4435 p_lpn_id => l_lpn_id,
4436 p_inventory_item_id => l_item_id,
4437 p_lot_number => l_lot,
4438 p_revision => l_rev,
4439 p_serial_number => l_serial_number,
4440 p_cost_group_id => l_cost_group_id,
4441 x_lpn_systemqty => l_primary_sys_qty
4442 );
4443 END IF;
4444
4445 IF ( l_serial_count_option = 3 ) THEN
4446 IF ( l_cycle_count_entry_id IS NULL ) THEN
4447 SELECT mtl_cycle_count_entries_s.NEXTVAL
4448 INTO l_cycle_count_entry_id
4449 FROM DUAL;
4450
4451 g_cc_entry.cycle_count_entry_id := l_cycle_count_entry_id;
4452 END IF;
4453
4454 -- Every time you calculate system quantity make sure that we update
4455 -- MTL_CC_SERIAL_NUMBERS table. So that change in system quantity is reflected
4456 -- in SERIAL_NUMBERS also
4457 -- Bug# 2386909
4458 -- Match against the LPN ID also when performing this insert statement
4459 INSERT INTO MTL_CC_SERIAL_NUMBERS
4460 ( CYCLE_COUNT_ENTRY_ID,
4461 SERIAL_NUMBER,
4462 LAST_UPDATE_DATE,
4463 LAST_UPDATED_BY,
4464 CREATION_DATE,
4465 CREATED_BY,
4466 LAST_UPDATE_LOGIN
4467 )
4468 SELECT l_cycle_count_entry_id,
4469 SERIAL_NUMBER,
4470 SYSDATE,
4471 l_last_updated_by,
4472 SYSDATE,
4473 l_last_updated_by,
4474 l_last_update_login
4475 FROM mtl_serial_numbers msn
4476 WHERE msn.inventory_item_id = l_item_id
4477 AND msn.current_organization_id = l_org_id
4478 AND msn.current_subinventory_code = l_sub
4479 AND NVL ( msn.lot_number, 'XX' ) = NVL ( l_lot, 'XX' )
4480 AND NVL ( msn.revision, 'XXX' ) = NVL ( l_rev, 'XXX' )
4481 AND NVL ( msn.current_locator_id, -2 ) = NVL ( l_loc, -2 )
4482 AND msn.current_status = 3
4483 AND NVL ( msn.lpn_id, -99999 ) = NVL ( l_lpn_id, -99999 )
4484 AND NOT EXISTS (
4485 SELECT 'x'
4486 FROM MTL_CC_SERIAL_NUMBERS
4487 WHERE CYCLE_COUNT_ENTRY_ID = l_cycle_count_entry_id
4488 AND SERIAL_NUMBER = msn.SERIAL_NUMBER );
4489 END IF;
4490 END IF;
4491
4492 IF ( l_primary_sys_qty IS NULL ) THEN
4493 l_primary_sys_qty := 0;
4494 END IF;
4495
4496 IF (( l_serial_count_option <> 3) OR
4497 ( l_serial_count_option = 3 AND l_serial_number_control_code IN (1, 6) ) )
4498 THEN
4499 l_conversion_qty :=
4500 inv_convert.inv_um_convert ( l_item_id,
4501 5,
4502 l_primary_sys_qty,
4503 l_from_uom,
4504 l_to_uom,
4505 NULL,
4506 NULL
4507 );
4508 ELSE
4509 -- Don't need to convert the quantity for multiple
4510 -- serial count option since the serials will be counted
4511 -- in the item's primary UOM code
4512 l_conversion_qty := l_primary_sys_qty;
4513 END IF;
4514
4515 -- Set the output variable equal to the final converted system quantity
4516 x_system_quantity := l_conversion_qty;
4517
4518 IF ( l_debug = 1 ) THEN
4519 print_debug ( 'Quantity returned: ' || x_system_quantity );
4520 END IF;
4521 */
4522 END system_quantity;
4523
4524 -- nsinghi bug#6052831. Created overloaded procedure to handle secondary qty.
4525 PROCEDURE system_quantity (
4526 x_system_quantity OUT NOCOPY NUMBER
4527 , x_sec_system_quantity OUT NOCOPY NUMBER
4528 )
4529 IS
4530 l_conversion_qty NUMBER := 0;
4531 l_primary_sys_qty NUMBER := 0;
4532 l_secondary_sys_qty NUMBER := 0; -- nsinghi bug#6052831
4533 l_loaded_sec_sys_qty NUMBER := 0; -- nsinghi bug#6052831
4534 l_loaded_sys_qty NUMBER := 0; -- bug 2640378
4535 l_item_id NUMBER := g_cc_entry.inventory_item_id;
4536 l_to_uom VARCHAR2 ( 3 ) := g_count_uom;
4537 l_from_uom VARCHAR2 ( 3 );
4538 l_org_id NUMBER := g_cc_entry.organization_id;
4539 l_sub VARCHAR2 ( 10 ) := g_cc_entry.subinventory;
4540 l_lot VARCHAR2 ( 30 ) := g_cc_entry.lot_number;
4541 l_rev VARCHAR2 ( 10 ) := g_cc_entry.revision;
4542 l_loc NUMBER := g_cc_entry.locator_id;
4543 l_cost_group_id NUMBER := g_cc_entry.cost_group_id;
4544 l_last_updated_by NUMBER := g_cc_entry.last_updated_by;
4545 l_last_update_login NUMBER := g_cc_entry.last_update_login;
4546 l_cycle_count_entry_id NUMBER := g_cc_entry.cycle_count_entry_id;
4547 l_lpn_id NUMBER := g_cc_entry.parent_lpn_id;
4548 l_current_sys_qty NUMBER := 0;
4549 l_serial_number VARCHAR2 ( 30 ) := g_cc_entry.serial_number;
4550 x_error_code NUMBER := 0;
4551 x_return_status VARCHAR2 ( 1 );
4552 x_init_msg_lst VARCHAR2 ( 1 );
4553 x_commit VARCHAR2 ( 1 );
4554 x_msg_count NUMBER := 0;
4555 x_msg_data VARCHAR2 ( 240 );
4556 l_serial_number_control_code NUMBER;
4557 l_serial_count_option NUMBER;
4558 l_debug NUMBER := NVL ( FND_PROFILE.VALUE ( 'INV_DEBUG_TRACE' ), 0 );
4559 /* Bug 4886188 -Added the local variables for the lpn details from wlpn*/
4560
4561 l_lpn_subinv VARCHAR2(10) ;
4562 l_lpn_locator_id NUMBER ;
4563 l_lpn_context NUMBER;
4564
4565 /* End of fix for Bug 4886188 */
4566 BEGIN
4567 IF ( l_debug = 1 ) THEN
4568 print_debug ( '***system_quantity***' );
4569 END IF;
4570
4571
4572 /*
4573 ****** Fix for bug 4886188
4574 ****** If the Lpn Context is 'Issued Out of Stores' or 'Intransit' or 'Packing Context' or 'Loaded to Dock'
4575 ****** system quantity should be shown as 0. Because, ideally the LPN will not be present in that location.
4576 */
4577
4578 IF ( l_lpn_id IS NOT NULL ) THEN
4579
4580 SELECT NVL ( subinventory_code, '###' ),
4581 NVL ( locator_id, -99 ),
4582 lpn_context
4583 INTO l_lpn_subinv,
4584 l_lpn_locator_id,
4585 l_lpn_context
4586 FROM WMS_LICENSE_PLATE_NUMBERS
4587 WHERE lpn_id = l_lpn_id ;
4588
4589 IF ( l_debug = 1 ) THEN
4590 print_debug ( 'l_lpn_subinv: ===> ' || l_lpn_subinv );
4591 print_debug ( 'l_lpn_locator_id: => ' || l_lpn_locator_id );
4592 print_debug ( 'l_lpn_context: => ' || l_lpn_context );
4593 END IF;
4594
4595 IF l_lpn_context = 8 or l_lpn_context = 9 or l_lpn_context = 4 or l_lpn_context = 6 THEN
4596 IF ( l_debug = 1 ) THEN
4597 print_debug ( 'Returning the system quantity as 0' );
4598 END IF;
4599 x_system_quantity := 0;
4600 g_condition:=TRUE ;
4601 return;
4602 END IF;
4603 END IF;
4604 /* End of fix for bug number 4886188 */
4605
4606
4607
4608
4609
4610 -- Get the required variable values from the fields
4611 SELECT primary_uom_code,
4612 serial_number_control_code
4613 INTO l_from_uom,
4614 l_serial_number_control_code
4615 FROM mtl_system_items
4616 WHERE inventory_item_id = g_cc_entry.inventory_item_id
4617 AND organization_id = g_cc_entry.organization_id;
4618
4619 SELECT NVL ( serial_count_option, 1 )
4620 INTO l_serial_count_option
4621 FROM mtl_cycle_count_headers
4622 WHERE cycle_count_header_id = g_cc_entry.cycle_count_header_id
4623 AND organization_id = g_cc_entry.organization_id;
4624
4625 IF ( l_debug = 1 ) THEN
4626 print_debug ( 'Serial count option: ' || l_serial_count_option );
4627 END IF;
4628
4629 IF ( l_serial_number_control_code IN ( 1, 6 )
4630 OR l_serial_count_option = 1
4631 ) THEN
4632 IF ( l_debug = 1 ) THEN
4633 print_debug ( 'Non serial controlled item' );
4634 END IF;
4635
4636 IF l_lpn_id IS NULL THEN
4637 IF ( l_debug = 1 ) THEN
4638 print_debug ( 'LPN ID is null' );
4639 END IF;
4640
4641 IF wms_is_installed ( l_org_id ) THEN
4642 IF ( l_debug = 1 ) THEN
4643 print_debug ( 'WMS is installed' );
4644 END IF;
4645
4646 SELECT NVL ( SUM ( primary_transaction_quantity ), 0 )
4647 , NVL ( SUM ( secondary_transaction_quantity ), 0 ) -- nsinghi bug#6052831
4648 INTO l_primary_sys_qty
4649 , l_secondary_sys_qty -- nsinghi bug#6052831
4650 FROM MTL_ONHAND_QUANTITIES_DETAIL
4651 WHERE inventory_item_id = l_item_id
4652 AND organization_id = l_org_id
4653 AND NVL ( containerized_flag, 2 ) = 2
4654 AND subinventory_code = l_sub
4655 AND NVL ( lot_number, 'XX' ) = NVL ( l_lot, 'XX' )
4656 AND NVL ( revision, 'XXX' ) = NVL ( l_rev, 'XXX' )
4657 AND NVL ( locator_id, -2 ) = NVL ( l_loc, -2 )
4658 AND NVL ( cost_group_id, -9 ) = NVL ( l_cost_group_id, -9 );
4659
4660 SELECT NVL ( SUM ( quantity ), 0 )
4661 , NVL ( SUM ( secondary_quantity ), 0 ) -- nsinghi bug#6052831
4662 INTO l_loaded_sys_qty
4663 , l_loaded_sec_sys_qty -- nsinghi bug#6052831
4664 FROM WMS_LOADED_QUANTITIES_V
4665 WHERE inventory_item_id = l_item_id
4666 AND organization_id = l_org_id
4667 AND NVL ( containerized_flag, 2 ) = 2
4668 AND subinventory_code = l_sub
4669 AND NVL ( lot_number, 'XX' ) = NVL ( l_lot, 'XX' )
4670 AND NVL ( revision, 'XXX' ) = NVL ( l_rev, 'XXX' )
4671 AND NVL ( locator_id, -2 ) = NVL ( l_loc, -2 )
4672 --Bug# 3071372
4673 --AND NVL ( cost_group_id, -9 ) = NVL ( l_cost_group_id, -9 )
4674 AND qty_type = 'LOADED'
4675 AND lpn_id IS NULL
4676 AND content_lpn_id IS NULL; -- bug 2640378
4677 -- need lpn_id and content lpn id is null because there could be a
4678 -- row in wms_loaded_quantities_v which has these fields populated for the
4679 -- same items/sub.. combination and here we are processing loose
4680
4681 IF ( l_debug = 1 ) THEN
4682 print_debug ( 'Loaded qty is ' || l_loaded_sys_qty );
4683 END IF;
4684
4685 IF l_loaded_sys_qty > 0 THEN
4686 l_primary_sys_qty := l_primary_sys_qty - l_loaded_sys_qty;
4687 END IF; -- bug 2640378
4688 ELSE
4689 IF ( l_debug = 1 ) THEN
4690 print_debug ( 'WMS is not installed' );
4691 END IF;
4692
4693 SELECT NVL ( SUM ( primary_transaction_quantity ), 0 )
4694 , NVL ( SUM ( secondary_transaction_quantity ), 0 ) -- nsinghi bug#6052831
4695 INTO l_primary_sys_qty
4696 , l_secondary_sys_qty -- nsinghi bug#6052831
4697 FROM MTL_ONHAND_QUANTITIES_DETAIL
4698 WHERE inventory_item_id = l_item_id
4699 AND organization_id = l_org_id
4700 AND NVL ( containerized_flag, 2 ) = 2
4701 AND subinventory_code = l_sub
4702 AND NVL ( lot_number, 'XX' ) = NVL ( l_lot, 'XX' )
4703 AND NVL ( revision, 'XXX' ) = NVL ( l_rev, 'XXX' )
4704 AND NVL ( locator_id, -2 ) = NVL ( l_loc, -2 );
4705 END IF;
4706 ELSE
4707 IF ( l_debug = 1 ) THEN
4708 print_debug ( 'LPN ID is not null' || l_lpn_id );
4709 END IF;
4710
4711 MTL_INV_UTIL_GRP.Get_LPN_Item_SysQty ( p_api_version => 0.9,
4712 p_init_msg_lst => NULL,
4713 p_commit => NULL,
4714 x_return_status => x_return_status,
4715 x_msg_count => x_msg_count,
4716 x_msg_data => x_msg_data,
4717 p_organization_id => l_org_id,
4718 p_lpn_id => l_lpn_id,
4719 p_inventory_item_id => l_item_id,
4720 p_lot_number => l_lot,
4721 p_revision => l_rev,
4722 p_serial_number => l_serial_number,
4723 p_cost_group_id => l_cost_group_id,
4724 x_lpn_systemqty => l_primary_sys_qty,
4725 x_lpn_sec_systemqty => l_secondary_sys_qty -- nsinghi bug#6052831
4726 );
4727 END IF;
4728 ELSIF ( l_serial_number_control_code IN ( 2, 5 )
4729 AND l_serial_count_option > 1
4730 ) THEN
4731 IF ( l_debug = 1 ) THEN
4732 print_debug ( 'Serial controlled item' );
4733 END IF;
4734
4735 IF ( l_lpn_id IS NULL ) THEN
4736 IF ( l_debug = 1 ) THEN
4737 print_debug ( 'No LPN ID' );
4738 END IF;
4739
4740 -- Bug# 2386909
4741 -- Also make sure you query only serials which are loose
4742 SELECT NVL ( SUM ( DECODE ( msn.current_status, 3, 1, 0 ) ), 0 )
4743 INTO l_primary_sys_qty
4744 FROM mtl_serial_numbers msn
4745 WHERE msn.serial_number = NVL ( l_serial_number, serial_number )
4746 AND msn.inventory_item_id = l_item_id
4747 AND msn.current_organization_id = l_org_id
4748 AND msn.current_subinventory_code = l_sub
4749 AND NVL ( msn.lot_number, 'XX' ) = NVL ( l_lot, 'XX' )
4750 AND NVL ( msn.revision, 'XXX' ) = NVL ( l_rev, 'XXX' )
4751 AND NVL ( msn.current_locator_id, -2 ) = NVL ( l_loc, -2 )
4752 AND msn.lpn_id IS NULL
4753 AND is_serial_loaded ( l_org_id,
4754 l_item_id,
4755 NVL ( l_serial_number, serial_number ),
4756 NULL
4757 ) = 2;
4758 -- bug 2640378
4759 ELSE
4760 IF ( l_debug = 1 ) THEN
4761 print_debug ( 'LPN ID' || l_lpn_id );
4762 END IF;
4763
4764 MTL_INV_UTIL_GRP.Get_LPN_Item_SysQty ( p_api_version => 0.9,
4765 p_init_msg_lst => NULL,
4766 p_commit => NULL,
4767 x_return_status => x_return_status,
4768 x_msg_count => x_msg_count,
4769 x_msg_data => x_msg_data,
4770 p_organization_id => l_org_id,
4771 p_lpn_id => l_lpn_id,
4772 p_inventory_item_id => l_item_id,
4773 p_lot_number => l_lot,
4774 p_revision => l_rev,
4775 p_serial_number => l_serial_number,
4776 p_cost_group_id => l_cost_group_id,
4777 x_lpn_systemqty => l_primary_sys_qty
4778 );
4779 END IF;
4780
4781 IF ( l_serial_count_option = 3 ) THEN
4782 IF ( l_cycle_count_entry_id IS NULL ) THEN
4783 SELECT mtl_cycle_count_entries_s.NEXTVAL
4784 INTO l_cycle_count_entry_id
4785 FROM DUAL;
4786
4787 g_cc_entry.cycle_count_entry_id := l_cycle_count_entry_id;
4788 END IF;
4789
4790 -- Every time you calculate system quantity make sure that we update
4791 -- MTL_CC_SERIAL_NUMBERS table. So that change in system quantity is reflected
4792 -- in SERIAL_NUMBERS also
4793 -- Bug# 2386909
4794 -- Match against the LPN ID also when performing this insert statement
4795 INSERT INTO MTL_CC_SERIAL_NUMBERS
4796 ( CYCLE_COUNT_ENTRY_ID,
4797 SERIAL_NUMBER,
4798 LAST_UPDATE_DATE,
4799 LAST_UPDATED_BY,
4800 CREATION_DATE,
4801 CREATED_BY,
4802 LAST_UPDATE_LOGIN
4803 )
4804 SELECT l_cycle_count_entry_id,
4805 SERIAL_NUMBER,
4806 SYSDATE,
4807 l_last_updated_by,
4808 SYSDATE,
4809 l_last_updated_by,
4810 l_last_update_login
4811 FROM mtl_serial_numbers msn
4812 WHERE msn.inventory_item_id = l_item_id
4813 AND msn.current_organization_id = l_org_id
4814 AND msn.current_subinventory_code = l_sub
4815 AND NVL ( msn.lot_number, 'XX' ) = NVL ( l_lot, 'XX' )
4816 AND NVL ( msn.revision, 'XXX' ) = NVL ( l_rev, 'XXX' )
4817 AND NVL ( msn.current_locator_id, -2 ) = NVL ( l_loc, -2 )
4818 AND msn.current_status = 3
4819 AND NVL ( msn.lpn_id, -99999 ) = NVL ( l_lpn_id, -99999 )
4820 AND NOT EXISTS (
4821 SELECT 'x'
4822 FROM MTL_CC_SERIAL_NUMBERS
4823 WHERE CYCLE_COUNT_ENTRY_ID = l_cycle_count_entry_id
4824 AND SERIAL_NUMBER = msn.SERIAL_NUMBER );
4825 END IF;
4826 END IF;
4827
4828 IF ( l_primary_sys_qty IS NULL ) THEN
4829 l_primary_sys_qty := 0;
4830 END IF;
4831 -- nsinghi bug#6052831 START
4832 IF ( l_secondary_sys_qty IS NULL ) THEN
4833 l_secondary_sys_qty := 0;
4834 END IF;
4835 -- nsinghi bug#6052831 END
4836
4837 IF (( l_serial_count_option <> 3) OR
4838 ( l_serial_count_option = 3 AND l_serial_number_control_code IN (1, 6) ) )
4839 THEN
4840 l_conversion_qty :=
4841 inv_convert.inv_um_convert ( l_item_id,
4842 5,
4843 l_primary_sys_qty,
4844 l_from_uom,
4845 l_to_uom,
4846 NULL,
4847 NULL
4848 );
4849 ELSE
4850 -- Don't need to convert the quantity for multiple
4851 -- serial count option since the serials will be counted
4852 -- in the item's primary UOM code
4853 l_conversion_qty := l_primary_sys_qty;
4854 END IF;
4855
4856 -- Set the output variable equal to the final converted system quantity
4857 x_system_quantity := l_conversion_qty;
4858 x_sec_system_quantity := l_secondary_sys_qty; -- nsinghi bug#6052831
4859
4860 IF ( l_debug = 1 ) THEN
4861 print_debug ( 'Quantity returned: ' || x_system_quantity );
4862 print_debug ( 'Secondary Quantity returned: ' || x_sec_system_quantity );
4863 END IF;
4864 END system_quantity;
4865
4866 PROCEDURE value_variance (
4867 x_value_variance OUT NOCOPY NUMBER
4868 )
4869 IS
4870 l_count_qty NUMBER := g_count_quantity;
4871 l_system_qty NUMBER;
4872 l_item_cost NUMBER;
4873 l_item_id NUMBER := g_cc_entry.inventory_item_id;
4874 l_value_variance NUMBER;
4875 l_conversion_qty NUMBER;
4876 l_from_uom VARCHAR2 ( 3 ) := g_count_uom;
4877 l_to_uom VARCHAR2 ( 3 );
4878 l_adj_qty NUMBER;
4879 l_debug NUMBER := NVL ( FND_PROFILE.VALUE ( 'INV_DEBUG_TRACE' ), 0 );
4880 BEGIN
4881 IF ( l_debug = 1 ) THEN
4882 print_debug ( '***value_variance***' );
4883 END IF;
4884
4885 -- Get the item system quantity
4886 system_quantity ( x_system_quantity => l_system_qty );
4887 -- Get the item cost
4888 l_item_cost :=
4889 get_item_cost ( in_org_id => g_cc_entry.organization_id,
4890 in_item_id => g_cc_entry.inventory_item_id,
4891 in_locator_id => g_cc_entry.locator_id
4892 );
4893 g_cc_entry.item_unit_cost := l_item_cost;
4894
4895 -- Get the item primary uom code
4896 SELECT primary_uom_code
4897 INTO l_to_uom
4898 FROM MTL_SYSTEM_ITEMS
4899 WHERE inventory_item_id = g_cc_entry.inventory_item_id
4900 AND organization_id = g_cc_entry.organization_id;
4901
4902 -- Convert the system quantity into the count uom
4903 /*2977288l_system_qty :=
4904 inv_convert.inv_um_convert ( g_cc_entry.inventory_item_id,
4905 6,
4906 l_system_qty,
4907 l_to_uom,
4908 g_count_uom,
4909 NULL,
4910 NULL
4911 );*/
4912 -- Calculate the adjusted quantity
4913 l_adj_qty := l_count_qty - l_system_qty;
4914 -- Calculate the conversion quantity
4915 l_conversion_qty :=
4916 inv_convert.inv_um_convert ( l_item_id,
4917 5,
4918 l_adj_qty,
4919 l_from_uom,
4920 l_to_uom,
4921 NULL,
4922 NULL
4923 );
4924 l_value_variance := l_conversion_qty * l_item_cost;
4925 -- Set the OUT parameters
4926 x_value_variance := l_value_variance;
4927 END value_variance;
4928
4929 FUNCTION wms_is_installed (
4930 p_organization_id IN NUMBER
4931 )
4932 RETURN BOOLEAN
4933 IS
4934 x_return_status VARCHAR2 ( 1 );
4935 x_msg_count NUMBER;
4936 x_msg_data VARCHAR2 ( 240 );
4937 l_debug NUMBER := NVL ( FND_PROFILE.VALUE ( 'INV_DEBUG_TRACE' ), 0 );
4938 BEGIN
4939 IF ( l_debug = 1 ) THEN
4940 print_debug ( '***wms_is_installed***' );
4941 END IF;
4942
4943 IF WMS_INSTALL.check_install ( x_return_status,
4944 x_msg_count,
4945 x_msg_data,
4946 p_organization_id
4947 ) THEN
4948 RETURN TRUE;
4949 ELSE
4950 RETURN FALSE;
4951 END IF;
4952 END wms_is_installed;
4953
4954 FUNCTION get_item_cost (
4955 in_org_id NUMBER,
4956 in_item_id NUMBER,
4957 in_locator_id NUMBER
4958 )
4959 RETURN NUMBER
4960 IS
4961 l_item_cost NUMBER;
4962 l_locator_id NUMBER := in_locator_id;
4963 l_cost_group_id NUMBER := g_cc_entry.cost_group_id;
4964 l_debug NUMBER := NVL ( FND_PROFILE.VALUE ( 'INV_DEBUG_TRACE' ), 0 );
4965 BEGIN
4966 IF ( l_debug = 1 ) THEN
4967 print_debug ( '***get_item_cost***' );
4968 END IF;
4969
4970 -- We are doing this for dynamic locators
4971 IF ( l_locator_id = -1 ) THEN
4972 l_locator_id := NULL;
4973 END IF;
4974
4975 -- Bug# 2094288
4976 -- For standard costed orgs, get the item cost with the common
4977 -- cost group ID = 1 always. For average costed orgs, use the
4978 -- cost group ID stamped on the transaction
4979 -- Bug # 2180251: All primary costing methods not equal to 1 should
4980 -- also be considered as an average costed org
4981 BEGIN
4982 SELECT NVL ( ccicv.item_cost, 0 )
4983 INTO l_item_cost
4984 FROM cst_cg_item_costs_view ccicv,
4985 mtl_parameters mp
4986 WHERE l_locator_id IS NULL
4987 AND ccicv.organization_id = in_org_id
4988 AND ccicv.inventory_item_id = in_item_id
4989 AND ccicv.organization_id = mp.organization_id
4990 /* Bug 5555367 - Modified the condition
4991 AND ccicv.cost_group_id =
4992 DECODE ( mp.primary_cost_method,
4993 1, 1,
4994 NVL ( l_cost_group_id, 1 )
4995 )
4996 */
4997 AND ccicv.cost_group_id =
4998 DECODE ( mp.primary_cost_method,
4999 1, 1,
5000 NVL ( l_cost_group_id, mp.default_cost_group_id)
5001 )
5002 UNION ALL
5003 SELECT NVL ( ccicv.item_cost, 0 )
5004 FROM mtl_item_locations mil,
5005 cst_cg_item_costs_view ccicv,
5006 mtl_parameters mp
5007 WHERE l_locator_id IS NOT NULL
5008 AND mil.organization_id = in_org_id
5009 AND mil.inventory_location_id = l_locator_id
5010 AND mil.project_id IS NULL
5011 AND ccicv.organization_id = mil.organization_id
5012 AND ccicv.inventory_item_id = in_item_id
5013 AND ccicv.organization_id = mp.organization_id
5014 /* Bug 5555367 - Modified the condition
5015 AND ccicv.cost_group_id =
5016 DECODE ( mp.primary_cost_method,
5017 1, 1,
5018 NVL ( l_cost_group_id, 1 )
5019 )
5020 */
5021 AND ccicv.cost_group_id =
5022 DECODE ( mp.primary_cost_method,
5023 1, 1,
5024 NVL ( l_cost_group_id, mp.default_cost_group_id)
5025 )
5026 UNION ALL
5027 SELECT NVL ( ccicv.item_cost, 0 )
5028 FROM mtl_item_locations mil,
5029 mrp_project_parameters mrp,
5030 cst_cg_item_costs_view ccicv,
5031 mtl_parameters mp
5032 WHERE l_locator_id IS NOT NULL
5033 AND mil.organization_id = in_org_id
5034 AND mil.inventory_location_id = l_locator_id
5035 AND mil.project_id IS NOT NULL
5036 AND mrp.organization_id = mil.organization_id
5037 AND mrp.project_id = mil.project_id
5038 AND ccicv.organization_id = mil.organization_id
5039 AND ccicv.inventory_item_id = in_item_id
5040 AND ccicv.organization_id = mp.organization_id
5041 AND ccicv.cost_group_id =
5042 DECODE ( mp.primary_cost_method,
5043 1, 1,
5044 NVL ( mrp.costing_group_id, 1 )
5045 );
5046 EXCEPTION
5047 WHEN NO_DATA_FOUND THEN
5048 l_item_cost := 0;
5049 END;
5050
5051 RETURN ( l_item_cost );
5052 END GET_ITEM_COST;
5053
5054 -- This function returns 2 IF a serial is not loaded ELSE returns 1
5055 -- Added as part of bug 2640378
5056 FUNCTION IS_SERIAL_LOADED (
5057 p_organization_id IN NUMBER,
5058 p_inventory_item_id IN NUMBER,
5059 p_serial_number IN VARCHAR2,
5060 p_lpn_id IN NUMBER
5061 )
5062 RETURN NUMBER
5063 IS
5064 l_serial_count NUMBER;
5065 l_lot_control_code NUMBER;
5066 l_debug NUMBER := NVL ( FND_PROFILE.VALUE ( 'INV_DEBUG_TRACE' ), 0 );
5067 BEGIN
5068 IF p_organization_id IS NOT NULL
5069 AND p_serial_number IS NOT NULL
5070 AND p_inventory_item_id IS NOT NULL THEN
5071 IF ( l_debug = 1 ) THEN
5072 print_debug ( '******** IS SERIAL LOADED ***********' );
5073 END IF;
5074
5075 /*
5076 IF (l_debug = 1) THEN
5077 print_debug('Item: ===> ' || p_inventory_item_id);
5078 print_debug('Serial: => ' || p_serial_number);
5079 print_debug('Org ID: => ' || p_organization_id);
5080 print_debug('LPN ID: => ' || p_lpn_id);
5081 END IF;
5082 */
5083 IF p_lpn_id IS NULL THEN
5084 SELECT lot_control_code
5085 INTO l_lot_control_code
5086 FROM mtl_system_items
5087 WHERE organization_id = p_organization_id
5088 AND inventory_item_id = p_inventory_item_id;
5089
5090 IF l_lot_control_code = 1 THEN -- no lot control code
5091 -- just check with msnt
5092 SELECT COUNT ( * )
5093 INTO l_serial_count
5094 FROM mtl_serial_numbers_temp s,
5095 wms_loaded_quantities_v wl
5096 WHERE s.transaction_temp_id = wl.transaction_temp_id
5097 AND p_serial_number BETWEEN s.fm_serial_number
5098 AND s.to_serial_number;
5099
5100 IF l_serial_count = 1 THEN
5101 -- print_debug('Non lot controlled serial ' || p_serial_number || ' already loaded ');
5102 RETURN 1;
5103 ELSE
5104 -- print_debug('Non lot controlled serial ' || p_serial_number || ' not loaded ');
5105 RETURN 2;
5106 END IF;
5107 ELSE -- have to join mtlt also
5108 SELECT COUNT ( * )
5109 INTO l_serial_count
5110 FROM mtl_serial_numbers_temp s,
5111 wms_loaded_quantities_v wl,
5112 mtl_transaction_lots_temp l
5113 WHERE wl.transaction_temp_id = l.transaction_temp_id
5114 AND s.transaction_temp_id = l.serial_transaction_temp_id
5115 AND p_serial_number BETWEEN fm_serial_number
5116 AND to_serial_number;
5117
5118 IF l_serial_count >= 1 THEN
5119 -- print_debug('lot controlled serial ' || p_serial_number || ' already loaded ');
5120 RETURN 1;
5121 ELSE
5122 -- print_debug('lot controlled serial ' || p_serial_number || ' not loaded ');
5123 RETURN 2;
5124 END IF;
5125 END IF; -- lot control code
5126 ELSE -- lpn is not null
5127 SELECT COUNT ( * )
5128 INTO l_serial_count
5129 FROM mtl_serial_numbers s,
5130 wms_loaded_quantities_v wl
5131 WHERE s.lpn_id = p_lpn_id
5132 AND NVL ( wl.content_lpn_id, NVL ( wl.lpn_id, -1 ) ) = s.lpn_id
5133 AND s.serial_number = p_serial_number
5134 AND s.current_organization_id = p_organization_id
5135 AND s.inventory_item_id = p_inventory_item_id;
5136
5137 IF l_serial_count > 0 THEN -- serial is loaded
5138 RETURN 1;
5139 ELSE
5140 RETURN 2;
5141 END IF;
5142 END IF; -- lpn id not/null
5143 ELSE -- org or serial or item is null
5144 RETURN 2;
5145 END IF;
5146 EXCEPTION
5147 WHEN OTHERS THEN
5148 RETURN 2;
5149 END;
5150
5151 PROCEDURE is_serial_entered (
5152 event IN VARCHAR2,
5153 entered OUT NOCOPY NUMBER
5154 )
5155 IS
5156 l_serial_count_option NUMBER;
5157 l_serial_detail_option NUMBER;
5158 l_serial_detail NUMBER := g_cc_entry.serial_detail;
5159 l_cycle_count_entry_id NUMBER := g_cc_entry.cycle_count_entry_id;
5160 l_number_of_counts NUMBER;
5161 l_counts NUMBER := g_cc_entry.number_of_counts;
5162 l_last_updated_by NUMBER := g_cc_entry.last_updated_by;
5163 l_last_update_login NUMBER := g_cc_entry.last_update_login;
5164 -- for unscheduled entries
5165 l_sub VARCHAR2 ( 10 ) := g_cc_entry.subinventory;
5166 l_lot VARCHAR2 ( 30 ) := g_cc_entry.lot_number;
5167 l_rev VARCHAR2 ( 10 ) := g_cc_entry.revision;
5168 l_loc NUMBER := g_cc_entry.locator_id;
5169 l_item_id NUMBER := g_cc_entry.inventory_item_id;
5170 l_org_id NUMBER := g_cc_entry.organization_id;
5171 l_system_quantity NUMBER;
5172 l_serial_number_control_code NUMBER;
5173 l_debug NUMBER := NVL ( FND_PROFILE.VALUE ( 'INV_DEBUG_TRACE' ), 0 );
5174 BEGIN
5175 IF ( l_debug = 1 ) THEN
5176 print_debug ( '***is_serial_entered***' );
5177 END IF;
5178
5179 -- Get the required values
5180 SELECT NVL ( serial_count_option, 1 ),
5181 NVL ( serial_detail_option, 1 )
5182 INTO l_serial_count_option,
5183 l_serial_detail_option
5184 FROM mtl_cycle_count_headers
5185 WHERE cycle_count_header_id = g_cc_entry.cycle_count_header_id
5186 AND organization_id = g_cc_entry.organization_id;
5187
5188 -- Get the serial number control code
5189 SELECT serial_number_control_code
5190 INTO l_serial_number_control_code
5191 FROM mtl_system_items
5192 WHERE inventory_item_id = g_cc_entry.inventory_item_id
5193 AND organization_id = g_cc_entry.organization_id;
5194
5195 -- Get the item system quantity
5196 system_quantity ( x_system_quantity => l_system_quantity );
5197 entered := 0;
5198
5199 IF ( l_counts IS NULL ) THEN
5200 l_counts := 0;
5201 END IF;
5202
5203 IF ( event = 'WHEN-VALIDATE-RECORD'
5204 OR event = 'POPULATE_SERIAL_DETAIL'
5205 ) THEN
5206 IF ( ( ( l_serial_count_option = 3
5207 AND l_serial_detail = 2
5208 AND g_count_quantity <> l_system_quantity
5209 )
5210 OR ( l_serial_count_option = 3 AND l_serial_detail = 1 )
5211 )
5212 AND ( l_serial_number_control_code IN ( 2, 5 ) )
5213 ) THEN
5214 BEGIN
5215 SELECT MIN ( NVL ( number_of_counts, 0 ) )
5216 INTO l_number_of_counts
5217 FROM mtl_cc_serial_numbers
5218 WHERE cycle_count_entry_id = l_cycle_count_entry_id
5219 GROUP BY cycle_count_entry_id;
5220 EXCEPTION
5221 WHEN NO_DATA_FOUND THEN
5222 l_number_of_counts := 0;
5223 END;
5224
5225 IF ( ( ( l_number_of_counts = 0 )
5226 OR ( l_number_of_counts < l_counts )
5227 )
5228 AND ( event = 'WHEN-VALIDATE-RECORD' )
5229 AND ( l_system_quantity <> 0
5230 OR g_count_quantity <> 0 )
5231 ) THEN
5232 -- FND_MESSAGE.SET_NAME('INV', 'INV_CC_NO_SN_INFO');
5233 -- FND_MSG_PUB.ADD;
5234 -- RAISE FND_API.G_EXC_ERROR;
5235 IF ( l_debug = 1 ) THEN
5236 print_debug ( 'No SN info!' );
5237 END IF;
5238 ELSE
5239 entered := 1;
5240 END IF;
5241 END IF;
5242 ELSIF event = 'OUT-TOLERANCE' THEN
5243 IF ( ( ( l_serial_count_option = 3
5244 AND l_serial_detail = 2
5245 AND ( g_count_quantity <> l_system_quantity )
5246 )
5247 OR ( l_serial_count_option = 3 AND l_serial_detail = 1 )
5248 )
5249 AND ( l_serial_number_control_code IN ( 2, 5 ) )
5250 ) THEN
5251 BEGIN
5252 SELECT MIN ( number_of_counts )
5253 INTO l_number_of_counts
5254 FROM mtl_cc_serial_numbers
5255 WHERE cycle_count_entry_id = l_cycle_count_entry_id
5256 GROUP BY cycle_count_entry_id;
5257 EXCEPTION
5258 WHEN NO_DATA_FOUND THEN
5259 l_number_of_counts := 0;
5260 END;
5261
5262 IF ( l_number_of_counts = 0
5263 OR l_number_of_counts < l_counts ) THEN
5264 FND_MESSAGE.SET_NAME ( 'INV', 'INV_CC_OUT_TOL_NO_SN' );
5265 FND_MSG_PUB.ADD;
5266 RAISE FND_API.G_EXC_ERROR;
5267 ELSE
5268 entered := 1;
5269 END IF;
5270 END IF;
5271 END IF;
5272 END is_serial_entered;
5273
5274 PROCEDURE new_serial_number
5275 IS
5276 l_serial_number VARCHAR2 ( 30 );
5277 l_serial_count_option NUMBER;
5278 l_item_id NUMBER := g_cc_entry.inventory_item_id;
5279 l_serial_detail NUMBER := g_cc_entry.serial_detail;
5280 l_garbage VARCHAR2 ( 30 );
5281 l_count NUMBER;
5282 l_success BOOLEAN := FALSE;
5283 l_cycle_count_entry_id NUMBER := g_cc_entry.cycle_count_entry_id;
5284 l_receipt VARCHAR2 ( 1 ) := 'R';
5285 l_issue VARCHAR2(1) := 'I'; /* Added by Bug 7229492 */
5286 l_serial_adjustment_option NUMBER;
5287 l_adjustment_quantity NUMBER := g_cc_entry.adjustment_quantity;
5288 l_approval_tolerance_positive NUMBER;
5289 l_approval_tolerance_negative NUMBER;
5290 l_cost_tolerance_positive NUMBER;
5291 l_cost_tolerance_negative NUMBER;
5292 l_debug NUMBER := NVL ( FND_PROFILE.VALUE ( 'INV_DEBUG_TRACE' ), 0 );
5293
5294 --Bug 5186993
5295 l_automatic_recount_flag NUMBER;
5296 l_maximum_auto_recounts NUMBER;
5297 l_days_until_late NUMBER;
5298 --Bug 6978840
5299 l_approval_option_code NUMBER;
5300
5301 BEGIN
5302 IF ( l_debug = 1 ) THEN
5303 print_debug ( '***new_serial_number***' );
5304 END IF;
5305
5306 -- Get the required variable values
5307 SELECT NVL ( serial_count_option, 1 ),
5308 NVL ( serial_adjustment_option, 2 ),
5309 NVL ( automatic_recount_flag, 2 ),
5310 NVL ( maximum_auto_recounts, 0 ),
5311 NVL ( days_until_late , 0 ),
5312 --Bug 6978840
5313 NVL ( approval_option_code , 3)
5314 INTO l_serial_count_option,
5315 l_serial_adjustment_option,
5316 l_automatic_recount_flag,
5317 l_maximum_auto_recounts,
5318 l_days_until_late,
5319 l_approval_option_code
5320 FROM mtl_cycle_count_headers
5321 WHERE cycle_count_header_id = g_cc_entry.cycle_count_header_id
5322 AND organization_id = g_cc_entry.organization_id;
5323
5324 IF ( l_serial_count_option = 3 ) THEN
5325 -- Multiple serial number per count
5326 l_serial_number := g_cc_serial_entry.serial_number;
5327
5328 SELECT COUNT ( * )
5329 INTO l_count
5330 FROM MTL_CC_SERIAL_NUMBERS
5331 WHERE serial_number = l_serial_number
5332 AND cycle_count_entry_id = l_cycle_count_entry_id;
5333
5334 IF ( l_count > 0 ) THEN
5335 FND_MESSAGE.SET_NAME ( 'INV', 'INV_DUP' );
5336 FND_MESSAGE.SET_TOKEN ( 'VALUE1', l_serial_number );
5337 FND_MSG_PUB.ADD;
5338 ROLLBACK TO save_serial_detail;
5339 RAISE FND_API.G_EXC_ERROR;
5340 END IF;
5341 ELSIF ( l_serial_count_option = 2 ) THEN
5342 -- Single serial per count
5343 l_serial_number := g_cc_entry.serial_number;
5344 END IF;
5345
5346 IF ( l_serial_number IS NULL ) THEN
5347 FND_MESSAGE.SET_NAME ( 'INV', 'INV_CC_NULL_SN' );
5348 FND_MSG_PUB.ADD;
5349 l_success := FALSE;
5350
5351 IF ( l_serial_count_option = 3 ) THEN
5352 ROLLBACK TO save_serial_detail;
5353 END IF;
5354
5355 RAISE FND_API.G_EXC_ERROR;
5356 END IF;
5357
5358 IF ( l_debug = 1 ) THEN
5359 print_debug ( 'l_automatic_recount_flag = '||l_automatic_recount_flag||', g_cc_entry.number_of_counts = '||g_cc_entry.number_of_counts);
5360 print_debug ( 'l_maximum_auto_recounts = '||l_maximum_auto_recounts||', l_adjustment_quantity = '||l_adjustment_quantity);
5361 END IF;
5362
5363 -- Bug 5186993, if automatic recount is set, check whether the adjustment has been
5364 -- counted the maximum number of times, if not setting for recount and return
5365 -- Bug 6978840 , checking if the approval option is 'If out of tolerance' and tolerance is not met
5366 if(l_approval_option_code = 3 and g_serial_out_tolerance = TRUE) then
5367 if ( l_automatic_recount_flag = 1 AND l_serial_count_option = 2
5368 AND nvl(g_cc_entry.number_of_counts, 0) <= l_maximum_auto_recounts
5369 AND nvl(l_adjustment_quantity, 0) <> 0 ) THEN
5370 IF ( l_debug = 1 ) THEN
5371 print_debug ( 'new_serial_number: Setting to recount' );
5372 END IF;
5373 g_serial_entry_status_code := 3;
5374 count_entry_status_code();
5375 get_final_count_info();
5376 g_cc_entry.count_due_date := SYSDATE + l_days_until_late;
5377 return;
5378 end if;
5379 end if;
5380
5381 /* If condition Added by 7229492 */
5382 if (l_adjustment_quantity < 0 and l_serial_count_option = 2)
5383 then
5384 l_success := check_serial_number_location(l_issue);
5385 else
5386 l_success := check_serial_number_location(l_receipt);
5387 End if;
5388 /* If condition Added by 7229492 */
5389
5390 IF ( l_success = FALSE ) THEN
5391 IF ( l_debug = 1 ) THEN
5392 print_debug ( 'check serial number: FALSE' );
5393 END IF;
5394
5395 mark ( );
5396 ELSE
5397 IF ( l_debug = 1 ) THEN
5398 print_debug ( 'check serial number: TRUE' );
5399 END IF;
5400 END IF;
5401
5402 -- Calculate if the serial is out of tolerance or not
5403 get_tolerances ( pre_approve_flag => 'SERIAL',
5404 x_approval_tolerance_positive => l_approval_tolerance_positive,
5405 x_approval_tolerance_negative => l_approval_tolerance_negative,
5406 x_cost_tolerance_positive => l_cost_tolerance_positive,
5407 x_cost_tolerance_negative => l_cost_tolerance_negative
5408 );
5409 serial_tolerance_logic ( p_serial_adj_qty => l_adjustment_quantity,
5410 p_app_tol_pos => l_approval_tolerance_positive,
5411 p_app_tol_neg => l_approval_tolerance_negative,
5412 p_cost_tol_pos => l_cost_tolerance_positive,
5413 p_cost_tol_neg => l_cost_tolerance_negative
5414 );
5415
5416 IF ( g_serial_out_tolerance ) THEN
5417 IF ( l_debug = 1 ) THEN
5418 print_debug ( 'Serial out tolerance: TRUE' );
5419 END IF;
5420 ELSE
5421 IF ( l_debug = 1 ) THEN
5422 print_debug ( 'Serial out tolerance: FALSE' );
5423 END IF;
5424 END IF;
5425
5426 IF ( l_success = FALSE ) THEN
5427 -- mtl_serial_check.inv_qtybetwn approved our Serial_Number and
5428 -- inserted into MTL_SERIAL_NUMBERS table (If needed).
5429 -- Now we need to perform necessary adjustment transactions.
5430
5431 IF ( l_debug = 1 ) THEN
5432 print_debug ( 'Serial count option: ' || l_serial_count_option );
5433 print_debug ( 'Serial adjustment option: '
5434 || l_serial_adjustment_option
5435 );
5436 END IF;
5437
5438 IF ( l_serial_adjustment_option = 1
5439 AND g_serial_out_tolerance = FALSE
5440 ) THEN
5441 -- Do a serial adjustment if possible
5442 IF ( l_debug = 1 ) THEN
5443 print_debug ( 'Trying to adjust serial' );
5444 END IF;
5445
5446 IF ( l_serial_count_option = 2 ) THEN
5447 -- Single serial
5448 g_cc_entry.approval_condition := NULL;
5449 g_cc_entry.entry_status_code := 5;
5450 print_debug('from new_serial_number : 1');
5451 final_preupdate_logic ( );
5452 ELSIF ( l_serial_count_option = 3 ) THEN
5453 -- Multiple serial
5454 g_cc_serial_entry.approval_condition := NULL;
5455 g_serial_entry_status_code := 5;
5456 g_cc_serial_entry.pos_adjustment_qty := 1;
5457 g_cc_serial_entry.neg_adjustment_qty := 0;
5458 count_entry_status_code ( );
5459 perform_serial_adj_txn ( );
5460 END IF;
5461 ELSE
5462 -- Approvals required for serial adjustment
5463 IF ( l_debug = 1 ) THEN
5464 print_debug ( 'Approvals required for serial adjustments' );
5465 END IF;
5466
5467 IF ( l_serial_count_option = 2 ) THEN
5468 -- Single serial
5469 g_cc_entry.approval_condition := 3;
5470 g_cc_entry.entry_status_code := 2;
5471 print_debug('from new_serial_number : 2');
5472 final_preupdate_logic ( );
5473 ELSIF ( l_serial_count_option = 3 ) THEN
5474 -- Multiple serial
5475 g_cc_serial_entry.approval_condition := 3;
5476 g_serial_entry_status_code := 2;
5477 g_cc_serial_entry.pos_adjustment_qty := 1;
5478 g_cc_serial_entry.neg_adjustment_qty := 0;
5479 count_entry_status_code ( );
5480 END IF;
5481 END IF;
5482 ELSE
5483 -- Serial exists so no adjustment is required
5484 IF ( l_serial_count_option = 2 ) THEN
5485 -- Single serial
5486 g_cc_entry.entry_status_code := 5;
5487 print_debug('from new_serial_number : 2');
5488 final_preupdate_logic ( );
5489 ELSIF ( l_serial_count_option = 3 ) THEN
5490 -- Multiple serial
5491 g_cc_serial_entry.pos_adjustment_qty := 1;
5492 g_cc_serial_entry.neg_adjustment_qty := 0;
5493 count_entry_status_code ( );
5494 END IF;
5495 END IF;
5496 END new_serial_number;
5497
5498 /* Deletes the serial info from mtl_cc_Serial_numbers in case of an Issue transaction */
5499 PROCEDURE delete_Serial_entry(p_serial_number IN VARCHAR2, p_cc_header_id IN NUMBER, p_cycle_count_entry_id IN NUMBER) IS
5500 BEGIN
5501
5502 DELETE FROM mtl_cc_Serial_numbers
5503 WHERE serial_number = p_serial_number
5504 AND cycle_count_entry_id IN
5505 (SELECT cycle_count_entry_id
5506 FROM mtl_cycle_count_entries
5507 WHERE cycle_Count_header_id = p_cc_header_id
5508 AND entry_status_code IN (1,3))
5509 AND cycle_count_entry_id <> p_cycle_Count_entry_id;
5510
5511 EXCEPTION
5512 WHEN OTHERS THEN
5513 print_debug('Exception while trying to delete serial number ' || g_cc_Serial_entry.serial_number);
5514 END delete_serial_entry;
5515
5516
5517 PROCEDURE existing_serial_number
5518 IS
5519 l_adjustment_quantity NUMBER := g_cc_entry.adjustment_quantity;
5520 l_system_present NUMBER;
5521 l_unit_status NUMBER;
5522 l_ret_value BOOLEAN := FALSE;
5523 l_adj_quantity NUMBER := g_cc_entry.adjustment_quantity;
5524 l_neg_adj_quantity NUMBER := g_cc_entry.neg_adjustment_quantity;
5525 l_serial_detail NUMBER := g_cc_entry.serial_detail;
5526 l_serial_count_option NUMBER;
5527 l_success BOOLEAN;
5528 l_issue VARCHAR ( 1 ) := 'I';
5529 l_receipt VARCHAR ( 1 ) := 'R';
5530 l_serial_adjustment_option NUMBER;
5531 l_system_quantity NUMBER;
5532 l_primary_uom VARCHAR2 ( 3 );
5533 l_adjustment_value NUMBER;
5534 l_multiple_count NUMBER := 0;
5535 l_approval_tolerance_positive NUMBER;
5536 l_approval_tolerance_negative NUMBER;
5537 l_cost_tolerance_positive NUMBER;
5538 l_cost_tolerance_negative NUMBER;
5539 l_debug NUMBER := NVL ( FND_PROFILE.VALUE ( 'INV_DEBUG_TRACE' ), 0 );
5540 --Bug 5186993
5541 l_automatic_recount_flag NUMBER;
5542 l_maximum_auto_recounts NUMBER;
5543 l_days_until_late NUMBER;
5544 l_cycle_count_entry_id NUMBER := g_cc_entry.cycle_count_entry_id;
5545 --Bug 6978840
5546 l_approval_option_code NUMBER;
5547
5548 BEGIN
5549 IF ( l_debug = 1 ) THEN
5550 print_debug ( '***existing_serial_number***' );
5551
5552 END IF;
5553
5554 -- Get the variable values
5555 SELECT NVL ( serial_count_option, 1 ),
5556 NVL ( serial_adjustment_option, 2 ),
5557 NVL ( automatic_recount_flag, 2 ),
5558 NVL ( maximum_auto_recounts, 0 ),
5559 NVL ( days_until_late , 0 ),
5560 --Bug 6978840
5561 NVL ( approval_option_code , 3)
5562 INTO l_serial_count_option,
5563 l_serial_adjustment_option,
5564 l_automatic_recount_flag,
5565 l_maximum_auto_recounts,
5566 l_days_until_late,
5567 l_approval_option_code
5568 FROM mtl_cycle_count_headers
5569 WHERE cycle_count_header_id = g_cc_entry.cycle_count_header_id
5570 AND organization_id = g_cc_entry.organization_id;
5571
5572 IF ( l_debug = 1 ) THEN
5573 print_debug ( 'l_automatic_recount_flag = '||l_automatic_recount_flag||', g_cc_entry.number_of_counts = '||g_cc_entry.number_of_counts);
5574 print_debug ( 'l_maximum_auto_recounts = '||l_maximum_auto_recounts||', l_adjustment_quantity = '||l_adjustment_quantity);
5575 END IF;
5576
5577 -- Bug 5186993, if automatic recount is set, check whether the adjustment has been
5578 -- counted the maximum number of times, if not setting for recount and return
5579 -- Bug 6978840 , checking if the approval option is 'If out of tolerance' and tolerance is not met
5580 if(l_approval_option_code = 3 and g_serial_out_tolerance = TRUE) then
5581 if ( l_automatic_recount_flag = 1 AND l_serial_count_option = 2
5582 AND nvl(g_cc_entry.number_of_counts, 0) <= l_maximum_auto_recounts
5583 AND nvl(l_adjustment_quantity, 0) <> 0 ) THEN
5584 IF ( l_debug = 1 ) THEN
5585 print_debug ( 'existing_serial_number: Setting to recount' );
5586 END IF;
5587 g_serial_entry_status_code := 3;
5588 count_entry_status_code();
5589 get_final_count_info();
5590 g_cc_entry.count_due_date := SYSDATE + l_days_until_late;
5591 unmark(l_cycle_count_entry_id);
5592 return;
5593 end if;
5594 end if;
5595
5596
5597
5598 -- Set the values for g_system_present and g_unit_status
5599 -- Get the item system quantity
5600 system_quantity ( x_system_quantity => l_system_quantity );
5601
5602
5603 IF ( l_system_quantity <> 0 ) THEN
5604 g_system_present := 1;
5605 ELSE
5606 g_system_present := 2;
5607 END IF;
5608
5609 IF ( g_count_quantity IS NOT NULL ) THEN
5610 IF ( g_count_quantity <> 0 ) THEN
5611 g_unit_status := 1;
5612 ELSE
5613 g_unit_status := 2;
5614 END IF;
5615 END IF;
5616
5617 IF ( l_serial_count_option = 3 ) THEN
5618 -- Need to get the value for system present manually
5619 print_debug('getting the value for the sytem present manually');
5620
5621 IF ( g_cc_entry.parent_lpn_id IS NULL ) THEN
5622 print_debug('parent_lpn_id is null');
5623 -- No LPN so we want to check if serial is present in the system
5624 -- with the given sub and loc so that if there is a discrepancy,
5625 -- it will pick it up and issue out and receive the serial into
5626 -- the sub/loc where it was found during the counting
5627 SELECT NVL ( SUM ( DECODE ( msn.current_status, 3, 1, 0 ) ), 0 )
5628 INTO l_multiple_count
5629 FROM mtl_serial_numbers msn
5630 WHERE msn.serial_number = g_cc_serial_entry.serial_number
5631 AND msn.inventory_item_id = g_cc_entry.inventory_item_id
5632 AND msn.current_organization_id = g_cc_entry.organization_id
5633 AND msn.current_subinventory_code = g_cc_entry.subinventory
5634 AND NVL ( msn.lot_number, 'XX' ) =
5635 NVL ( g_cc_entry.lot_number, 'XX' )
5636 AND NVL ( msn.revision, 'XXX' ) =
5637 NVL ( g_cc_entry.revision, 'XXX' )
5638 AND NVL ( msn.current_locator_id, -2 ) =
5639 NVL ( g_cc_entry.locator_id, -2 )
5640 AND msn.lpn_id IS NULL --Bug# 3646068
5641 AND is_serial_loaded ( g_cc_entry.organization_id,
5642 g_cc_entry.inventory_item_id,
5643 g_cc_serial_entry.serial_number,
5644 NULL
5645 ) = 2;
5646 ELSE
5647 print_debug('parent_lpn_id ' || g_cc_entry.parent_lpn_id);
5648 -- If the serial is inside an LPN but the LPN is discrepant, then
5649 -- we do not want the serial to be considered as missing here since
5650 -- we will do a sub transfer for the discrepant LPN which will
5651 -- also move the serial packed within it
5652 SELECT NVL ( SUM ( DECODE ( msn.current_status, 3, 1, 0 ) ), 0 )
5653 INTO l_multiple_count
5654 FROM mtl_serial_numbers msn
5655 WHERE msn.serial_number = g_cc_serial_entry.serial_number
5656 AND msn.inventory_item_id = g_cc_entry.inventory_item_id
5657 AND msn.current_organization_id = g_cc_entry.organization_id
5658 AND NVL ( msn.lot_number, 'XX' ) =
5659 NVL ( g_cc_entry.lot_number, 'XX' )
5660 AND NVL ( msn.revision, 'XXX' ) =
5661 NVL ( g_cc_entry.revision, 'XXX' )
5662 AND msn.lpn_id = g_cc_entry.parent_lpn_id
5663 AND is_serial_loaded ( g_cc_entry.organization_id,
5664 g_cc_entry.inventory_item_id,
5665 g_cc_serial_entry.serial_number,
5666 g_cc_entry.parent_lpn_id
5667 ) = 2;
5668 END IF;
5669
5670 print_debug('l_multiple_count ' || l_multiple_count);
5671 IF ( l_multiple_count <> 0 ) THEN
5672 g_system_present := 1;
5673 ELSE
5674 g_system_present := 2;
5675 END IF;
5676
5677 g_unit_status := g_cc_serial_entry.unit_status_current;
5678 END IF;
5679
5680 IF ( l_serial_count_option = 3 ) THEN
5681 IF ( l_debug = 1 ) THEN
5682 print_debug ( 'Serial Number: ' || g_cc_serial_entry.serial_number
5683 );
5684 END IF;
5685 ELSIF ( l_serial_count_option = 2 ) THEN
5686 IF ( l_debug = 1 ) THEN
5687 print_debug ( 'Serial Number: ' || g_cc_entry.serial_number );
5688 END IF;
5689 END IF;
5690
5691 IF ( l_debug = 1 ) THEN
5692 print_debug ( 'System Present: ' || g_system_present );
5693 print_debug ( 'Unit Status: ' || g_unit_status );
5694 END IF;
5695
5696 l_system_present := g_system_present;
5697 l_unit_status := g_unit_status;
5698
5699 IF ( l_debug = 1 ) THEN
5700 print_debug ( 'l_system_present: ' || l_system_present );
5701 print_debug ( 'l_unit_status: ' || l_unit_status );
5702 END IF;
5703
5704 -- Get the item primary uom code
5705 SELECT primary_uom_code
5706 INTO l_primary_uom
5707 FROM MTL_SYSTEM_ITEMS
5708 WHERE inventory_item_id = g_cc_entry.inventory_item_id
5709 AND organization_id = g_cc_entry.organization_id;
5710
5711 IF ( l_debug = 1 ) THEN
5712 print_debug ( 'l_primary_uom: ' || l_primary_uom );
5713 print_debug ( 'g_count_uom: ' || g_count_uom );
5714 print_debug ( 'l_primary_uom: ' || l_primary_uom );
5715 print_debug ( 'l_system_quantity: ' || l_system_quantity );
5716 print_debug ( 'g_count_quantity: ' || g_count_quantity );
5717
5718 END IF;
5719
5720 -- Convert the system quantity into the primary uom
5721
5722 l_system_quantity :=
5723 inv_convert.inv_um_convert ( g_cc_entry.inventory_item_id,
5724 6,
5725 l_system_quantity,
5726 g_count_uom,
5727 l_primary_uom,
5728 NULL,
5729 NULL
5730 );
5731 IF ( l_debug = 1 ) THEN
5732 print_debug ( 'l_system_quantity: ' || l_system_quantity );
5733 print_debug ( 'g_count_quantity: ' || g_count_quantity );
5734 END IF;
5735
5736 -- Get and set the adjustment quantity and adjustment value
5737 IF ( l_serial_count_option IN ( 2, 3 ) ) THEN
5738 l_adjustment_quantity := g_count_quantity - l_system_quantity;
5739 g_cc_entry.adjustment_quantity := l_adjustment_quantity;
5740 --Bug# 3640622 Commented out the code.
5741 --g_cc_entry.adjustment_date := SYSDATE;
5742 value_variance ( x_value_variance => l_adjustment_value );
5743 g_cc_entry.adjustment_amount := l_adjustment_value;
5744 END IF;
5745
5746 -- Calculate if the serial is out of tolerance or not
5747 get_tolerances ( pre_approve_flag => 'SERIAL',
5748 x_approval_tolerance_positive => l_approval_tolerance_positive,
5749 x_approval_tolerance_negative => l_approval_tolerance_negative,
5750 x_cost_tolerance_positive => l_cost_tolerance_positive,
5751 x_cost_tolerance_negative => l_cost_tolerance_negative
5752 );
5753 serial_tolerance_logic ( p_serial_adj_qty => l_adjustment_quantity,
5754 p_app_tol_pos => l_approval_tolerance_positive,
5755 p_app_tol_neg => l_approval_tolerance_negative,
5756 p_cost_tol_pos => l_cost_tolerance_positive,
5757 p_cost_tol_neg => l_cost_tolerance_negative
5758 );
5759
5760 IF ( g_serial_out_tolerance ) THEN
5761 IF ( l_debug = 1 ) THEN
5762 print_debug ( 'Serial out tolerance: TRUE' );
5763 END IF;
5764 ELSE
5765 IF ( l_debug = 1 ) THEN
5766 print_debug ( 'Serial out tolerance: FALSE' );
5767 END IF;
5768 END IF;
5769
5770 -- Multiple serial count option
5771 IF ( l_serial_count_option = 3 ) THEN
5772 IF ( l_debug = 1 ) THEN
5773 print_debug ( 'Multiple serial: existing_serial_number' );
5774 END IF;
5775
5776 -- If the s/n is shown on the system, but was counted as missing
5777 -- i.e. l_system_present = 1 and l_unit_status = 2, then execute.
5778 -- The serial no. will not show up in our cycle count if it does
5779 -- not exist in the system.
5780 IF ( ( l_system_present = 1 ) AND ( l_unit_status = 2 ) ) THEN
5781 IF ( l_debug = 1 ) THEN
5782 print_debug ( 'Missing serial is: '
5783 || g_cc_serial_entry.serial_number
5784 );
5785 print_debug ( 'serial adjustment option is: '
5786 || l_serial_adjustment_option
5787 );
5788 END IF;
5789
5790 IF ( l_serial_adjustment_option = 1
5791 AND g_serial_out_tolerance = FALSE
5792 ) THEN
5793 IF ( l_debug = 1 ) THEN
5794 print_debug ( 'Trying to make adjustment automatically' );
5795 END IF;
5796
5797 l_success := check_serial_number_location ( l_issue );
5798 g_cc_serial_entry.pos_adjustment_qty := 0;
5799 g_cc_serial_entry.neg_adjustment_qty := 1;
5800
5801 IF ( l_success ) THEN
5802 IF ( l_debug = 1 ) THEN
5803 print_debug ( 'check_serial_number_location: TRUE' );
5804 END IF;
5805 ELSE
5806 IF ( l_debug = 1 ) THEN
5807 print_debug ( 'check_serial_number_location: FALSE' );
5808 END IF;
5809 END IF;
5810
5811 IF ( l_success = FALSE ) THEN
5812 g_serial_entry_status_code := 5;
5813 g_cc_serial_entry.approval_condition := NULL;
5814 END IF;
5815
5816 count_entry_status_code ( );
5817 perform_serial_adj_txn ( );
5818 -- If serial adjustment option is "review all adjustments", then send to approval
5819 ELSE
5820 IF ( l_debug = 1 ) THEN
5821 print_debug ( 'Need to review this adjustment' );
5822 END IF;
5823
5824 l_success := check_serial_number_location ( l_issue );
5825 g_serial_entry_status_code := 2;
5826 g_cc_serial_entry.approval_condition := 3;
5827 g_cc_serial_entry.pos_adjustment_qty := 0;
5828 g_cc_serial_entry.neg_adjustment_qty := 1;
5829 count_entry_status_code ( );
5830 END IF;
5831 -- If the s/n is missing on the system, but was counted as present:
5832
5833 -- This part will only be executed if after CC generation some other transaction issued
5834 -- out the Serial Number but the counter finds it at the count serial location.
5835 -- The condition where serial number never existed in the system will be handled by
5836 -- 'NEW' or 'INSERT' record condition
5837 ELSIF ( ( l_system_present = 2 ) AND ( l_unit_status = 1 ) ) THEN
5838 IF ( l_debug = 1 ) THEN
5839 print_debug ( 'Serial is counted as present: '
5840 || g_cc_serial_entry.serial_number
5841 );
5842 END IF;
5843
5844 IF ( l_serial_adjustment_option = 1
5845 AND g_serial_out_tolerance = FALSE
5846 ) THEN
5847 IF ( l_debug = 1 ) THEN
5848 print_debug ( 'Trying to make adjustment automatically' );
5849 END IF;
5850
5851 l_success := check_serial_number_location ( l_receipt );
5852 g_cc_serial_entry.pos_adjustment_qty := 1;
5853 g_cc_serial_entry.neg_adjustment_qty := 0;
5854
5855 IF ( l_success ) THEN
5856 IF ( l_debug = 1 ) THEN
5857 print_debug ( 'check_serial_number_location: TRUE' );
5858 END IF;
5859 ELSE
5860 IF ( l_debug = 1 ) THEN
5861 print_debug ( 'check_serial_number_location: FALSE' );
5862 END IF;
5863 END IF;
5864
5865 IF ( l_success = FALSE ) THEN
5866 g_serial_entry_status_code := 5;
5867 g_cc_serial_entry.approval_condition := NULL;
5868 END IF;
5869
5870 count_entry_status_code ( );
5871 perform_serial_adj_txn ( );
5872 -- If serial adjustment option is "review all adjustments", then send to approval
5873 ELSE
5874 IF ( l_debug = 1 ) THEN
5875 print_debug ( 'Need to review this adjustment' );
5876 END IF;
5877
5878 l_success := check_serial_number_location ( l_receipt );
5879 g_serial_entry_status_code := 2;
5880 g_cc_serial_entry.approval_condition := 3;
5881 g_cc_serial_entry.pos_adjustment_qty := 1;
5882 g_cc_serial_entry.neg_adjustment_qty := 0;
5883 count_entry_status_code ( );
5884 END IF;
5885 /* All other cases considered as no problem, no adjustment required */
5886 ELSE
5887 IF ( l_debug = 1 ) THEN
5888 print_debug ( 'All other cases with no adjustments' );
5889 END IF;
5890
5891 g_serial_entry_status_code := 5;
5892 g_cc_entry.entry_status_code := 5; /* Added for bug#4926279*/
5893 g_cc_serial_entry.pos_adjustment_qty := NULL;
5894 g_cc_serial_entry.neg_adjustment_qty := NULL;
5895 g_cc_serial_entry.approval_condition := NULL;
5896 count_entry_status_code ( );
5897 END IF;
5898 -- Single serial count option
5899 ELSIF ( l_serial_count_option = 2 ) THEN
5900 IF ( l_debug = 1 ) THEN
5901 print_debug ( 'Single serial: existing_serial_number' );
5902 END IF;
5903
5904 /* If the s/n is shown on the system, but was counted as missing */
5905 IF ( l_adjustment_quantity = -1 ) THEN
5906 IF ( l_debug = 1 ) THEN
5907 print_debug ( 'Serial is missing: ' || g_cc_entry.serial_number
5908 );
5909 END IF;
5910
5911 IF ( l_serial_adjustment_option = 1 ) THEN
5912 IF ( l_debug = 1 ) THEN
5913 print_debug ( 'Trying to adjust the serial' );
5914 END IF;
5915
5916 l_success := check_serial_number_location ( l_issue );
5917 g_cc_entry.neg_adjustment_quantity := 1;
5918
5919 IF ( l_success = FALSE ) THEN
5920 IF ( l_debug = 1 ) THEN
5921 print_debug ( 'check_serial_number_location returned: FALSE'
5922 );
5923 END IF;
5924
5925 g_serial_entry_status_code := 5;
5926 g_cc_entry.entry_status_code := 5;
5927 g_cc_entry.approval_condition := NULL;
5928 ELSE
5929 IF ( l_debug = 1 ) THEN
5930 print_debug ( 'check_serial_number_location returned: TRUE'
5931 );
5932 END IF;
5933 END IF;
5934 print_debug('from existing_Serial_number : 1');
5935 final_preupdate_logic ( );
5936 /* If serial adjustment option is "review all adjustments", then send to approval */
5937 ELSIF ( l_serial_adjustment_option = 2 ) THEN
5938 IF ( l_debug = 1 ) THEN
5939 print_debug ( 'Serial adjustment needs to be reviewed' );
5940 END IF;
5941
5942 l_success := check_serial_number_location ( l_issue );
5943
5944 IF ( l_success = FALSE ) THEN
5945 IF ( l_debug = 1 ) THEN
5946 print_debug ( 'check_serial_number_location returned: FALSE'
5947 );
5948 END IF;
5949 ELSE
5950 IF ( l_debug = 1 ) THEN
5951 print_debug ( 'check_serial_number_location returned: TRUE'
5952 );
5953 END IF;
5954 END IF;
5955
5956 g_serial_entry_status_code := 2;
5957 g_cc_entry.entry_status_code := 2;
5958 g_cc_entry.neg_adjustment_quantity := 1;
5959 g_cc_entry.approval_condition := 3;
5960 print_debug('from existing_Serial_number : 2');
5961 final_preupdate_logic ( );
5962 END IF;
5963 /* IF the s/n is missing on the system, but was count as present */
5964 ELSIF ( l_adjustment_quantity = 1 ) THEN
5965 IF ( l_debug = 1 ) THEN
5966 print_debug ( 'Serial is found: ' || g_cc_entry.serial_number );
5967 END IF;
5968
5969 IF ( l_serial_adjustment_option = 1 ) THEN
5970 IF ( l_debug = 1 ) THEN
5971 print_debug ( 'Trying to adjust the serial' );
5972 END IF;
5973
5974 l_success := check_serial_number_location ( l_receipt );
5975 g_cc_entry.adjustment_quantity := 1;
5976
5977 IF ( l_success = FALSE ) THEN
5978 IF ( l_debug = 1 ) THEN
5979 print_debug ( 'check_serial_number_location returned: FALSE'
5980 );
5981 END IF;
5982
5983 g_serial_entry_status_code := 5;
5984 g_cc_entry.entry_status_code := 5;
5985 g_cc_entry.approval_condition := NULL;
5986 ELSE
5987 IF ( l_debug = 1 ) THEN
5988 print_debug ( 'check_serial_number_location returned: TRUE'
5989 );
5990 END IF;
5991 END IF;
5992 print_debug('from existing_Serial_number : 3');
5993 final_preupdate_logic ( );
5994 /* if serial adjustment option is "review all adjustments", then send to approval */
5995 ELSIF ( l_serial_adjustment_option = 2 ) THEN
5996 IF ( l_debug = 1 ) THEN
5997 print_debug ( 'Serial adjustment needs to be reviewed' );
5998 END IF;
5999
6000 l_success := check_serial_number_location ( l_receipt );
6001
6002 IF ( l_success = FALSE ) THEN
6003 IF ( l_debug = 1 ) THEN
6004 print_debug ( 'check_serial_number_location returned: FALSE'
6005 );
6006 END IF;
6007 ELSE
6008 IF ( l_debug = 1 ) THEN
6009 print_debug ( 'check_serial_number_location returned: TRUE'
6010 );
6011 END IF;
6012 END IF;
6013
6014 g_serial_entry_status_code := 2;
6015 g_cc_entry.entry_status_code := 2;
6016 g_cc_entry.adjustment_quantity := 1;
6017 g_cc_entry.approval_condition := 3;
6018 print_debug('from existing_Serial_number : 4');
6019 final_preupdate_logic ( );
6020 END IF;
6021 /* all other cases considered as no problem, no adjustment required */
6022 ELSE
6023 IF ( l_debug = 1 ) THEN
6024 print_debug ( 'No serial adjustment needs to be made' );
6025 END IF;
6026
6027 g_serial_entry_status_code := 5;
6028 g_cc_entry.entry_status_code := 5;
6029 g_cc_entry.neg_adjustment_quantity := NULL;
6030 g_cc_entry.approval_condition := NULL;
6031 print_debug('from existing_Serial_number : 5');
6032 final_preupdate_logic ( );
6033 END IF;
6034 END IF;
6035 END existing_serial_number;
6036
6037 -- Function check_serial_number_location
6038 --
6039 -- This function checks to see if the Serial Number where this serial number is
6040 -- located in the system.
6041 FUNCTION check_serial_number_location (
6042 issue_receipt VARCHAR2
6043 )
6044 RETURN BOOLEAN
6045 IS
6046 u1 VARCHAR2 ( 30 );
6047 u2 VARCHAR2 ( 30 );
6048 u3 NUMBER;
6049 u4 VARCHAR2 ( 30 );
6050 u5 VARCHAR2 ( 30 );
6051 u6 VARCHAR2 ( 30 );
6052 u7 VARCHAR2 ( 3 );
6053 u8 VARCHAR2 ( 30 );
6054 u9 VARCHAR2 ( 30 );
6055 u10 VARCHAR2 ( 30 );
6056 u11 VARCHAR2 ( 3 );
6057 u12 VARCHAR2 ( 30 );
6058 u13 VARCHAR2 ( 10 );
6059 u14 VARCHAR2 ( 30 );
6060 u15 VARCHAR2 ( 1 );
6061 serial_count NUMBER := 0;
6062 l_serial_count_option NUMBER;
6063 l_serial_number_type NUMBER := 1; /* Default value */
6064 l_org_id NUMBER := g_cc_entry.organization_id;
6065 l_serial_number VARCHAR2 ( 30 ) := g_cc_entry.serial_number;
6066 l_serial_detail NUMBER;
6067 l_serial_discrepancy NUMBER;
6068 l_item_id NUMBER := g_cc_entry.inventory_item_id;
6069 l_subinv VARCHAR2 ( 10 ) := g_cc_entry.subinventory;
6070 l_revision VARCHAR2 ( 3 ) := g_cc_entry.revision;
6071 l_current_status NUMBER;
6072 l_ret_value BOOLEAN := FALSE;
6073 l_system_quantity NUMBER;
6074 l_dummy_quantity NUMBER;
6075 l_serial_number_control_code NUMBER;
6076 l_return_status VARCHAR2 ( 300 );
6077 l_msg_count NUMBER;
6078 l_msg_data VARCHAR2 ( 300 );
6079 l_error_code NUMBER;
6080 l_quantity NUMBER;
6081 l_prefix VARCHAR2 ( 240 );
6082 -- Variables used for serial discrepancies
6083 l_msn_subinv VARCHAR2 ( 10 );
6084 l_msn_locator_id NUMBER;
6085 l_debug NUMBER := NVL ( FND_PROFILE.VALUE ( 'INV_DEBUG_TRACE' ), 0 );
6086 BEGIN
6087 IF ( l_debug = 1 ) THEN
6088 print_debug ( '***check_serial_number_location***' );
6089 END IF;
6090
6091 -- Get the variable values
6092 SELECT NVL ( serial_count_option, 1 ),
6093 NVL ( serial_detail_option, 1 ),
6094 NVL ( serial_discrepancy_option, 2 )
6095 INTO l_serial_count_option,
6096 l_serial_detail,
6097 l_serial_discrepancy
6098 FROM mtl_cycle_count_headers
6099 WHERE cycle_count_header_id = g_cc_entry.cycle_count_header_id
6100 AND organization_id = g_cc_entry.organization_id;
6101
6102 -- Get the serial number control code
6103 SELECT serial_number_control_code
6104 INTO l_serial_number_control_code
6105 FROM mtl_system_items
6106 WHERE inventory_item_id = g_cc_entry.inventory_item_id
6107 AND organization_id = g_cc_entry.organization_id;
6108
6109 -- Get the item system quantity
6110 system_quantity ( x_system_quantity => l_system_quantity );
6111
6112 IF ( ( l_system_quantity ) = 1
6113 AND ( g_count_quantity = 1 )
6114 AND ( l_serial_count_option = 2 )
6115 ) THEN
6116 l_ret_value := TRUE;
6117 ELSE
6118 IF ( l_org_id IS NOT NULL ) THEN
6119 SELECT SERIAL_NUMBER_TYPE
6120 INTO l_serial_number_type
6121 FROM MTL_PARAMETERS
6122 WHERE ORGANIZATION_ID = l_org_id;
6123 END IF;
6124
6125 IF ( l_debug = 1 ) THEN
6126 print_debug ( 'Got the serial number type: '
6127 || l_serial_number_type
6128 );
6129 END IF;
6130
6131 IF ( l_serial_count_option = 3 ) THEN
6132 u1 := g_cc_serial_entry.serial_number;
6133 u2 := g_cc_serial_entry.serial_number;
6134 l_serial_number := g_cc_serial_entry.serial_number;
6135 ELSE
6136 u1 := g_cc_entry.serial_number;
6137 u2 := g_cc_entry.serial_number;
6138 l_serial_number := g_cc_entry.serial_number;
6139 END IF;
6140
6141 u3 := g_cc_entry.system_quantity_current;
6142 u4 := NULL;
6143 u5 := g_cc_entry.inventory_item_id;
6144 u6 := g_cc_entry.organization_id;
6145 u7 := l_serial_number_type;
6146 u8 := g_cc_entry.cycle_count_entry_id;
6147 u9 := TO_CHAR ( 9 );
6148 u10 := l_serial_number_control_code;
6149 u11 := g_cc_entry.revision;
6150 u12 := g_cc_entry.lot_number;
6151 u13 := g_cc_entry.subinventory;
6152 u14 := g_cc_entry.locator_id;
6153 u15 := issue_receipt;
6154
6155 -- Serial was found as missing so need to issue it out.
6156 IF ( issue_receipt = 'I' ) THEN
6157 IF ( l_debug = 1 ) THEN
6158 print_debug ( 'Need to issue out the serial so reset the sub and loc'
6159 );
6160 END IF;
6161
6162 SELECT CURRENT_SUBINVENTORY_CODE,
6163 NVL ( CURRENT_LOCATOR_ID, 0 )
6164 INTO l_msn_subinv,
6165 l_msn_locator_id
6166 FROM MTL_SERIAL_NUMBERS
6167 WHERE SERIAL_NUMBER = u1
6168 AND INVENTORY_ITEM_ID = g_cc_entry.inventory_item_id
6169 AND CURRENT_ORGANIZATION_ID = g_cc_entry.organization_id;
6170
6171 -- Reset these values just for calling the validation procedure
6172 u13 := l_msn_subinv;
6173 u14 := l_msn_locator_id;
6174 END IF;
6175
6176 IF ( l_debug = 1 ) THEN
6177 print_debug ( 'Calling the package mtl_serial_check.inv_qtybetwn' );
6178 print_debug ( 'Inputs to API are: ' );
6179 print_debug ( 'p_from_serial_number: =========> ' || u1 );
6180 print_debug ( 'p_to_serial_number: ===========> ' || u2 );
6181 print_debug ( 'p_item_id: ====================> ' || u5 );
6182 print_debug ( 'p_organization_id: ============> ' || u6 );
6183 print_debug ( 'p_serial_number_type: =========> ' || u7 );
6184 print_debug ( 'p_transaction_action_id: ======> ' || u8 );
6185 print_debug ( 'p_transaction_source_type_id: => ' || u9 );
6186 print_debug ( 'p_serial_control: =============> ' || u10 );
6187 print_debug ( 'p_revision: ===================> ' || u11 );
6188 print_debug ( 'p_lot_number: =================> ' || u12 );
6189 print_debug ( 'p_subinventory: ===============> ' || u13 );
6190 print_debug ( 'p_locator_id: =================> ' || u14 );
6191 print_debug ( 'p_receipt_issue_flag: =========> ' || u15 );
6192 END IF;
6193
6194 -- Call package in file INVSERLB.PLS instead of a USER_EXIT
6195 mtl_serial_check.inv_qtybetwn ( p_api_version => 0.9,
6196 x_return_status => l_return_status,
6197 x_msg_count => l_msg_count,
6198 x_msg_data => l_msg_data,
6199 x_errorcode => l_error_code,
6200 p_from_serial_number => u1,
6201 p_to_serial_number => u2,
6202 x_quantity => l_quantity,
6203 x_prefix => l_prefix,
6204 p_item_id => u5,
6205 p_organization_id => u6,
6206 p_serial_number_type => u7,
6207 p_transaction_action_id => u8,
6208 p_transaction_source_type_id => u9,
6209 p_serial_control => u10,
6210 p_revision => u11,
6211 p_lot_number => u12,
6212 p_subinventory => u13,
6213 p_locator_id => u14,
6214 p_receipt_issue_flag => u15
6215 );
6216
6217 IF ( l_debug = 1 ) THEN
6218 print_debug ( 'Error code is: ' || l_error_code );
6219 print_debug ( 'Issue receipt: ' || issue_receipt );
6220 END IF;
6221
6222 IF ( l_error_code <> 0 AND issue_receipt = 'R' ) THEN
6223 IF ( l_debug = 1 ) THEN
6224 print_debug ( 'Serial number: ' || l_serial_number );
6225 print_debug ( 'Item ID: ' || l_item_id );
6226 print_debug ( 'Organization ID: ' || l_org_id );
6227 END IF;
6228
6229 BEGIN
6230 SELECT 1,
6231 current_status
6232 INTO serial_count,
6233 l_current_status
6234 FROM MTL_SERIAL_NUMBERS
6235 WHERE SERIAL_NUMBER = l_serial_number
6236 AND INVENTORY_ITEM_ID = l_item_id
6237 AND CURRENT_ORGANIZATION_ID = l_org_id
6238 AND CURRENT_STATUS IN ( 1, 3 );
6239 EXCEPTION
6240 WHEN OTHERS THEN
6241 IF ( l_debug = 1 ) THEN
6242 print_debug ( 'SQL Error: ' || SQLCODE );
6243 END IF;
6244 END;
6245
6246 IF ( l_debug = 1 ) THEN
6247 print_debug ( 'serial_count: ' || serial_count );
6248 print_debug ( 'serial_discrepancy: ' || l_serial_discrepancy );
6249 print_debug ( 'serial count option: ' || l_serial_count_option );
6250 END IF;
6251
6252 IF ( serial_count = 1 AND l_serial_discrepancy = 1 ) THEN
6253 IF ( l_serial_count_option = 2 ) THEN
6254 g_cc_entry.approval_condition := 1;
6255 g_cc_entry.entry_status_code := 2;
6256
6257 IF ( l_debug = 1 ) THEN
6258 print_debug ( 'entry_status_code: '
6259 || g_cc_entry.entry_status_code
6260 );
6261 END IF;
6262 ELSIF ( l_serial_count_option = 3 ) THEN
6263 g_serial_entry_status_code := 2;
6264 g_cc_serial_entry.approval_condition := 1;
6265
6266 IF ( l_debug = 1 ) THEN
6267 print_debug ( 'entry_status_code: '
6268 || g_cc_entry.entry_status_code
6269 );
6270 END IF;
6271 END IF;
6272
6273 FND_MESSAGE.SET_NAME ( 'INV', 'INV_CC_SERIAL_MULTI_TRANSACT2' );
6274 FND_MESSAGE.SET_TOKEN ( 'SERIAL', l_serial_number );
6275 FND_MSG_PUB.ADD;
6276
6277 IF ( l_debug = 1 ) THEN
6278 print_debug ( 'l_current_status: ' || l_current_status );
6279 END IF;
6280
6281 IF ( l_current_status = 1 ) THEN
6282 l_ret_value := TRUE;
6283 ELSE
6284 l_ret_value := FALSE;
6285 END IF;
6286 ELSE
6287 FND_MESSAGE.SET_NAME ( 'INV', 'INV_CC_SERIAL_DISCREPANCY' );
6288 FND_MESSAGE.SET_TOKEN ( 'SERIAL', l_serial_number );
6289 FND_MSG_PUB.ADD;
6290
6291 IF ( l_serial_count_option = 3 ) THEN
6292 -- clear_block(NO_VALIDATE);
6293 -- go_block('CC_ENTRIES');
6294 -- hide_window('CC_SERIAL_ENTRY');
6295 IF ( l_debug = 1 ) THEN
6296 print_debug ( 'Multiple serial error' );
6297 END IF;
6298
6299 ROLLBACK TO save_serial_detail;
6300 END IF;
6301
6302 RAISE FND_API.G_EXC_ERROR;
6303 END IF;
6304 ELSIF ( l_error_code <> 0 ) THEN
6305 FND_MESSAGE.SET_NAME ( 'INV', 'INV_CC_SERIAL_DISCREPANCY' );
6306 FND_MESSAGE.SET_TOKEN ( 'SERIAL', l_serial_number );
6307 FND_MSG_PUB.ADD;
6308
6309 IF ( l_serial_count_option = 3 ) THEN
6310 IF ( l_debug = 1 ) THEN
6311 print_debug ( 'Multiple serial error' );
6312 END IF;
6313
6314 ROLLBACK TO save_serial_detail;
6315 END IF;
6316
6317 RAISE FND_API.G_EXC_ERROR;
6318 END IF;
6319 END IF;
6320
6321 RETURN ( l_ret_value );
6322 END check_serial_number_location;
6323
6324 PROCEDURE perform_serial_adj_txn
6325 IS
6326 l_entry_status_code NUMBER := g_serial_entry_status_code;
6327 l_number_of_counts NUMBER := g_cc_serial_entry.number_of_counts;
6328 l_adjustment_quantity NUMBER;
6329 l_transaction_id NUMBER;
6330 l_org_id NUMBER := g_cc_entry.organization_id;
6331 l_cc_header_id NUMBER := g_cc_entry.cycle_count_header_id;
6332 l_item_id NUMBER := g_cc_entry.inventory_item_id;
6333 l_sub VARCHAR2 ( 10 ) := g_cc_entry.subinventory;
6334 l_txn_quantity NUMBER;
6335 l_txn_uom VARCHAR2 ( 3 ) := g_count_uom;
6336 l_lot_num VARCHAR2 ( 30 ) := g_cc_entry.lot_number;
6337 l_lot_exp_date DATE;
6338 l_rev VARCHAR2 ( 3 ) := g_cc_entry.revision;
6339 l_locator_id NUMBER := g_cc_entry.locator_id;
6340 l_txn_ref VARCHAR2 ( 240 ) := g_cc_entry.reference_current;
6341 l_reason_id NUMBER := g_cc_entry.transaction_reason_id;
6342 l_txn_header_id NUMBER := NVL ( g_txn_header_id, -2 );
6343 l_txn_temp_id NUMBER;
6344 l_user_id NUMBER := g_user_id;
6345 l_login_id NUMBER := g_login_id;
6346 l_txn_proc_mode NUMBER := g_txn_proc_mode;
6347 l_txn_acct_id NUMBER;
6348 l_success_flag NUMBER;
6349 l_p_uom_qty NUMBER;
6350 l_cycle_count_entry_id NUMBER := g_cc_entry.cycle_count_entry_id;
6351 l_from_uom VARCHAR2 ( 3 );
6352 l_to_uom VARCHAR2 ( 3 );
6353 l_txn_date DATE := SYSDATE;
6354 l_serial_number VARCHAR2 ( 30 ) := g_cc_serial_entry.serial_number;
6355 l_serial_prefix VARCHAR2 ( 30 );
6356 l_lpn_id NUMBER := g_cc_entry.parent_lpn_id;
6357 l_cost_group_id NUMBER := g_cc_entry.cost_group_id;
6358 -- Variables used for handling serial discrepancies
6359 l_msn_subinv VARCHAR2 ( 10 );
6360 l_msn_lot_number VARCHAR2 ( 30 );
6361 l_msn_locator_id NUMBER;
6362 l_msn_revision VARCHAR2 ( 3 );
6363 l_msn_lpn_id NUMBER;
6364 l_current_status NUMBER;
6365 l_adj_qty NUMBER;
6366 l_temp_subinv VARCHAR2 ( 10 );
6367 l_temp_locator_id NUMBER;
6368 l_item_name VARCHAR2 ( 100 );
6369 -- Bug # 2743382
6370
6371 v_available_quantity NUMBER;
6372 v_entry_status_code NUMBER;
6373 x_return_status VARCHAR2 ( 10 );
6374 x_qoh NUMBER;
6375 x_att NUMBER;
6376 v_ser_code NUMBER;
6377 v_lot_code NUMBER;
6378 v_rev_code NUMBER;
6379 v_is_ser_controlled BOOLEAN := FALSE;
6380 v_is_lot_controlled BOOLEAN := FALSE;
6381 v_is_rev_controlled BOOLEAN := FALSE;
6382 l_rqoh NUMBER;
6383 l_qr NUMBER;
6384 l_qs NUMBER;
6385 l_atr NUMBER;
6386 l_msg_count NUMBER;
6387 l_msg_data VARCHAR2 ( 2000 );
6388 l_parent_lpn_id NUMBER;
6389 l_neg_inv_rcpt_code NUMBER;
6390 l_debug NUMBER := NVL ( FND_PROFILE.VALUE ( 'INV_DEBUG_TRACE' ), 0 );
6391 l_allow_neg_onhand_prof_val NUMBER; -- 4870490
6392 BEGIN
6393 IF ( l_debug = 1 ) THEN
6394 print_debug ( '***perform_serial_adj_txn***' );
6395 END IF;
6396
6397 /*Bug 5704910*/
6398 --Clearing the quantity tree cache
6399 inv_quantity_tree_pub.clear_quantity_cache;
6400
6401 --Bug# 3640622
6402 g_cc_entry.adjustment_date := SYSDATE;
6403
6404 -- Get the item primary uom code
6405 SELECT primary_uom_code
6406 INTO l_to_uom
6407 FROM MTL_SYSTEM_ITEMS
6408 WHERE inventory_item_id = g_cc_entry.inventory_item_id
6409 AND organization_id = g_cc_entry.organization_id;
6410
6411 -- Get the cycle count header inventory adjustment account
6412 SELECT NVL ( inventory_adjustment_account, -1 )
6413 INTO l_txn_acct_id
6414 FROM mtl_cycle_count_headers
6415 WHERE cycle_count_header_id = g_cc_entry.cycle_count_header_id
6416 AND organization_id = g_cc_entry.organization_id;
6417
6418 SELECT concatenated_segments
6419 INTO l_item_name
6420 FROM mtl_system_items_kfv
6421 WHERE inventory_item_id = l_item_id AND organization_id = l_org_id;
6422
6423 l_from_uom := g_count_uom;
6424 l_txn_uom := l_from_uom;
6425
6426 IF ( l_txn_date IS NULL ) THEN
6427 l_txn_date := SYSDATE;
6428 END IF;
6429
6430 IF ( l_debug = 1 ) THEN
6431 print_debug ( 'Serial: '
6432 || g_cc_serial_entry.serial_number
6433 || ' Pos adj qty: '
6434 || g_cc_serial_entry.pos_adjustment_qty
6435 || ' Neg adj qty: '
6436 || g_cc_serial_entry.neg_adjustment_qty
6437 );
6438 END IF;
6439
6440 IF ( g_cc_serial_entry.pos_adjustment_qty = 1 ) THEN
6441 l_adjustment_quantity := 1;
6442 l_txn_quantity := 1;
6443 ELSIF ( g_cc_serial_entry.neg_adjustment_qty = 1 ) THEN
6444 l_adjustment_quantity := -1;
6445 l_txn_quantity := -1;
6446 ELSE
6447 l_adjustment_quantity := 0;
6448 l_txn_quantity := 0;
6449 END IF;
6450
6451 IF ( l_debug = 1 ) THEN
6452 print_debug ( 'Multiple serial entry status code: '
6453 || l_entry_status_code
6454 );
6455 print_debug ( 'Adjustment quantity: ' || l_adjustment_quantity );
6456 END IF;
6457
6458 IF ( l_entry_status_code = 5 AND l_adjustment_quantity <> 0 ) THEN
6459 IF ( l_txn_header_id = -2 ) THEN
6460 SELECT mtl_material_transactions_s.NEXTVAL
6461 INTO l_txn_header_id
6462 FROM DUAL;
6463
6464 g_txn_header_id := l_txn_header_id;
6465 END IF;
6466
6467 SELECT mtl_material_transactions_s.NEXTVAL
6468 INTO l_txn_temp_id
6469 FROM DUAL;
6470
6471 SELECT auto_serial_alpha_prefix
6472 INTO l_serial_prefix
6473 FROM mtl_system_items
6474 WHERE inventory_item_id = l_item_id AND organization_id = l_org_id;
6475
6476 l_p_uom_qty :=
6477 inv_convert.inv_um_convert ( l_item_id,
6478 5,
6479 l_txn_quantity,
6480 l_from_uom,
6481 l_to_uom,
6482 NULL,
6483 NULL
6484 );
6485
6486 -- Bug 3296675, we need to delete cycle count reservations before checking for availability.
6487 delete_reservation ( );
6488
6489 -- Bug # 2743382
6490
6491 SELECT negative_inv_receipt_code
6492 INTO l_neg_inv_rcpt_code --Negative Balance 1:Allowed 2:Disallowed
6493 FROM mtl_parameters
6494 WHERE organization_id = l_org_id;
6495
6496 --4870490
6497 l_allow_neg_onhand_prof_val := NVL(FND_PROFILE.VALUE('INV_ALLOW_CC_TXNS_ONHAND_NEG'),2);
6498
6499
6500 -- Bug number 4469742 commented the IF clause here AS per the discussion WITH the PM
6501 -- for the complete opinion from the PM please refer to the update in the bug
6502 --*** JSHERMAN 07/01/05 02:44 pm ***
6503 -- after this the check IF (v_available_quantity + v_adjustment_quantity < 0) will happen
6504 -- irrespective of the the l_neg_inv_rcpt_code flag value
6505
6506 -- IF ( l_neg_inv_rcpt_code = 2 ) THEN
6507
6508 SELECT serial_number_control_code,
6509 lot_control_code,
6510 revision_qty_control_code
6511 INTO v_ser_code,
6512 v_lot_code,
6513 v_rev_code
6514 FROM mtl_system_items
6515 WHERE inventory_item_id = l_item_id
6516 AND organization_id = l_org_id;
6517
6518 IF ( v_ser_code <> 1 ) THEN
6519 v_is_ser_controlled := TRUE;
6520 END IF;
6521
6522 IF ( v_lot_code <> 1 ) THEN
6523 v_is_lot_controlled := TRUE;
6524 END IF;
6525
6526 IF ( v_rev_code <> 1 ) THEN
6527 v_is_rev_controlled := TRUE;
6528 END IF;
6529
6530 inv_quantity_tree_pub.query_quantities ( p_api_version_number => 1.0,
6531 p_init_msg_lst => 'F',
6532 x_return_status => x_return_status,
6533 x_msg_count => l_msg_count,
6534 x_msg_data => l_msg_data,
6535 p_organization_id => l_org_id,
6536 p_inventory_item_id => l_item_id,
6537 p_tree_mode => 1,
6538 p_is_revision_control => v_is_rev_controlled,
6539 p_is_lot_control => v_is_lot_controlled,
6540 p_is_serial_control => v_is_ser_controlled,
6541 p_demand_source_type_id => NULL,
6542 p_revision => l_rev,
6543 p_lot_number => l_lot_num,
6544 p_lot_expiration_date => l_lot_exp_date,
6545 p_subinventory_code => l_sub,
6546 p_locator_id => l_locator_id,
6547 p_onhand_source => 3,
6548 x_qoh => x_qoh,
6549 x_rqoh => l_rqoh,
6550 x_qr => l_qr,
6551 x_qs => l_qs,
6552 x_att => x_att,
6553 x_atr => l_atr
6554 );
6555 v_available_quantity := x_att;
6556
6557 /* Bug Number 4690372
6558 Profile Value : Yes-1
6559 No/NUll- 2
6560 l_neg_rcpt_code 1- Allow
6561 2-Disallow
6562
6563 Approval Option L-Neg_rcpot Code Profile Value Behaviour
6564
6565 Always 1 1 Allows Approval
6566 Always 1 2 On Approval Error is shown
6567 Always 2 1 On Approval Error is shown
6568 Always 2 2 On Approval Error is shown
6569
6570
6571 Approval Option L-Neg_rcpot Code Profile Value Behaviour
6572
6573 Never 1 1 Adjustments happen at entry
6574 Never 1 2 Adjustments Deferrred to Approval
6575 Never 2 1 Adjustments Deferrred to Approval
6576 Never 2 2 Adjustments Deferrred to Approval
6577 */
6578
6579
6580 --Bug 5095970, changing l_atr to x_att since for non-reservable subs l_atr will be 0
6581 IF ( v_available_quantity + l_adjustment_quantity < 0 AND l_entry_status_code = 5)
6582 AND (l_allow_neg_onhand_prof_val = 2 OR l_neg_inv_rcpt_code = 2 )
6583 THEN
6584 -- The cycle count adjustment should not be processed since it will
6585 -- invalidate an existing reservation/allocation.
6586
6587 -- Reset the approval related colums in the cycle count entry record
6588 g_cc_entry.approval_type := NULL;
6589 g_cc_entry.approver_employee_id := NULL;
6590 g_cc_entry.approval_date := NULL;
6591 -- Reset the entry status code to 2: Approval required
6592 -- Do this for both the local variable as well as the global cycle count
6593 -- entry record
6594 g_cc_entry.entry_status_code := 2;
6595 l_entry_status_code := 2;
6596 END IF;
6597
6598
6599 -- Bug number 4469742 moved the IF clause here AS per the discussion WITH the PM
6600 -- for the complete opinion from the PM please refer to the update in the bug
6601 --*** JSHERMAN 07/01/05 02:44 pm ***
6602 -- after this the check IF (v_available_quantity + v_adjustment_quantity < 0) will happen
6603 -- irrespective of the the l_neg_inv_rcpt_code flag value
6604
6605 IF ( l_neg_inv_rcpt_code = 2 ) THEN
6606
6607 inv_quantity_tree_pub.update_quantities ( p_api_version_number => 1.0,
6608 p_init_msg_lst => 'F',
6609 x_return_status => x_return_status,
6610 x_msg_count => l_msg_count,
6611 x_msg_data => l_msg_data,
6612 p_organization_id => l_org_id,
6613 p_inventory_item_id => l_item_id,
6614 p_tree_mode => 1,
6615 p_is_revision_control => v_is_rev_controlled,
6616 p_is_lot_control => v_is_lot_controlled,
6617 p_is_serial_control => v_is_ser_controlled,
6618 p_demand_source_type_id => NULL,
6619 p_revision => l_rev,
6620 p_lot_number => l_lot_num,
6621 p_subinventory_code => l_sub,
6622 p_locator_id => l_locator_id,
6623 p_onhand_source => 3,
6624 p_containerized => 0,
6625 p_primary_quantity => ABS ( l_adjustment_quantity
6626 ),
6627 p_quantity_type => 5,
6628 x_qoh => x_qoh,
6629 x_rqoh => l_rqoh,
6630 x_qr => l_qr,
6631 x_qs => l_qs,
6632 x_att => x_att,
6633 x_atr => l_atr,
6634 p_lpn_id => NULL --added for lpn reservation
6635 );
6636 END IF;
6637
6638 -- Check to see if the serial number is found
6639 -- in a discrepant location or not
6640 SELECT NVL ( REVISION, 'XXX' ),
6641 NVL ( LOT_NUMBER, 'X' ),
6642 CURRENT_STATUS,
6643 CURRENT_SUBINVENTORY_CODE,
6644 NVL ( CURRENT_LOCATOR_ID, 0 ),
6645 NVL ( LPN_ID, -99 )
6646 INTO l_msn_revision,
6647 l_msn_lot_number,
6648 l_current_status,
6649 l_msn_subinv,
6650 l_msn_locator_id,
6651 l_msn_lpn_id
6652 FROM MTL_SERIAL_NUMBERS
6653 WHERE SERIAL_NUMBER = l_serial_number
6654 AND INVENTORY_ITEM_ID = g_cc_entry.inventory_item_id
6655 AND CURRENT_ORGANIZATION_ID = g_cc_entry.organization_id;
6656
6657 -- If serial number exist with status 3 but at a different loc or revision etc.
6658 -- than we first need to issue out the original serial number and then process
6659 -- the receipt transaction. Additionally, if the serial is found
6660 -- in a different LPN than what is in the system, it will also
6661 -- issue out the serial first before receiving it back into inventory
6662
6663 IF ( l_current_status = 3
6664 AND l_adjustment_quantity = 1
6665 AND ( l_msn_lpn_id <> NVL ( g_cc_entry.parent_lpn_id, -99 )
6666 OR ( ( l_msn_revision <> g_cc_entry.revision
6667 OR l_msn_lot_number <> g_cc_entry.lot_number
6668 OR l_msn_subinv <> g_cc_entry.subinventory
6669 OR l_msn_locator_id <> g_cc_entry.locator_id
6670 )
6671 AND l_msn_lpn_id = -99
6672 AND g_cc_entry.parent_lpn_id IS NULL
6673 )
6674 )
6675 ) THEN
6676 IF ( l_msn_revision = 'XXX' ) THEN
6677 l_msn_revision := NULL;
6678 END IF;
6679
6680 IF ( l_msn_lot_number = 'X' ) THEN
6681 l_msn_lot_number := NULL;
6682 END IF;
6683
6684 IF ( l_msn_locator_id = 0 ) THEN
6685 l_msn_locator_id := NULL;
6686 END IF;
6687
6688 IF ( l_msn_lpn_id = -99 ) THEN
6689 l_msn_lpn_id := NULL;
6690 END IF;
6691
6692 l_adj_qty := -1;
6693
6694 IF ( l_debug = 1 ) THEN
6695 print_debug ( 'Serial discrepancy exists so issue out the serial first'
6696 );
6697 print_debug ( 'Calling cc_transact with the following parameters: '
6698 );
6699 print_debug ( 'org_id: ========> ' || l_org_id );
6700 print_debug ( 'cc_header_id: ==> ' || l_cc_header_id );
6701 print_debug ( 'item_id: =======> ' || l_item_id );
6702 print_debug ( 'sub: ===========> ' || l_msn_subinv );
6703 print_debug ( 'puomqty: =======> ' || -l_p_uom_qty );
6704 print_debug ( 'txnqty: ========> ' || l_adj_qty );
6705 print_debug ( 'txnuom: ========> ' || l_txn_uom );
6706 print_debug ( 'txndate: =======> ' || l_txn_date );
6707 print_debug ( 'txnacctid: =====> ' || l_txn_acct_id );
6708 print_debug ( 'lotnum: ========> ' || l_msn_lot_number );
6709 print_debug ( 'lotexpdate: ====> ' || l_lot_exp_date );
6710 print_debug ( 'rev: ===========> ' || l_msn_revision );
6711 print_debug ( 'locator_id: ====> ' || l_msn_locator_id );
6712 print_debug ( 'txnref: ========> ' || l_txn_ref );
6713 print_debug ( 'reasonid: ======> ' || l_reason_id );
6714 print_debug ( 'userid: ========> ' || l_user_id );
6715 print_debug ( 'cc_entry_id: ===> ' || l_cycle_count_entry_id );
6716 print_debug ( 'loginid: =======> ' || l_login_id );
6717 print_debug ( 'txnprocmode: ===> ' || l_txn_proc_mode );
6718 print_debug ( 'txnheaderid: ===> ' || l_txn_header_id );
6719 print_debug ( 'serialnum: =====> ' || l_serial_number );
6720 print_debug ( 'txntempid: =====> ' || l_txn_temp_id );
6721 print_debug ( 'serialprefix: ==> ' || l_serial_prefix );
6722 print_debug ( 'lpn_id: ========> ' || l_msn_lpn_id );
6723 print_debug ( 'cost_group_id: => ' || l_cost_group_id );
6724 print_debug ( ' ' );
6725 END IF;
6726
6727 l_success_flag :=
6728 mtl_cc_transact_pkg.cc_transact ( org_id => l_org_id,
6729 cc_header_id => l_cc_header_id,
6730 item_id => l_item_id,
6731 sub => l_msn_subinv,
6732 puomqty => -l_p_uom_qty,
6733 txnqty => l_adj_qty,
6734 txnuom => l_txn_uom,
6735 txndate => l_txn_date,
6736 txnacctid => l_txn_acct_id,
6737 lotnum => l_msn_lot_number,
6738 lotexpdate => l_lot_exp_date,
6739 rev => l_msn_revision,
6740 locator_id => l_msn_locator_id,
6741 txnref => l_txn_ref,
6742 reasonid => l_reason_id,
6743 userid => l_user_id,
6744 cc_entry_id => l_cycle_count_entry_id,
6745 loginid => l_login_id,
6746 txnprocmode => l_txn_proc_mode,
6747 txnheaderid => l_txn_header_id,
6748 serialnum => l_serial_number,
6749 txntempid => l_txn_temp_id,
6750 serialprefix => l_serial_prefix,
6751 lpn_id => l_msn_lpn_id,
6752 cost_group_id => l_cost_group_id
6753 );
6754
6755 IF ( l_debug = 1 ) THEN
6756 print_debug ( 'success_flag: ' || l_success_flag );
6757 print_debug('Calling delete_Serial_entry 1');
6758 END IF;
6759
6760 delete_serial_entry(l_serial_number,l_cc_header_id,l_cycle_count_entry_id); --3595723 Delete the serial info from mtl_cc_Serial_numbers
6761
6762
6763 --If success flag is 2 or 3 then set the message for invalid
6764 --material status for the lot/serial and the item combination
6765 IF ( NVL ( l_success_flag, -1 ) < 0 ) THEN
6766 FND_MESSAGE.SET_NAME ( 'INV', 'INV_ADJ_TXN_FAILED' );
6767 FND_MSG_PUB.ADD;
6768 ROLLBACK TO save_serial_detail;
6769 RAISE FND_API.G_EXC_ERROR;
6770 ELSIF NVL ( l_success_flag, -1 ) = 2 THEN
6771 FND_MESSAGE.SET_NAME ( 'INV', 'INV_TRX_LOT_NA_DUE_MS' );
6772 FND_MESSAGE.SET_TOKEN ( 'TOKEN1', l_msn_lot_number );
6773 FND_MESSAGE.SET_TOKEN ( 'TOKEN2', l_item_name );
6774 FND_MSG_PUB.ADD;
6775 RAISE FND_API.G_EXC_ERROR;
6776 ELSIF NVL ( l_success_flag, -1 ) = 3 THEN
6777 FND_MESSAGE.SET_NAME ( 'INV', 'INV_TRX_SER_NA_DUE_MS' );
6778 FND_MESSAGE.SET_TOKEN ( 'TOKEN1', l_serial_number );
6779 FND_MESSAGE.SET_TOKEN ( 'TOKEN2', l_item_name );
6780 FND_MSG_PUB.ADD;
6781 RAISE FND_API.G_EXC_ERROR;
6782 END IF;
6783
6784 -- Get a new txn temp ID for receiving the serial back into inventory
6785 SELECT mtl_material_transactions_s.NEXTVAL
6786 INTO l_txn_temp_id
6787 FROM DUAL;
6788 END IF;
6789
6790 IF ( l_adjustment_quantity = 1 ) THEN
6791 -- Receiving the serial into the sub and loc where it was found
6792 l_temp_subinv := l_sub;
6793 l_temp_locator_id := l_locator_id;
6794 ELSIF ( l_adjustment_quantity = -1 ) THEN
6795 -- Issuing out the serial from the sub and loc where
6796 -- the system thinks it currently is
6797 l_temp_subinv := l_msn_subinv;
6798 l_temp_locator_id := l_msn_locator_id;
6799 IF ( l_debug = 1 ) THEN
6800 print_debug('Calling delete_Serial_entry 2');
6801 END IF;
6802 delete_serial_entry(l_serial_number,l_cc_header_id,l_cycle_count_entry_id); --3595723 Delete the serial info from mtl_cc_Serial_numbers
6803 END IF;
6804
6805 IF ( l_debug = 1 ) THEN
6806 print_debug ( 'Calling cc_transact with the following parameters: '
6807 );
6808 print_debug ( 'org_id: ===========> ' || l_org_id );
6809 print_debug ( 'cc_header_id: =====> ' || l_cc_header_id );
6810 print_debug ( 'item_id: ==========> ' || l_item_id );
6811 print_debug ( 'sub: ==============> ' || l_temp_subinv );
6812 print_debug ( 'puomqty: ==========> ' || l_p_uom_qty );
6813 print_debug ( 'txnqty: ===========> ' || l_txn_quantity );
6814 print_debug ( 'txnuom: ===========> ' || l_txn_uom );
6815 print_debug ( 'txndate: ==========> ' || l_txn_date );
6816 print_debug ( 'txnacctid: ========> ' || l_txn_acct_id );
6817 print_debug ( 'lotnum: ===========> ' || l_lot_num );
6818 print_debug ( 'lotexpdate: =======> ' || l_lot_exp_date );
6819 print_debug ( 'rev: ==============> ' || l_rev );
6820 print_debug ( 'locator_id: =======> ' || l_temp_locator_id );
6821 print_debug ( 'txnref: ===========> ' || l_txn_ref );
6822 print_debug ( 'reasonid: =========> ' || l_reason_id );
6823 print_debug ( 'userid: ===========> ' || l_user_id );
6824 print_debug ( 'cc_entry_id: ======> ' || l_cycle_count_entry_id );
6825 print_debug ( 'loginid: ==========> ' || l_login_id );
6826 print_debug ( 'txnprocmode: ======> ' || l_txn_proc_mode );
6827 print_debug ( 'txnheaderid: ======> ' || l_txn_header_id );
6828 print_debug ( 'serialnum: ========> ' || l_serial_number );
6829 print_debug ( 'txntempid: ========> ' || l_txn_temp_id );
6830 print_debug ( 'serialprefix: =====> ' || l_serial_prefix );
6831 print_debug ( 'lpn_id: ===========> ' || l_lpn_id );
6832 print_debug ( 'cost_group_id: ====> ' || l_cost_group_id );
6833 print_debug ( ' ' );
6834 END IF;
6835
6836 l_success_flag :=
6837 mtl_cc_transact_pkg.cc_transact ( org_id => l_org_id,
6838 cc_header_id => l_cc_header_id,
6839 item_id => l_item_id,
6840 sub => l_temp_subinv,
6841 puomqty => l_p_uom_qty,
6842 txnqty => l_txn_quantity,
6843 txnuom => l_txn_uom,
6844 txndate => l_txn_date,
6845 txnacctid => l_txn_acct_id,
6846 lotnum => l_lot_num,
6847 lotexpdate => l_lot_exp_date,
6848 rev => l_rev,
6849 locator_id => l_temp_locator_id,
6850 txnref => l_txn_ref,
6851 reasonid => l_reason_id,
6852 userid => l_user_id,
6853 cc_entry_id => l_cycle_count_entry_id,
6854 loginid => l_login_id,
6855 txnprocmode => l_txn_proc_mode,
6856 txnheaderid => l_txn_header_id,
6857 serialnum => l_serial_number,
6858 txntempid => l_txn_temp_id,
6859 serialprefix => l_serial_prefix,
6860 lpn_id => l_lpn_id,
6861 cost_group_id => l_cost_group_id
6862 );
6863
6864 IF ( l_debug = 1 ) THEN
6865 print_debug ( 'success_flag: ' || l_success_flag );
6866 END IF;
6867
6868 --If success flag is 2 or 3 then set the message for invalid
6869 --material status for the lot/serial and the item combination
6870 --IF NVL(l_txn_header_id, -1) < 0 OR
6871 IF NVL ( l_success_flag, -1 ) < 0 THEN
6872 FND_MESSAGE.SET_NAME ( 'INV', 'INV_ADJ_TXN_FAILED' );
6873 FND_MSG_PUB.ADD;
6874 ROLLBACK TO save_serial_detail;
6875 RAISE FND_API.G_EXC_ERROR;
6876 ELSIF NVL ( l_success_flag, -1 ) = 2 THEN
6877 FND_MESSAGE.SET_NAME ( 'INV', 'INV_TRX_LOT_NA_DUE_MS' );
6878 FND_MESSAGE.SET_TOKEN ( 'TOKEN1', l_lot_num );
6879 FND_MESSAGE.SET_TOKEN ( 'TOKEN2', l_item_name );
6880 FND_MSG_PUB.ADD;
6881 RAISE FND_API.G_EXC_ERROR;
6882 ELSIF NVL ( l_success_flag, -1 ) = 3 THEN
6883 FND_MESSAGE.SET_NAME ( 'INV', 'INV_TRX_SER_NA_DUE_MS' );
6884 FND_MESSAGE.SET_TOKEN ( 'TOKEN1', l_serial_number );
6885 FND_MESSAGE.SET_TOKEN ( 'TOKEN2', l_item_name );
6886 FND_MSG_PUB.ADD;
6887 RAISE FND_API.G_EXC_ERROR;
6888 END IF;
6889
6890 -- Set the commit status flag so that the TM will be called in the
6891 -- post commit procedure
6892 IF ( l_debug = 1 ) THEN
6893 print_debug ( 'Setting the g_commit_status_flag := 1' );
6894 END IF;
6895
6896 g_commit_status_flag := 1;
6897 g_cc_entry.inventory_adjustment_account := l_txn_acct_id;
6898 END IF;
6899 END perform_serial_adj_txn;
6900
6901 PROCEDURE count_entry_status_code
6902 IS
6903 l_count_esc NUMBER := g_count_entry_status_code;
6904 l_serial_esc NUMBER := g_serial_entry_status_code;
6905 l_debug NUMBER := NVL ( FND_PROFILE.VALUE ( 'INV_DEBUG_TRACE' ), 0 );
6906 BEGIN
6907 IF ( l_debug = 1 ) THEN
6908 print_debug ( '***count_entry_status_code***' );
6909 print_debug ( 'Count Entry Status: ' || l_count_esc );
6910 print_debug ( 'Serial Entry Status: ' || l_serial_esc );
6911 END IF;
6912
6913 IF ( l_count_esc IS NULL
6914 OR l_count_esc = 1 ) THEN
6915 g_count_entry_status_code := l_serial_esc;
6916 ELSE
6917 IF ( l_count_esc > l_serial_esc ) THEN
6918 g_count_entry_status_code := l_serial_esc;
6919 END IF;
6920 END IF;
6921 END count_entry_status_code;
6922
6923 PROCEDURE update_serial_row
6924 IS
6925 l_debug NUMBER := NVL ( FND_PROFILE.VALUE ( 'INV_DEBUG_TRACE' ), 0 );
6926 BEGIN
6927 IF ( l_debug = 1 ) THEN
6928 print_debug ( '***update_serial_row***' );
6929 END IF;
6930
6931 -- Set the WHO column information
6932 g_cc_serial_entry.last_update_date := SYSDATE;
6933 g_cc_serial_entry.last_updated_by := g_user_id;
6934 g_cc_serial_entry.last_update_login := g_login_id;
6935
6936 UPDATE MTL_CC_SERIAL_NUMBERS
6937 SET last_update_date = g_cc_serial_entry.last_update_date,
6938 last_updated_by = g_cc_serial_entry.last_updated_by,
6939 last_update_login = g_cc_serial_entry.last_update_login,
6940 number_of_counts = g_cc_serial_entry.number_of_counts,
6941 unit_status_current = g_cc_serial_entry.unit_status_current,
6942 unit_status_prior = g_cc_serial_entry.unit_status_prior,
6943 unit_status_first = g_cc_serial_entry.unit_status_first,
6944 approval_condition = g_cc_serial_entry.approval_condition,
6945 pos_adjustment_qty = g_cc_serial_entry.pos_adjustment_qty,
6946 neg_adjustment_qty = g_cc_serial_entry.neg_adjustment_qty
6947 WHERE cycle_count_entry_id = g_cc_entry.cycle_count_entry_id
6948 AND ( ( serial_number = g_cc_serial_entry.serial_number )
6949 OR ( serial_number IS NULL
6950 AND g_cc_serial_entry.serial_number IS NULL
6951 )
6952 );
6953
6954 IF ( SQL%NOTFOUND ) THEN
6955 RAISE NO_DATA_FOUND;
6956 END IF;
6957 END update_serial_row;
6958
6959 PROCEDURE mark
6960 IS
6961 g1 VARCHAR2 ( 30 );
6962 g2 VARCHAR2 ( 30 );
6963 g3 NUMBER;
6964 g4 NUMBER;
6965 g5 NUMBER;
6966 g6 NUMBER;
6967 g7 NUMBER;
6968 success NUMBER := 1;
6969 l_serial_number_ctrl_code NUMBER;
6970 l_serial_count_option NUMBER;
6971 l_debug NUMBER := NVL ( FND_PROFILE.VALUE ( 'INV_DEBUG_TRACE' ), 0 );
6972 BEGIN
6973 IF ( l_debug = 1 ) THEN
6974 print_debug ( '***mark***' );
6975 END IF;
6976
6977 -- Get the required values
6978 SELECT serial_number_control_code
6979 INTO l_serial_number_ctrl_code
6980 FROM mtl_system_items
6981 WHERE inventory_item_id = g_cc_entry.inventory_item_id
6982 AND organization_id = g_cc_entry.organization_id;
6983
6984 SELECT NVL ( serial_count_option, 1 )
6985 INTO l_serial_count_option
6986 FROM mtl_cycle_count_headers
6987 WHERE cycle_count_header_id = g_cc_entry.cycle_count_header_id
6988 AND organization_id = g_cc_entry.organization_id;
6989
6990 IF ( l_serial_number_ctrl_code IN ( 2, 5 ) ) THEN
6991 IF ( l_serial_count_option = 2 ) THEN
6992 g1 := g_cc_entry.serial_number;
6993 g2 := g_cc_entry.serial_number;
6994 ELSIF ( l_serial_count_option = 3 ) THEN
6995 g1 := g_serial_number;
6996 g2 := g_serial_number;
6997 END IF;
6998 END IF;
6999
7000 g3 := g_cc_entry.inventory_item_id;
7001 g4 := g_cc_entry.organization_id;
7002 g5 := g_cc_entry.cycle_count_header_id;
7003 g6 := g_cc_entry.cycle_count_entry_id;
7004 g7 := NULL;
7005
7006 -- Call the procedure to mark the serial only if the entry is serial
7007 -- controlled and the cycle count header is single serial
7008 IF ( l_debug = 1 ) THEN
7009 print_debug ( 'Serial number control code: '
7010 || l_serial_number_ctrl_code
7011 );
7012 print_debug ( 'Serial count option: ' || l_serial_count_option );
7013 END IF;
7014
7015 IF ( ( l_serial_number_ctrl_code IN ( 2, 5 ) )
7016 AND ( l_serial_count_option = 2 )
7017 ) THEN
7018 IF ( l_debug = 1 ) THEN
7019 print_debug ( 'Calling serial_check.inv_mark_serial with the following parameters: '
7020 );
7021 print_debug ( 'from_serial_number: => ' || g1 );
7022 print_debug ( 'to_serial_number: ===> ' || g2 );
7023 print_debug ( 'item_id: ============> ' || g3 );
7024 print_debug ( 'org_id: =============> ' || g4 );
7025 print_debug ( 'hdr_id: =============> ' || g5 );
7026 print_debug ( 'temp_id: ============> ' || g6 );
7027 print_debug ( 'lot_temp_id: ========> ' || g7 );
7028 print_debug ( ' ' );
7029 END IF;
7030
7031 serial_check.inv_mark_serial ( from_serial_number => g1,
7032 to_serial_number => g2,
7033 item_id => g3,
7034 org_id => g4,
7035 hdr_id => g5,
7036 temp_id => g6,
7037 lot_temp_id => g7,
7038 success => success
7039 );
7040
7041 IF ( l_debug = 1 ) THEN
7042 print_debug ( 'Return value of success: ' || success );
7043 END IF;
7044
7045 -- A return success value of -1 means that the serial has already
7046 -- been marked. We don't need to error out in this case.
7047 IF ( success < -1 ) THEN
7048 FND_MESSAGE.SET_NAME ( 'INV', 'INV_SERIAL_UNAVAILABLE' );
7049 FND_MESSAGE.SET_TOKEN ( 'FIRST-SERIAL', g1 );
7050 FND_MSG_PUB.ADD;
7051
7052 IF ( l_serial_count_option = 3 ) THEN
7053 ROLLBACK TO save_serial_detail;
7054 END IF;
7055
7056 RAISE FND_API.G_EXC_ERROR;
7057 END IF;
7058 END IF;
7059 END mark;
7060
7061 PROCEDURE unmark (
7062 cycle_cnt_entry_id NUMBER
7063 )
7064 IS
7065 g1 VARCHAR2 ( 30 );
7066 g2 VARCHAR2 ( 30 );
7067 g3 NUMBER;
7068 g4 NUMBER;
7069 g5 NUMBER;
7070 g6 NUMBER;
7071 g7 NUMBER;
7072 l_serial_number_ctrl_code NUMBER;
7073 l_serial_count_option NUMBER;
7074 l_current_serial VARCHAR2 ( 30 );
7075 l_current_item NUMBER;
7076 l_debug NUMBER := NVL ( FND_PROFILE.VALUE ( 'INV_DEBUG_TRACE' ), 0 );
7077 BEGIN
7078 IF ( l_debug = 1 ) THEN
7079 print_debug ( '***unmark***' );
7080 END IF;
7081
7082 -- Get the required values
7083 SELECT serial_number_control_code
7084 INTO l_serial_number_ctrl_code
7085 FROM mtl_system_items
7086 WHERE inventory_item_id = g_cc_entry.inventory_item_id
7087 AND organization_id = g_cc_entry.organization_id;
7088
7089 SELECT NVL ( serial_count_option, 1 )
7090 INTO l_serial_count_option
7091 FROM mtl_cycle_count_headers
7092 WHERE cycle_count_header_id = g_cc_entry.cycle_count_header_id
7093 AND organization_id = g_cc_entry.organization_id;
7094
7095 SELECT NVL ( serial_number, '@@@@@' ),
7096 inventory_item_id
7097 INTO l_current_serial,
7098 l_current_item
7099 FROM mtl_cycle_count_entries
7100 WHERE cycle_count_entry_id = cycle_cnt_entry_id;
7101
7102 -- Old call to serial_check.inv_unmark_serial
7103 --g1 := NULL;
7104 --g2 := NULL;
7105 --g3 := l_serial_number_ctrl_code;
7106 --g4 := g_cc_entry.cycle_count_header_id;
7107 --g5 := cycle_cnt_entry_id;
7108 --g6 := NULL;
7109
7110 -- New call to serial_check.inv_unmark_serial
7111 -- For performance reasons, pass the serial number and item id
7112 -- instead since these are the primary keys for MTL_SERIAL_NUMBERS
7113 IF ( l_serial_number_ctrl_code IN ( 2, 5 ) ) THEN
7114 IF ( l_serial_count_option = 2 ) THEN
7115 g1 := l_current_serial;
7116 g2 := l_current_serial;
7117 ELSIF ( l_serial_count_option = 3 ) THEN
7118 g1 := g_serial_number;
7119 g2 := g_serial_number;
7120 END IF;
7121 END IF;
7122
7123 g3 := l_serial_number_ctrl_code;
7124 g4 := NULL;
7125 g5 := NULL;
7126 g6 := NULL;
7127 g7 := l_current_item;
7128
7129 -- Call the procedure to unmark the serial only if the entry is serial
7130 -- controlled and the cycle count header is single serial
7131 IF ( l_debug = 1 ) THEN
7132 print_debug ( 'Serial number control code: '
7133 || l_serial_number_ctrl_code
7134 );
7135 print_debug ( 'Serial count option: ' || l_serial_count_option );
7136 END IF;
7137
7138 IF ( ( l_serial_number_ctrl_code IN ( 2, 5 ) )
7139 AND ( l_serial_count_option = 2 )
7140 ) THEN
7141 IF ( l_debug = 1 ) THEN
7142 print_debug ( 'Calling serial_check.inv_unmark_serial with the following parameters: '
7143 );
7144 print_debug ( 'from_serial_number: ==> ' || g1 );
7145 print_debug ( 'to_serial_number: ====> ' || g2 );
7146 print_debug ( 'serial_code: =========> ' || g3 );
7147 print_debug ( 'hdr_id: ==============> ' || g4 );
7148 print_debug ( 'temp_id: =============> ' || g5 );
7149 print_debug ( 'lot_temp_id: =========> ' || g6 );
7150 print_debug ( 'p_inventory_item_id: => ' || g7 );
7151 print_debug ( ' ' );
7152 END IF;
7153
7154 serial_check.inv_unmark_serial ( from_serial_number => g1,
7155 to_serial_number => g2,
7156 serial_code => g3,
7157 hdr_id => g4,
7158 temp_id => g5,
7159 lot_temp_id => g6,
7160 p_inventory_item_id => g7
7161 );
7162 END IF;
7163 END unmark;
7164
7165 PROCEDURE get_profiles
7166 IS
7167 v_user_id NUMBER;
7168 v_login_id NUMBER;
7169 profile_name VARCHAR2 ( 60 );
7170 profile_val VARCHAR2 ( 80 );
7171 l_debug NUMBER := NVL ( FND_PROFILE.VALUE ( 'INV_DEBUG_TRACE' ), 0 );
7172 BEGIN
7173 IF ( l_debug = 1 ) THEN
7174 print_debug ( '***get_profiles***' );
7175 END IF;
7176
7177 v_login_id := fnd_global.login_id;
7178 g_login_id := v_login_id;
7179 -- Get profile option for transaction date validation
7180 profile_name := 'TRANSACTION_PROCESS_MODE';
7181 profile_val := FND_PROFILE.VALUE ( profile_name );
7182
7183 IF ( profile_val = 4 ) THEN
7184 -- Get form level profile
7185 profile_name := 'CYCLE_COUNT_ENTRIES_TXN';
7186 profile_val := FND_PROFILE.VALUE ( profile_name );
7187 END IF;
7188
7189 g_txn_proc_mode := profile_val;
7190 END get_profiles;
7191
7192 PROCEDURE get_employee (
7193 p_organization_id IN NUMBER
7194 )
7195 IS
7196 l_employee_id NUMBER;
7197 l_employee_full_name VARCHAR2 ( 240 );
7198 l_user_id NUMBER := g_user_id;
7199 l_org_id NUMBER := p_organization_id;
7200 l_debug NUMBER := NVL ( FND_PROFILE.VALUE ( 'INV_DEBUG_TRACE' ), 0 );
7201 BEGIN
7202 IF ( l_debug = 1 ) THEN
7203 print_debug ( '***get_employee***' );
7204 END IF;
7205
7206 BEGIN
7207 SELECT mec.full_name,
7208 fus.employee_id
7209 INTO l_employee_full_name,
7210 l_employee_id
7211 FROM mtl_employees_current_view mec,
7212 fnd_user fus
7213 WHERE fus.user_id = l_user_id
7214 AND mec.employee_id = fus.employee_id
7215 AND mec.organization_id = l_org_id;
7216 EXCEPTION
7217 WHEN NO_DATA_FOUND THEN
7218 -- Just get the employee ID if the employee
7219 -- is not properly defined in the MTL_EMPLOYEES_CURRENT_VIEW
7220 SELECT fus.employee_id
7221 INTO l_employee_id
7222 FROM fnd_user fus
7223 WHERE fus.user_id = l_user_id;
7224
7225 l_employee_full_name := NULL;
7226 END;
7227
7228 g_employee_id := l_employee_id;
7229 g_employee_full_name := l_employee_full_name;
7230 EXCEPTION
7231 WHEN NO_DATA_FOUND THEN
7232 g_employee_id := NULL;
7233 g_employee_full_name := NULL;
7234 END get_employee;
7235
7236 PROCEDURE process_summary (
7237 p_cycle_count_header_id IN NUMBER,
7238 p_organization_id IN NUMBER,
7239 p_subinventory IN VARCHAR2,
7240 p_locator_id IN NUMBER,
7241 p_parent_lpn_id IN NUMBER,
7242 p_unscheduled_count_entry IN NUMBER,
7243 p_user_id IN NUMBER
7244 )
7245 IS
7246 l_current_lpn NUMBER;
7247 l_temp_uom_code VARCHAR2 ( 3 );
7248
7249 CURSOR nested_lpn_cursor
7250 IS
7251 SELECT *
7252 FROM WMS_LICENSE_PLATE_NUMBERS
7253 START WITH lpn_id = p_parent_lpn_id
7254 CONNECT BY parent_lpn_id = PRIOR lpn_id;
7255
7256 CURSOR lpn_contents_cursor
7257 IS
7258 SELECT *
7259 FROM WMS_LPN_CONTENTS
7260 WHERE parent_lpn_id = l_current_lpn
7261 AND NVL ( serial_summary_entry, 2 ) = 2;
7262
7263 CURSOR lpn_serial_contents_cursor
7264 IS
7265 SELECT *
7266 FROM MTL_SERIAL_NUMBERS
7267 WHERE lpn_id = l_current_lpn;
7268
7269 CURSOR lpn_multiple_serial_cursor
7270 IS
7271 SELECT *
7272 FROM WMS_LPN_CONTENTS
7273 WHERE parent_lpn_id = l_current_lpn AND serial_summary_entry = 1;
7274
7275 --Bug#4891370.Added new cursor to query loaded quantity from LPN.
7276 CURSOR lpn_loaded_quantity_cur(p_inventory_item_id NUMBER,p_organization_id NUMBER,p_lpn_id NUMBER)
7277 IS
7278 SELECT NVL ( SUM ( quantity ), 0 )
7279 FROM WMS_LOADED_QUANTITIES_V WLQV
7280 WHERE WLQV.inventory_item_id = p_inventory_item_id
7281 AND WLQV.organization_id = p_organization_id
7282 AND (lpn_id = p_lpn_id OR content_lpn_id = p_lpn_id )
7283 AND qty_type = 'LOADED';
7284
7285
7286 l_serial_count_option NUMBER;
7287 l_temp_count NUMBER;
7288 l_debug NUMBER := NVL ( FND_PROFILE.VALUE ( 'INV_DEBUG_TRACE' ), 0 );
7289 l_lpn_loaded_qty NUMBER; --Bug#4891370
7290 l_cnt_qty NUMBER; --Added for bug#4886188
7291 l_lpn_context NUMBER; --Added for bug#4886188
7292
7293 BEGIN
7294 IF ( l_debug = 1 ) THEN
7295 print_debug ( '***process_summary***' );
7296 END IF;
7297
7298 -- Get the serial count option first
7299 SELECT NVL ( serial_count_option, 1 )
7300 INTO l_serial_count_option
7301 FROM mtl_cycle_count_headers
7302 WHERE cycle_count_header_id = p_cycle_count_header_id
7303 AND organization_id = p_organization_id;
7304
7305 /* Use the cursor that searches through all levels in the parent child relationship */
7306 FOR v_lpn_id IN nested_lpn_cursor
7307 LOOP
7308 l_current_lpn := v_lpn_id.lpn_id;
7309
7310 IF ( l_debug = 1 ) THEN
7311 print_debug ( 'Current LPN: ' || l_current_lpn );
7312 END IF;
7313
7314 -- Process the count entry for the LPN item itself if it is associated with
7315 -- an inventory item
7316 IF ( v_lpn_id.inventory_item_id IS NOT NULL ) THEN
7317 -- Make sure that this inventory item is defined in the
7318 -- cycle count header item scope
7319 SELECT COUNT ( * )
7320 INTO l_temp_count
7321 FROM mtl_cycle_count_items
7322 WHERE inventory_item_id = v_lpn_id.inventory_item_id
7323 AND cycle_count_header_id = p_cycle_count_header_id;
7324
7325 IF ( l_temp_count <> 0 ) THEN
7326 /* Get the primary UOM for the container inventory item */
7327 SELECT primary_uom_code
7328 INTO l_temp_uom_code
7329 FROM mtl_system_items
7330 WHERE inventory_item_id = v_lpn_id.inventory_item_id
7331 AND organization_id = v_lpn_id.organization_id;
7332
7333 IF ( l_debug = 1 ) THEN
7334 print_debug ( 'Counting an LPN item itself' );
7335 END IF;
7336
7337 process_entry ( p_cycle_count_header_id => p_cycle_count_header_id,
7338 p_organization_id => p_organization_id,
7339 p_subinventory => p_subinventory,
7340 p_locator_id => p_locator_id,
7341 p_parent_lpn_id => v_lpn_id.parent_lpn_id,
7342 p_inventory_item_id => v_lpn_id.inventory_item_id,
7343 p_revision => v_lpn_id.revision,
7344 p_lot_number => v_lpn_id.lot_number,
7345 p_from_serial_number => v_lpn_id.serial_number,
7346 p_to_serial_number => v_lpn_id.serial_number,
7347 p_count_quantity => 1,
7348 p_count_uom => l_temp_uom_code,
7349 p_unscheduled_count_entry => p_unscheduled_count_entry,
7350 p_user_id => p_user_id,
7351 p_cost_group_id => v_lpn_id.cost_group_id
7352 );
7353 END IF;
7354 END IF;
7355
7356 /* Process the count entries for the LPN content items */
7357 FOR v_lpn_content IN lpn_contents_cursor
7358 LOOP
7359 -- Make sure that this inventory item is defined in the
7360 -- cycle count header item scope
7361 SELECT COUNT ( * )
7362 INTO l_temp_count
7363 FROM mtl_cycle_count_items
7364 WHERE inventory_item_id = v_lpn_content.inventory_item_id
7365 AND cycle_count_header_id = p_cycle_count_header_id;
7366
7367 IF ( l_temp_count <> 0 ) THEN
7368 IF ( l_debug = 1 ) THEN
7369 print_debug ( 'Counting an LPN content item' );
7370 END IF;
7371
7372
7373 --Bug#4891370.Reduce the loaded quantity from count quantity.
7374 OPEN lpn_loaded_quantity_cur(v_lpn_content.inventory_item_id,p_organization_id,l_current_lpn);
7375 FETCH lpn_loaded_quantity_cur INTO l_lpn_loaded_qty;
7376
7377 IF (lpn_loaded_quantity_cur%FOUND) THEN
7378 v_lpn_content.quantity := v_lpn_content.quantity - l_lpn_loaded_qty;
7379 IF ( l_debug = 1 ) THEN
7380 print_debug ('For lpn_id:'||l_current_lpn||',Loaded qty:'||l_lpn_loaded_qty
7381 ||',count qty:'|| v_lpn_content.quantity );
7382 END IF;
7383 END IF;
7384
7385 CLOSE lpn_loaded_quantity_cur; ----End of fix for Bug#4891370
7386
7387 process_entry ( p_cycle_count_header_id => p_cycle_count_header_id,
7388 p_organization_id => p_organization_id,
7389 p_subinventory => p_subinventory,
7390 p_locator_id => p_locator_id,
7391 p_parent_lpn_id => v_lpn_content.parent_lpn_id,
7392 p_inventory_item_id => v_lpn_content.inventory_item_id,
7393 p_revision => v_lpn_content.revision,
7394 p_lot_number => v_lpn_content.lot_number,
7395 p_from_serial_number => NULL,
7396 p_to_serial_number => NULL,
7397 p_count_quantity => v_lpn_content.quantity,
7398 p_count_uom => v_lpn_content.uom_code,
7399 p_unscheduled_count_entry => p_unscheduled_count_entry,
7400 p_user_id => p_user_id,
7401 p_cost_group_id => v_lpn_content.cost_group_id
7402 );
7403 END IF;
7404 END LOOP;
7405
7406 /* Process the count entries for serialized items */
7407 IF ( l_serial_count_option = 2 ) THEN
7408 -- Single serial
7409 FOR v_lpn_serial_content IN lpn_serial_contents_cursor
7410 LOOP
7411 -- Make sure that this inventory item is defined in the
7412 -- cycle count header item scope
7413 SELECT COUNT ( * )
7414 INTO l_temp_count
7415 FROM mtl_cycle_count_items
7416 WHERE inventory_item_id =
7417 v_lpn_serial_content.inventory_item_id
7418 AND cycle_count_header_id = p_cycle_count_header_id;
7419
7420 IF ( l_temp_count <> 0 ) THEN
7421 /* Get the primary UOM for the serialized item */
7422 SELECT primary_uom_code
7423 INTO l_temp_uom_code
7424 FROM mtl_system_items
7425 WHERE inventory_item_id =
7426 v_lpn_serial_content.inventory_item_id
7427 AND organization_id =
7428 v_lpn_serial_content.current_organization_id;
7429
7430 IF ( l_debug = 1 ) THEN
7431 print_debug ( 'Counting an LPN single serial controlled item'
7432 );
7433 END IF;
7434
7435 /*
7436 ****** Fix for bug 4886188
7437 ****** If the Lpn Context is 'Issued Out of Stores' or 'Intransit' or 'Packing Context' or 'Loaded to Dock'
7438 ****** count quantity should be taken as 0.
7439 */
7440
7441 IF ( p_parent_lpn_id IS NOT NULL ) THEN
7442
7443 SELECT
7444 lpn_context
7445 INTO l_lpn_context
7446 FROM WMS_LICENSE_PLATE_NUMBERS
7447 WHERE lpn_id = p_parent_lpn_id ;
7448
7449 IF ( l_debug = 1 ) THEN
7450 print_debug ( 'l_lpn_context: => ' || l_lpn_context );
7451 END IF;
7452
7453 IF l_lpn_context = 8 or l_lpn_context = 9 or l_lpn_context = 4 or l_lpn_context = 6 THEN
7454 l_cnt_qty := 0 ;
7455 ELSE
7456 l_cnt_qty := 1 ;
7457 END IF;
7458 END IF;
7459 /* End of fix for bug number 4886188 */
7460
7461
7462 process_entry ( p_cycle_count_header_id => p_cycle_count_header_id,
7463 p_organization_id => p_organization_id,
7464 p_subinventory => p_subinventory,
7465 p_locator_id => p_locator_id,
7466 p_parent_lpn_id => v_lpn_serial_content.lpn_id,
7467 p_inventory_item_id => v_lpn_serial_content.inventory_item_id,
7468 p_revision => v_lpn_serial_content.revision,
7469 p_lot_number => v_lpn_serial_content.lot_number,
7470 p_from_serial_number => v_lpn_serial_content.serial_number,
7471 p_to_serial_number => v_lpn_serial_content.serial_number,
7472 p_count_quantity => l_cnt_qty, --Changed for Bug Number 4886188
7473 p_count_uom => l_temp_uom_code,
7474 p_unscheduled_count_entry => p_unscheduled_count_entry,
7475 p_user_id => p_user_id,
7476 p_cost_group_id => v_lpn_serial_content.cost_group_id
7477 );
7478 END IF;
7479 END LOOP;
7480 ELSIF ( l_serial_count_option = 3 ) THEN
7481 -- Multiple Serial
7482 FOR v_lpn_multiple_serial IN lpn_multiple_serial_cursor
7483 LOOP
7484 -- Make sure that this inventory item is defined in the
7485 -- cycle count header item scope
7486 SELECT COUNT ( * )
7487 INTO l_temp_count
7488 FROM mtl_cycle_count_items
7489 WHERE inventory_item_id =
7490 v_lpn_multiple_serial.inventory_item_id
7491 AND cycle_count_header_id = p_cycle_count_header_id;
7492
7493 IF ( l_temp_count <> 0 ) THEN
7494 -- Mark all of the serials as present
7495 IF ( l_debug = 1 ) THEN
7496 print_debug ( 'Marking all of the multiple serials as present'
7497 );
7498 END IF;
7499
7500 inv_cyc_serials.mark_all_present ( p_organization_id => p_organization_id,
7501 p_subinventory => p_subinventory,
7502 p_locator_id => p_locator_id,
7503 p_inventory_item_id => v_lpn_multiple_serial.inventory_item_id,
7504 p_revision => v_lpn_multiple_serial.revision,
7505 p_lot_number => v_lpn_multiple_serial.lot_number,
7506 p_cycle_count_header_id => p_cycle_count_header_id,
7507 p_parent_lpn_id => v_lpn_multiple_serial.parent_lpn_id
7508 );
7509
7510 IF ( l_debug = 1 ) THEN
7511 print_debug ( 'Counting an LPN multiple serial controlled item'
7512 );
7513 END IF;
7514
7515 process_entry ( p_cycle_count_header_id => p_cycle_count_header_id,
7516 p_organization_id => p_organization_id,
7517 p_subinventory => p_subinventory,
7518 p_locator_id => p_locator_id,
7519 p_parent_lpn_id => v_lpn_multiple_serial.parent_lpn_id,
7520 p_inventory_item_id => v_lpn_multiple_serial.inventory_item_id,
7521 p_revision => v_lpn_multiple_serial.revision,
7522 p_lot_number => v_lpn_multiple_serial.lot_number,
7523 p_from_serial_number => NULL,
7524 p_to_serial_number => NULL,
7525 p_count_quantity => NULL,
7526 p_count_uom => NULL,
7527 p_unscheduled_count_entry => p_unscheduled_count_entry,
7528 p_user_id => p_user_id,
7529 p_cost_group_id => v_lpn_multiple_serial.cost_group_id
7530 );
7531 END IF;
7532 END LOOP;
7533 END IF;
7534 END LOOP;
7535 END process_summary;
7536
7537 PROCEDURE inv_serial_info (
7538 p_from_serial_number IN VARCHAR2,
7539 p_to_serial_number IN VARCHAR2,
7540 x_prefix OUT NOCOPY VARCHAR2,
7541 x_quantity OUT NOCOPY VARCHAR2,
7542 x_from_number OUT NOCOPY VARCHAR2,
7543 x_to_number OUT NOCOPY VARCHAR2,
7544 x_errorcode OUT NOCOPY NUMBER
7545 )
7546 IS
7547 L_f_alp_part VARCHAR2 ( 30 );
7548 L_t_alp_part VARCHAR2 ( 30 );
7549 L_f_num_part VARCHAR2 ( 30 );
7550 L_t_num_part VARCHAR2 ( 30 );
7551 L_ser_col_val VARCHAR2 ( 30 );
7552 L_ser_col_num NUMBER;
7553 L_from_length NUMBER;
7554 L_to_length NUMBER;
7555 L_f_ser_num VARCHAR2 ( 30 );
7556 L_t_ser_num VARCHAR2 ( 30 );
7557 l_debug NUMBER := NVL ( FND_PROFILE.VALUE ( 'INV_DEBUG_TRACE' ), 0 );
7558 BEGIN
7559 IF ( l_debug = 1 ) THEN
7560 print_debug ( '***inv_serial_info***' );
7561 END IF;
7562
7563 x_errorcode := 0;
7564 L_f_ser_num := P_FROM_SERIAL_NUMBER;
7565 L_t_ser_num := P_TO_SERIAL_NUMBER;
7566 -- Get the lengths of the two serial numbers. If the to serial
7567 -- number is not specified copy from serial number to it.
7568 L_from_length := NVL ( LENGTH ( L_f_ser_num ), 0 );
7569 L_to_length := NVL ( LENGTH ( L_t_ser_num ), 0 );
7570
7571 IF ( l_debug = 1 ) THEN
7572 print_debug ( 'L_from_length=' || L_from_length );
7573 print_debug ( 'L_to_length=' || L_to_length );
7574 END IF;
7575
7576 IF ( L_from_length = 0 ) THEN
7577 FND_MESSAGE.SET_NAME ( 'INV', 'INV_QTYBTWN_NO_SERIAL' );
7578 FND_MSG_PUB.ADD;
7579 x_errorcode := 124;
7580 END IF;
7581
7582 IF ( L_to_length = 0 ) THEN
7583 L_t_ser_num := L_f_ser_num;
7584 L_to_length := L_from_length;
7585 END IF;
7586
7587 -- Split the given serial number into alpha
7588 -- prefix and numeric part.
7589
7590 /* From Serial Number */
7591 L_ser_col_num := L_from_length;
7592
7593 WHILE ( L_ser_col_num > 0 )
7594 LOOP
7595 L_ser_col_val := SUBSTR ( L_f_ser_num, L_ser_col_num, 1 );
7596
7597 IF ASCII ( L_ser_col_val ) >= 48 AND ASCII ( L_ser_col_val ) <= 57 THEN
7598 L_f_num_part := L_ser_col_val || L_f_num_part;
7599 ELSE
7600 L_f_alp_part := SUBSTR ( L_f_ser_num, 1, L_ser_col_num );
7601 EXIT;
7602 END IF;
7603
7604 L_ser_col_num := L_ser_col_num - 1;
7605 END LOOP;
7606
7607 -- To Serial Number
7608 -- Values for 0 to 9 is corresponds to ASCII value 48 TO 57
7609 -- All other values are Non-numeric value
7610 L_ser_col_num := L_to_length;
7611
7612 WHILE ( L_ser_col_num > 0 )
7613 LOOP
7614 L_ser_col_val := SUBSTR ( L_t_ser_num, L_ser_col_num, 1 );
7615
7616 IF ASCII ( L_ser_col_val ) >= 48 AND ASCII ( L_ser_col_val ) <= 57 THEN
7617 L_t_num_part := L_ser_col_val || L_t_num_part;
7618 ELSE
7619 L_t_alp_part := SUBSTR ( L_t_ser_num, 1, L_ser_col_num );
7620 EXIT;
7621 END IF;
7622
7623 L_ser_col_num := L_ser_col_num - 1;
7624 END LOOP;
7625
7626 -- We compare the prefixes to see IF they are the same
7627
7628 IF ( L_f_alp_part <> L_t_alp_part )
7629 OR ( l_f_alp_part IS NULL AND l_t_alp_part IS NOT NULL )
7630 OR ( l_f_alp_part IS NOT NULL AND l_t_alp_part IS NULL ) THEN
7631 FND_MESSAGE.SET_NAME ( 'INV', 'INV_QTYBTWN_PFX' );
7632 FND_MSG_PUB.ADD;
7633 x_errorcode := 119;
7634 END IF;
7635
7636 -- Check the lengths of the two serial numbers to make sure they
7637 -- match.
7638 IF ( L_from_length <> L_to_length ) THEN
7639 -- Message Name : INV_QTYBTWN_LGTH
7640 FND_MESSAGE.SET_NAME ( 'INV', 'INV_QTYBTWN_LGTH' );
7641 FND_MSG_PUB.ADD;
7642 x_errorcode := 120;
7643 END IF;
7644
7645 -- Check whether the serial numbers are matched
7646 -- IF not, check the last character of serial number is character
7647 -- IF yes, return error message
7648
7649 -- XXX checks only one
7650 IF L_f_ser_num <> L_t_ser_num THEN
7651 IF ASCII ( SUBSTR ( L_f_ser_num, LENGTH ( L_f_ser_num ), 1 ) ) <
7652 48
7653 AND ASCII ( SUBSTR ( L_f_ser_num, LENGTH ( L_f_ser_num ), 1 ) ) >
7654 57 THEN
7655 FND_MESSAGE.SET_NAME ( 'INV', 'INV_QTYBTWN_LAST' );
7656 FND_MSG_PUB.ADD;
7657 x_errorcode := 121;
7658 END IF;
7659 END IF;
7660
7661 -- Calculate the dIFference of serial numbers
7662 -- How many serial nos are there in the given range
7663 IF ( l_debug = 1 ) THEN
7664 print_debug ( 'L_t_num_part=' || L_t_num_part );
7665 print_debug ( 'L_f_num_part=' || L_f_num_part );
7666 END IF;
7667
7668 -- Out variables
7669 X_Quantity :=
7670 NVL ( TO_NUMBER ( L_t_num_part ), 0 )
7671 - NVL ( TO_NUMBER ( L_f_num_part ), 0 )
7672 + 1;
7673
7674 IF ( X_Quantity <= 0 ) THEN
7675 -- Message Name : INV_QTYBTWN_NUM
7676 FND_MESSAGE.SET_NAME ( 'INV', 'INV_QTYBTWN_NUM' );
7677 FND_MSG_PUB.ADD;
7678 x_errorcode := 122;
7679 END IF;
7680
7681 -- Check to make sure To serial number is greater than
7682 -- From serial number.
7683
7684 X_PREFIX := L_f_alp_part;
7685 X_FROM_NUMBER := L_f_num_part;
7686 X_TO_NUMBER := L_t_num_part;
7687 EXCEPTION
7688 WHEN OTHERS THEN
7689 x_errorcode := -1;
7690 END;
7691
7692 PROCEDURE get_default_cost_group_id (
7693 p_organization_id IN NUMBER,
7694 p_subinventory IN VARCHAR2,
7695 x_out OUT NOCOPY NUMBER
7696 )
7697 IS
7698 l_default_cost_group_id NUMBER;
7699 l_debug NUMBER := NVL ( FND_PROFILE.VALUE ( 'INV_DEBUG_TRACE' ), 0 );
7700 BEGIN
7701 IF ( l_debug = 1 ) THEN
7702 print_debug ( '***get_default_cost_group_id***' );
7703 END IF;
7704
7705 BEGIN
7706 SELECT default_cost_group_id
7707 INTO l_default_cost_group_id
7708 FROM mtl_secondary_inventories
7709 WHERE organization_id = p_organization_id
7710 AND secondary_inventory_name = p_subinventory;
7711 EXCEPTION
7712 WHEN NO_DATA_FOUND THEN
7713 l_default_cost_group_id := NULL;
7714 END;
7715
7716 -- If there is no default at the sub level, get it at the org level
7717 IF ( l_default_cost_group_id IS NULL ) THEN
7718 SELECT NVL ( default_cost_group_id, -999 )
7719 INTO l_default_cost_group_id
7720 FROM mtl_parameters
7721 WHERE organization_id = p_organization_id;
7722 END IF;
7723
7724 -- Set the out parameters
7725 x_out := l_default_cost_group_id;
7726 END get_default_cost_group_id;
7727
7728 PROCEDURE get_cost_group_id (
7729 p_organization_id IN NUMBER,
7730 p_subinventory IN VARCHAR2,
7731 p_locator_id IN NUMBER,
7732 p_parent_lpn_id IN NUMBER,
7733 p_inventory_item_id IN NUMBER,
7734 p_revision IN VARCHAR2,
7735 p_lot_number IN VARCHAR2,
7736 p_serial_number IN VARCHAR2,
7737 x_out OUT NOCOPY NUMBER
7738 )
7739 IS
7740 l_cost_group_id NUMBER;
7741 l_debug NUMBER := NVL ( FND_PROFILE.VALUE ( 'INV_DEBUG_TRACE' ), 0 );
7742 BEGIN
7743 IF ( l_debug = 1 ) THEN
7744 print_debug ( '***get_cost_group_id***' );
7745 END IF;
7746
7747 IF ( p_serial_number IS NOT NULL ) THEN
7748 SELECT NVL ( cost_group_id, -999 )
7749 INTO l_cost_group_id
7750 FROM mtl_serial_numbers
7751 WHERE serial_number = p_serial_number
7752 AND inventory_item_id = p_inventory_item_id
7753 AND NVL ( revision, '@@@@@' ) = NVL ( p_revision, '@@@@@' )
7754 AND NVL ( lot_number, '@@@@@' ) = NVL ( p_lot_number, '@@@@@' )
7755 AND current_organization_id = p_organization_id
7756 --AND current_subinventory_code = p_subinventory
7757 --AND NVL(current_locator_id, -99999) = NVL(p_locator_id, -99999)
7758 AND NVL ( lpn_id, -99999 ) = NVL ( p_parent_lpn_id, -99999 );
7759 ELSIF ( p_parent_lpn_id IS NOT NULL ) THEN
7760 BEGIN
7761 SELECT DISTINCT NVL ( cost_group_id, -999 ) --bug3687177
7762 INTO l_cost_group_id
7763 FROM wms_lpn_contents
7764 WHERE parent_lpn_id = p_parent_lpn_id
7765 AND organization_id = p_organization_id
7766 AND inventory_item_id = p_inventory_item_id
7767 AND NVL ( revision, '@@@@@' ) = NVL ( p_revision, '@@@@@' )
7768 AND NVL ( lot_number, '@@@@@' ) = NVL ( p_lot_number, '@@@@@' )
7769 AND NVL ( serial_summary_entry, 2 ) = 2;
7770 EXCEPTION
7771 WHEN TOO_MANY_ROWS THEN
7772 IF ( l_debug = 1 ) THEN
7773 print_debug ( 'Too many rows returned in call to get_cost_group_id');
7774 END IF;
7775 END;
7776 ELSE
7777 SELECT DISTINCT NVL ( cost_group_id, -999 )
7778 INTO l_cost_group_id
7779 FROM MTL_ONHAND_QUANTITIES_DETAIL
7780 WHERE inventory_item_id = p_inventory_item_id
7781 AND NVL ( revision, '@@@@@' ) =
7782 NVL ( p_revision, '@@@@@' )
7783 AND NVL ( lot_number, '@@@@@' ) =
7784 NVL ( p_lot_number, '@@@@@' )
7785 AND organization_id = p_organization_id
7786 AND subinventory_code = p_subinventory
7787 AND NVL ( locator_id, -99999 ) =
7788 NVL ( p_locator_id, -99999 )
7789 AND NVL ( containerized_flag, 2 ) = 2;
7790 END IF;
7791
7792 -- Set the out return variable
7793 x_out := l_cost_group_id;
7794 EXCEPTION
7795 WHEN TOO_MANY_ROWS THEN
7796 IF ( l_debug = 1 ) THEN
7797 print_debug ( 'Too many rows returned in call to get_cost_group_id'
7798 );
7799 END IF;
7800
7801 x_out := -999;
7802 WHEN NO_DATA_FOUND THEN
7803 IF ( l_debug = 1 ) THEN
7804 print_debug ( 'No cost group found for this item' );
7805 END IF;
7806
7807 x_out := -999;
7808 END get_cost_group_id;
7809
7810 PROCEDURE ok_proc
7811 IS
7812 tmp_count NUMBER;
7813 serial_pos_adj_count NUMBER;
7814 serial_neg_adj_count NUMBER;
7815 cur_rec NUMBER;
7816
7817 CURSOR cc_multiple_entry_cursor
7818 IS
7819 SELECT *
7820 FROM mtl_cc_serial_numbers
7821 WHERE cycle_count_entry_id = g_cc_entry.cycle_count_entry_id;
7822
7823 l_group_mark_id NUMBER;
7824 l_serial_adjustment_option NUMBER;
7825 l_approval_tolerance_positive NUMBER;
7826 l_approval_tolerance_negative NUMBER;
7827 l_cost_tolerance_positive NUMBER;
7828 l_cost_tolerance_negative NUMBER;
7829 l_number_of_counts NUMBER;
7830 l_unit_status NUMBER;
7831 l_num_counts NUMBER := g_cc_entry.number_of_counts;
7832 l_debug NUMBER := NVL ( FND_PROFILE.VALUE ( 'INV_DEBUG_TRACE' ), 0 );
7833 --Bug 5186993
7834 l_automatic_recount_flag NUMBER;
7835 l_maximum_auto_recounts NUMBER;
7836 l_days_until_late NUMBER;
7837 --Bug 6978840
7838 l_approval_option_code NUMBER;
7839
7840 BEGIN
7841 IF ( l_debug = 1 ) THEN
7842 print_debug ( '***ok_proc***' );
7843 END IF;
7844
7845 tmp_count := 0;
7846 g_serial_out_tolerance := FALSE;
7847 -- There is never a positive serial adjustment since
7848 -- new serials will never be counted in mobile multiple
7849 -- serial counting. That is not being allowed at this time.
7850 serial_pos_adj_count := 0;
7851 serial_neg_adj_count := 0;
7852 g_count_entry_status_code := g_cc_entry.entry_status_code;
7853 OPEN cc_multiple_entry_cursor;
7854
7855 LOOP
7856 -- Note that here, all we are doing is calculating the values for
7857 -- serial_pos_adj_count, serial_neg_adj_count, and tmp_count in this loop.
7858 FETCH cc_multiple_entry_cursor INTO g_cc_serial_entry;
7859 EXIT WHEN cc_multiple_entry_cursor%NOTFOUND;
7860
7861 IF ( l_debug = 1 ) THEN
7862 print_debug ( 'Current serial processing: '
7863 || g_cc_serial_entry.serial_number
7864 );
7865 END IF;
7866
7867 -- For each multiple serial entry, get the
7868 -- serial number's group mark ID to determine if it was
7869 -- counted as present or not
7870 SELECT group_mark_id
7871 INTO l_group_mark_id
7872 FROM mtl_serial_numbers
7873 WHERE serial_number = g_cc_serial_entry.serial_number
7874 AND current_organization_id = g_cc_entry.organization_id
7875 AND inventory_item_id = g_cc_entry.inventory_item_id;
7876
7877 IF ( l_group_mark_id = 1 ) THEN
7878 -- We can not count the serial number towards the total count
7879 -- if the serial number was marked as not present.
7880 tmp_count := tmp_count + 1;
7881 l_unit_status := 1;
7882 ELSE
7883 l_unit_status := 2;
7884 END IF;
7885
7886 IF ( l_debug = 1 ) THEN
7887 print_debug ( 'Serial status for: '
7888 || g_cc_serial_entry.serial_number
7889 || ' = '
7890 || l_unit_status
7891 );
7892 END IF;
7893
7894 -- Find out the number of serial numbers user claims as missing and also
7895 -- find out the number of new serial numbers user finds during the count
7896 -- Note that in mobile multiple cycle counting, we are currently NOT
7897 -- allowing unscheduled multiple serial entries
7898 IF ( ( g_cc_serial_entry.unit_status_current <>
7899 g_cc_serial_entry.unit_status_prior
7900 )
7901 OR ( g_cc_serial_entry.unit_status_first IS NULL )
7902 ) THEN
7903 -- Since we do not allow new multiple serials to be found yet for
7904 -- mobile, serial_pos_adj_count will always be the initial value of
7905 -- 0. If this serial entry was new, then we would increment
7906 -- the parameter serial_pos_adj_count
7907 IF ( l_unit_status = 2 ) THEN
7908 serial_neg_adj_count := serial_neg_adj_count - 1;
7909 END IF;
7910 END IF;
7911
7912 -- Update the multiple serial info
7913 -- Modified the following for the Bug 4564346
7914 --l_number_of_counts := NVL ( g_cc_serial_entry.number_of_counts, 0 ) + 1;
7915 l_number_of_counts := NVL ( g_cc_serial_entry.number_of_counts,1);
7916
7917 IF ( l_number_of_counts = 1 ) THEN
7918 -- First count
7919 g_cc_serial_entry.unit_status_current := l_unit_status;
7920 g_cc_serial_entry.unit_status_first := l_unit_status;
7921 ELSIF ( l_number_of_counts > 1 ) THEN
7922 g_cc_serial_entry.unit_status_prior :=
7923 g_cc_serial_entry.unit_status_current;
7924 g_cc_serial_entry.unit_status_current := l_unit_status;
7925 END IF;
7926
7927 -- Following condition will only be true for new
7928 -- serial numbers created at the recount stage.
7929 IF ( l_number_of_counts <= l_num_counts ) THEN
7930 l_number_of_counts := l_num_counts + 1;
7931 END IF;
7932
7933 g_cc_serial_entry.number_of_counts := l_number_of_counts;
7934 END LOOP;
7935
7936 CLOSE cc_multiple_entry_cursor;
7937 -- Set the global count and UOM values for multiple serials
7938 -- since this is not initially set
7939 g_count_quantity := tmp_count;
7940
7941 SELECT primary_uom_code
7942 INTO g_count_uom
7943 FROM mtl_system_items
7944 WHERE inventory_item_id = g_cc_entry.inventory_item_id
7945 AND organization_id = g_cc_entry.organization_id;
7946
7947 -- Get the serial adjustment option for the cycle count header
7948 -- Bug 5186993
7949 SELECT NVL ( serial_adjustment_option, 2 ), NVL ( automatic_recount_flag, 2 ),
7950 NVL ( maximum_auto_recounts, 0 ), NVL ( days_until_late , 0 ),
7951 --Bug 6978840
7952 NVL( approval_option_code , 3)
7953 INTO l_serial_adjustment_option, l_automatic_recount_flag, l_maximum_auto_recounts, l_days_until_late, l_approval_option_code
7954 FROM mtl_cycle_count_headers
7955 WHERE cycle_count_header_id = g_cc_entry.cycle_count_header_id;
7956
7957 -- The user has selected 'Adjust if Possible' option for the serial items
7958 IF ( l_debug = 1 ) THEN
7959 print_debug ( 'Multiple serial adjustment option: '
7960 || l_serial_adjustment_option
7961 );
7962 END IF;
7963
7964 IF ( l_serial_adjustment_option <> 2 ) THEN
7965 -- Populate appropriate cycle count level tolerance information
7966 get_tolerances ( pre_approve_flag => 'SERIAL',
7967 x_approval_tolerance_positive => l_approval_tolerance_positive,
7968 x_approval_tolerance_negative => l_approval_tolerance_negative,
7969 x_cost_tolerance_positive => l_cost_tolerance_positive,
7970 x_cost_tolerance_negative => l_cost_tolerance_negative
7971 );
7972
7973 -- If user found new serial numbers during his counting then find out
7974 -- if total number of new serial numbers are within allowable tolerance or not.
7975 IF ( l_debug = 1 ) THEN
7976 print_debug ( 'Serial Pos Adj Count: ' || serial_pos_adj_count );
7977 END IF;
7978
7979 IF ( serial_pos_adj_count <> 0 ) THEN
7980 serial_tolerance_logic ( p_serial_adj_qty => serial_pos_adj_count,
7981 p_app_tol_pos => l_approval_tolerance_positive,
7982 p_app_tol_neg => l_approval_tolerance_negative,
7983 p_cost_tol_pos => l_cost_tolerance_positive,
7984 p_cost_tol_neg => l_cost_tolerance_negative
7985 );
7986 END IF;
7987
7988 -- If user found some serial numbers missing and we are still within
7989 -- adjustment tolerance then find out if we are within allowable
7990 -- negative tolerance or not.
7991 IF ( l_debug = 1 ) THEN
7992 print_debug ( 'Serial Neg Adj Count: ' || serial_neg_adj_count );
7993 END IF;
7994
7995 IF ( serial_neg_adj_count <> 0 AND g_serial_out_tolerance = FALSE ) THEN
7996 serial_tolerance_logic ( p_serial_adj_qty => serial_neg_adj_count,
7997 p_app_tol_pos => l_approval_tolerance_positive,
7998 p_app_tol_neg => l_approval_tolerance_negative,
7999 p_cost_tol_pos => l_cost_tolerance_positive,
8000 p_cost_tol_neg => l_cost_tolerance_negative
8001 );
8002 END IF;
8003 END IF;
8004
8005 -- For existing records
8006 IF ( l_debug = 1 ) THEN
8007 print_debug ( 'Looping again for multiple existing serial entries' );
8008 END IF;
8009
8010 OPEN cc_multiple_entry_cursor;
8011
8012 LOOP
8013 FETCH cc_multiple_entry_cursor INTO g_cc_serial_entry;
8014 EXIT WHEN cc_multiple_entry_cursor%NOTFOUND;
8015
8016 -- For each multiple serial entry, get the
8017 -- serial number's group mark ID to determine if it was
8018 -- counted as present or not. We have to do this again since
8019 -- the updating in the same cursor used previously does not save
8020 -- and we do not want to necessarily do a commit yet.
8021 SELECT group_mark_id
8022 INTO l_group_mark_id
8023 FROM mtl_serial_numbers
8024 WHERE serial_number = g_cc_serial_entry.serial_number
8025 AND current_organization_id = g_cc_entry.organization_id
8026 AND inventory_item_id = g_cc_entry.inventory_item_id;
8027
8028 IF ( l_group_mark_id = 1 ) THEN
8029 l_unit_status := 1;
8030 ELSE
8031 l_unit_status := 2;
8032 END IF;
8033
8034 -- Update the multiple serial info
8035 l_number_of_counts :=
8036 NVL ( g_cc_serial_entry.number_of_counts, 0 )
8037 + 1;
8038
8039 IF ( l_number_of_counts = 1 ) THEN
8040 -- First count
8041 g_cc_serial_entry.unit_status_current := l_unit_status;
8042 g_cc_serial_entry.unit_status_first := l_unit_status;
8043 ELSIF ( l_number_of_counts > 1 ) THEN
8044 g_cc_serial_entry.unit_status_prior :=
8045 g_cc_serial_entry.unit_status_current;
8046 g_cc_serial_entry.unit_status_current := l_unit_status;
8047 END IF;
8048
8049 -- Following condition will only be true for new serial numbers
8050 -- created at the recount stage.
8051 IF ( l_number_of_counts <= l_num_counts ) THEN
8052 l_number_of_counts := l_num_counts + 1;
8053 END IF;
8054
8055 -- Update the number of counts
8056 g_cc_serial_entry.number_of_counts := l_number_of_counts;
8057
8058 IF ( l_debug = 1 ) THEN
8059 print_debug ( 'Serial number processed: '
8060 || g_cc_serial_entry.serial_number
8061 );
8062 print_debug ( 'number of counts: '
8063 || g_cc_serial_entry.number_of_counts
8064 );
8065 print_debug ( 'current status: '
8066 || g_cc_serial_entry.unit_status_current
8067 );
8068 print_debug ( 'prior status: '
8069 || g_cc_serial_entry.unit_status_prior
8070 );
8071 print_debug ( 'first status: '
8072 || g_cc_serial_entry.unit_status_first
8073 );
8074 END IF;
8075
8076 IF ( g_cc_serial_entry.unit_status_current =
8077 NVL ( g_cc_serial_entry.unit_status_prior, -999 )
8078 ) THEN
8079 IF ( l_debug = 1 ) THEN
8080 print_debug ( 'Status of serial is unchanged' );
8081 END IF;
8082
8083 g_serial_entry_status_code := 5;
8084 count_entry_status_code ( );
8085 update_serial_row ( );
8086 ELSIF ( g_cc_serial_entry.unit_status_current <>
8087 NVL ( g_cc_serial_entry.unit_status_prior, -999 )
8088 ) THEN
8089 IF ( l_debug = 1 ) THEN
8090 print_debug ( 'Status of serial has changed since last counted'
8091 );
8092 END IF;
8093
8094 -- Dont need to mark the serial since the serial has already
8095 -- been marked with a group mark ID of 1 if it was counted as
8096 -- present for multiple serial count option. I'm also assuming
8097 -- that if the serial is unmarked, it will have a null value or
8098 -- non-positive value for the group mark ID for that serial number
8099 --mark();
8100 existing_serial_number ( );
8101 count_entry_status_code ( );
8102 update_serial_row ( );
8103 END IF;
8104
8105 -- Bug# 2379201
8106 -- If the serial was counted as present, then we should unmark the
8107 -- serial here since we don't need that information anymore.
8108 -- The group mark ID was marked with a value of 1 only to indicate
8109 -- that it was present and so no adjustment needs to be made for that
8110 -- serial. Therefore there is no need to mark it.
8111 IF ( g_cc_serial_entry.unit_status_current = 1 ) THEN
8112 IF ( l_debug = 1 ) THEN
8113 print_debug ( 'Unmarking the serial found present: '
8114 || g_cc_serial_entry.serial_number
8115 );
8116 END IF;
8117
8118 UPDATE mtl_serial_numbers
8119 SET group_mark_id = NULL
8120 WHERE serial_number = g_cc_serial_entry.serial_number
8121 AND current_organization_id = g_cc_entry.organization_id
8122 AND inventory_item_id = g_cc_entry.inventory_item_id;
8123 END IF;
8124 END LOOP;
8125
8126 CLOSE cc_multiple_entry_cursor;
8127
8128 -- This is based on the assumption that only Approver can request a recount in case of
8129 -- Multiple Serial Number per count. In that case after recount is done and no changes
8130 -- are made, we need to send the count back for approval.
8131 IF ( g_count_entry_status_code = 3 ) THEN
8132 g_count_entry_status_code := 2;
8133 END IF;
8134
8135 IF ( l_debug = 1 ) THEN
8136 print_debug ( 'l_automatic_recount_flag = '||l_automatic_recount_flag||', g_cc_entry.number_of_counts = '||g_cc_entry.number_of_counts||', l_maximum_auto_recounts = '||l_maximum_auto_recounts);
8137 END IF;
8138
8139 -- Bug 5186993, if automatic recount is set, check whether the adjustment has been
8140 -- counted the maximum number of times, if not setting for recount
8141 -- Bug 6978840 , checking if the approval option is 'If out of tolerance' and tolerance is not met
8142 if(l_approval_option_code = 3 and g_serial_out_tolerance = TRUE) then
8143 if ( l_automatic_recount_flag = 1 AND nvl(g_cc_entry.number_of_counts, 0) < l_maximum_auto_recounts ) THEN
8144 IF ( l_debug = 1 ) THEN
8145 print_debug ( 'ok_proc: Setting to recount' );
8146 END IF;
8147 g_count_entry_status_code := 3;
8148 g_cc_entry.count_due_date := SYSDATE + l_days_until_late;
8149 end if;
8150 end if;
8151
8152 get_final_count_info ( );
8153 END ok_proc;
8154
8155 PROCEDURE serial_tolerance_logic (
8156 p_serial_adj_qty IN NUMBER,
8157 p_app_tol_pos IN NUMBER,
8158 p_app_tol_neg IN NUMBER,
8159 p_cost_tol_pos IN NUMBER,
8160 p_cost_tol_neg IN NUMBER
8161 )
8162 IS
8163 l_system_quantity NUMBER;
8164 l_adjustment_value NUMBER;
8165 l_approval_option_code NUMBER;
8166 l_item_cost NUMBER;
8167 l_debug NUMBER := NVL ( FND_PROFILE.VALUE ( 'INV_DEBUG_TRACE' ), 0 );
8168 BEGIN
8169 IF ( l_debug = 1 ) THEN
8170 print_debug ( '***serial_tolerance_logic***' );
8171 END IF;
8172
8173 -- Get the cycle count headers approval option code
8174 SELECT NVL ( approval_option_code, 1 )
8175 INTO l_approval_option_code
8176 FROM mtl_cycle_count_headers
8177 WHERE cycle_count_header_id = g_cc_entry.cycle_count_header_id
8178 AND organization_id = g_cc_entry.organization_id;
8179
8180 -- Get the system quantity
8181 system_quantity ( x_system_quantity => l_system_quantity );
8182 g_serial_out_tolerance := FALSE;
8183 -- Get the item cost
8184 l_item_cost :=
8185 get_item_cost ( in_org_id => g_cc_entry.organization_id,
8186 in_item_id => g_cc_entry.inventory_item_id,
8187 in_locator_id => g_cc_entry.locator_id
8188 );
8189 g_cc_entry.item_unit_cost := l_item_cost;
8190 -- Calculate the adjustment value
8191 l_adjustment_value := l_item_cost * p_serial_adj_qty;
8192
8193 IF ( l_debug = 1 ) THEN
8194 print_debug ( 'Value : l_system_quantity ' || l_system_quantity );
8195 print_debug ( 'Value : p_serial_adj_qty ' || p_serial_adj_qty );
8196 print_debug ( 'Value : p_app_tol_neg ' || p_app_tol_neg );
8197 print_debug ( 'Value : p_cost_tol_neg ' || p_cost_tol_neg );
8198 print_debug ( 'Value : p_app_tol_pos ' || p_app_tol_pos );
8199 END IF;
8200
8201
8202 IF ( l_approval_option_code = 1 ) THEN
8203 -- Approval_option = always
8204 g_serial_out_tolerance := TRUE;
8205 ELSIF ( l_approval_option_code = 2 ) THEN
8206 -- Approval option = never
8207 g_serial_out_tolerance := FALSE;
8208 ELSE
8209 -- Approval option = required if out of tolerance
8210 IF ( l_system_quantity <> 0 ) THEN
8211 IF ( p_serial_adj_qty < 0 ) THEN
8212 IF ( ( p_app_tol_neg IS NOT NULL and p_app_tol_neg <> -1 ) /* added -1 constraint for bug 4926279 */
8213 AND ( ABS ( ( p_serial_adj_qty / l_system_quantity )
8214 * 100 ) > p_app_tol_neg
8215 )
8216 ) THEN
8217 g_serial_out_tolerance := TRUE;
8218 ELSE
8219 IF ( ( p_cost_tol_neg IS NOT NULL and p_cost_tol_neg <> -1 ) /* added -1 constraint for bug 4926279 */
8220 AND ( ABS ( l_adjustment_value ) > p_cost_tol_neg )
8221 ) THEN
8222 g_serial_out_tolerance := TRUE;
8223 ELSE
8224 g_serial_out_tolerance := FALSE;
8225 END IF;
8226 END IF;
8227 ELSE -- p_serial_adj_qty >= 0
8228 IF ( ( p_app_tol_pos IS NOT NULL and p_app_tol_pos <> -1) /* added -1 constraint for bug 4926279 */
8229 AND ( ABS ( ( p_serial_adj_qty / l_system_quantity )
8230 * 100 ) > p_app_tol_pos
8231 )
8232 ) THEN
8233 g_serial_out_tolerance := TRUE;
8234 ELSE
8235 IF ( p_cost_tol_pos IS NOT NULL and p_cost_tol_pos <> -1 /* added -1 constraint for bug 4926279 */
8236 AND ( ABS ( l_adjustment_value ) > p_cost_tol_pos )
8237 ) THEN
8238 g_serial_out_tolerance := TRUE;
8239 ELSE
8240 g_serial_out_tolerance := FALSE;
8241 END IF;
8242 END IF;
8243 END IF;
8244 ELSE -- system quantity = 0
8245 IF ( p_app_tol_pos IS NOT NULL and p_app_tol_pos <> -1) THEN /* added -1 constraint for bug 4926279 */
8246 g_serial_out_tolerance := TRUE;
8247 ELSE
8248 IF ( ( p_cost_tol_pos IS NOT NULL and p_cost_tol_pos <> -1) /* added -1 constraint for bug 4926279 */
8249 AND ( l_adjustment_value > p_cost_tol_pos )
8250 ) THEN
8251 g_serial_out_tolerance := TRUE;
8252 ELSE
8253 g_serial_out_tolerance := FALSE;
8254 END IF;
8255 END IF;
8256 END IF;
8257 END IF;
8258
8259 IF ( g_serial_out_tolerance ) THEN
8260 IF ( l_debug = 1 ) THEN
8261 print_debug ( 'g_serial_out_tolerance: TRUE' );
8262 END IF;
8263 ELSE
8264 IF ( l_debug = 1 ) THEN
8265 print_debug ( 'g_serial_out_tolerance: FALSE' );
8266 END IF;
8267 END IF;
8268 END serial_tolerance_logic;
8269
8270 PROCEDURE get_final_count_info
8271 IS
8272 l_entry_status_code NUMBER;
8273 l_debug NUMBER := NVL ( FND_PROFILE.VALUE ( 'INV_DEBUG_TRACE' ), 0 );
8274 BEGIN
8275 IF ( l_debug = 1 ) THEN
8276 print_debug ( '***get_final_count_info***' );
8277 END IF;
8278
8279 g_cc_entry.entry_status_code := g_count_entry_status_code;
8280 l_entry_status_code := g_cc_entry.entry_status_code;
8281
8282 IF ( l_entry_status_code = 5 ) THEN
8283 -- Count complete
8284 g_cc_entry.approval_date := SYSDATE;
8285 END IF;
8286 END get_final_count_info;
8287
8288 PROCEDURE get_scheduled_entry (
8289 p_cycle_count_header_id IN NUMBER,
8290 x_count OUT NOCOPY NUMBER
8291 )
8292 IS
8293 l_debug NUMBER := NVL ( FND_PROFILE.VALUE ( 'INV_DEBUG_TRACE' ), 0 );
8294 BEGIN
8295 IF ( l_debug = 1 ) THEN
8296 print_debug ( '***get_scheduled_entry***' );
8297 END IF;
8298
8299 SELECT COUNT ( * )
8300 INTO x_count
8301 FROM mtl_cycle_count_entries
8302 WHERE cycle_count_header_id = p_cycle_count_header_id
8303 AND entry_status_code IN ( 1, 3 )
8304 AND NVL ( export_flag, 2 ) = 2;
8305 END get_scheduled_entry;
8306
8307 -- This is a wrapper to call inventory INV_LOT_API_PUB.insertLot
8308 -- it stores the inserted lot info in a global variable for
8309 -- transaction exception rollback
8310 PROCEDURE insert_dynamic_lot (
8311 p_api_version IN NUMBER,
8312 p_init_msg_list IN VARCHAR2,
8313 p_commit IN VARCHAR2,
8314 p_validation_level IN NUMBER,
8315 p_inventory_item_id IN NUMBER,
8316 p_organization_id IN NUMBER,
8317 p_lot_number IN VARCHAR2,
8318 p_expiration_date IN OUT NOCOPY DATE,
8319 p_transaction_temp_id IN NUMBER,
8320 p_transaction_action_id IN NUMBER,
8321 p_transfer_organization_id IN NUMBER,
8322 p_status_id IN NUMBER,
8323 p_update_status IN VARCHAR2,
8324 x_object_id OUT NOCOPY NUMBER,
8325 x_return_status OUT NOCOPY VARCHAR2,
8326 x_msg_count OUT NOCOPY NUMBER,
8327 x_msg_data OUT NOCOPY VARCHAR2
8328 )
8329 IS
8330 l_debug NUMBER := NVL ( FND_PROFILE.VALUE ( 'INV_DEBUG_TRACE' ), 0 );
8331 BEGIN
8332 -- Initialize the return status
8333 x_return_status := FND_API.G_RET_STS_SUCCESS;
8334
8335 IF ( l_debug = 1 ) THEN
8336 print_debug ( '***Calling insert_dynamic_lot***' );
8337 END IF;
8338
8339 IF ( l_debug = 1 ) THEN
8340 print_debug ( 'Calling insertlot' );
8341 END IF;
8342
8343 inv_lot_api_pub.insertlot ( p_api_version => p_api_version,
8344 p_init_msg_list => p_init_msg_list,
8345 p_commit => p_commit,
8346 p_validation_level => p_validation_level,
8347 p_inventory_item_id => p_inventory_item_id,
8348 p_organization_id => p_organization_id,
8349 p_lot_number => p_lot_number,
8350 p_expiration_date => p_expiration_date,
8351 p_transaction_temp_id => p_transaction_temp_id,
8352 p_transaction_action_id => p_transaction_action_id,
8353 p_transfer_organization_id => p_transfer_organization_id,
8354 x_object_id => x_object_id,
8355 x_return_status => x_return_status,
8356 x_msg_count => x_msg_count,
8357 x_msg_data => x_msg_data
8358 );
8359
8360 IF ( x_return_status <> fnd_api.g_ret_sts_success ) THEN
8361 IF ( l_debug = 1 ) THEN
8362 print_debug ( 'insertLot was not called successfully' );
8363 END IF;
8364
8365 RAISE FND_API.G_EXC_ERROR;
8366 END IF;
8367
8368 IF ( l_debug = 1 ) THEN
8369 print_debug ( 'insertLot was called successfully' );
8370 END IF;
8371
8372 IF ( ( x_return_status = FND_API.g_ret_sts_success )
8373 AND ( p_update_status = 'TRUE' )
8374 ) THEN
8375 IF ( l_debug = 1 ) THEN
8376 print_debug ( 'Update the status of the new lot' );
8377 END IF;
8378
8379 inv_material_status_grp.update_status ( p_api_version_number => p_api_version,
8380 p_init_msg_lst => NULL,
8381 x_return_status => x_return_status,
8382 x_msg_count => x_msg_count,
8383 x_msg_data => x_msg_data,
8384 p_update_method => inv_material_status_pub.g_update_method_receive,
8385 p_status_id => p_status_id,
8386 p_organization_id => p_organization_id,
8387 p_inventory_item_id => p_inventory_item_id,
8388 p_sub_code => NULL,
8389 p_locator_id => NULL,
8390 p_lot_number => p_lot_number,
8391 p_serial_number => NULL,
8392 p_to_serial_number => NULL,
8393 p_object_type => 'O'
8394 );
8395
8396 IF ( x_return_status <> fnd_api.g_ret_sts_success ) THEN
8397 IF ( l_debug = 1 ) THEN
8398 print_debug ( 'update_status was not called successfully' );
8399 END IF;
8400
8401 RAISE FND_API.G_EXC_ERROR;
8402 END IF;
8403 END IF;
8404 END insert_dynamic_lot;
8405
8406 PROCEDURE update_serial_status (
8407 p_api_version IN NUMBER,
8408 p_init_msg_list IN VARCHAR2,
8409 p_commit IN VARCHAR2,
8410 p_validation_level IN NUMBER,
8411 p_inventory_item_id IN NUMBER,
8412 p_organization_id IN NUMBER,
8413 p_from_serial_number IN VARCHAR2,
8414 p_to_serial_number IN VARCHAR2,
8415 p_current_status IN NUMBER,
8416 p_serial_status_id IN NUMBER,
8417 p_update_serial_status IN VARCHAR2,
8418 p_lot_number IN VARCHAR2,
8419 x_return_status OUT NOCOPY VARCHAR2,
8420 x_msg_count OUT NOCOPY NUMBER,
8421 x_msg_data OUT NOCOPY VARCHAR2
8422 )
8423 IS
8424 l_from_ser_number NUMBER;
8425 l_to_ser_number NUMBER;
8426 l_range_numbers NUMBER;
8427 l_temp_prefix VARCHAR2 ( 30 );
8428 l_cur_serial_number VARCHAR2 ( 30 );
8429 l_cur_ser_number NUMBER;
8430 l_serial_num_length NUMBER;
8431 l_prefix_length NUMBER;
8432 l_progress VARCHAR2 ( 10 );
8433 l_success NUMBER;
8434 l_debug NUMBER := NVL ( FND_PROFILE.VALUE ( 'INV_DEBUG_TRACE' ), 0 );
8435 BEGIN
8436 IF ( l_debug = 1 ) THEN
8437 print_debug ( 'Enter update_serial_status: 10:'
8438 || TO_CHAR ( SYSDATE, 'YYYY-MM-DD HH:DD:SS' )
8439 );
8440 END IF;
8441
8442 l_progress := '10';
8443 x_return_status := FND_API.G_RET_STS_SUCCESS;
8444 SAVEPOINT count_update_serial_sp;
8445 l_progress := '20';
8446 -- get the number part of the 'to' serial
8447 inv_validate.number_from_sequence ( p_to_serial_number,
8448 l_temp_prefix,
8449 l_to_ser_number
8450 );
8451 l_progress := '30';
8452 -- get the number part of the 'from' serial
8453 inv_validate.number_from_sequence ( p_from_serial_number,
8454 l_temp_prefix,
8455 l_from_ser_number
8456 );
8457 l_progress := '40';
8458 -- total number of serials inserted into mtl_serial_numbers
8459 l_range_numbers := l_to_ser_number - l_from_ser_number + 1;
8460 l_serial_num_length := LENGTH ( p_from_serial_number );
8461 l_prefix_length := LENGTH ( l_temp_prefix );
8462
8463 FOR i IN 1 .. l_range_numbers
8464 LOOP
8465 l_cur_ser_number := l_from_ser_number + i - 1;
8466 -- concatenate the serial number to be inserted
8467 l_cur_serial_number :=
8468 l_temp_prefix
8469 || LPAD ( l_cur_ser_number,
8470 l_serial_num_length - l_prefix_length,
8471 '0'
8472 );
8473 l_progress := '50';
8474
8475 UPDATE mtl_serial_numbers
8476 SET previous_status = current_status,
8477 current_status = p_current_status,
8478 lot_number = p_lot_number,
8479 current_organization_id = p_organization_id
8480 WHERE serial_number = l_cur_serial_number
8481 AND inventory_item_id = p_inventory_item_id;
8482
8483 l_progress := '60';
8484
8485 IF p_update_serial_status = 'TRUE' THEN
8486 l_progress := '70';
8487 inv_material_status_grp.update_status ( p_api_version_number => p_api_version,
8488 p_init_msg_lst => NULL,
8489 x_return_status => x_return_status,
8490 x_msg_count => x_msg_count,
8491 x_msg_data => x_msg_data,
8492 p_update_method => inv_material_status_pub.g_update_method_receive,
8493 p_status_id => p_serial_status_id,
8494 p_organization_id => p_organization_id,
8495 p_inventory_item_id => p_inventory_item_id,
8496 p_sub_code => NULL,
8497 p_locator_id => NULL,
8498 p_lot_number => p_lot_number,
8499 p_serial_number => l_cur_serial_number,
8500 p_to_serial_number => NULL,
8501 p_object_type => 'S'
8502 );
8503 END IF;
8504
8505 l_progress := '80';
8506
8507 IF x_return_status <> fnd_api.g_ret_sts_success THEN
8508 RAISE FND_API.G_EXC_ERROR;
8509 END IF;
8510 END LOOP;
8511
8512 l_progress := '90';
8513 serial_check.inv_mark_serial ( from_serial_number => p_from_serial_number,
8514 to_serial_number => p_to_serial_number,
8515 item_id => p_inventory_item_id,
8516 org_id => p_organization_id,
8517 hdr_id => NULL,
8518 temp_id => NULL,
8519 lot_temp_id => NULL,
8520 success => l_success
8521 );
8522 l_progress := '100';
8523
8524 IF ( l_debug = 1 ) THEN
8525 print_debug ( 'Exit update_serial_status 110:'
8526 || TO_CHAR ( SYSDATE, 'YYYY-MM-DD HH:DD:SS' )
8527 );
8528 END IF;
8529 EXCEPTION
8530 WHEN FND_API.G_EXC_ERROR THEN
8531 ROLLBACK TO count_update_serial_sp;
8532 x_return_status := FND_API.G_RET_STS_ERROR;
8533
8534 IF ( l_debug = 1 ) THEN
8535 print_debug ( 'Exitting update_serial_status - execution error:'
8536 || l_progress
8537 || ' '
8538 || TO_CHAR ( SYSDATE, 'YYYY-MM-DD HH:DD:SS' )
8539 );
8540 END IF;
8541
8542 -- Get message count and data
8543 fnd_msg_pub.count_and_get ( p_encoded => fnd_api.g_false,
8544 p_count => x_msg_count,
8545 p_data => x_msg_data
8546 );
8547 WHEN FND_API.G_EXC_UNEXPECTED_ERROR THEN
8548 ROLLBACK TO count_update_serial_sp;
8549 x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
8550
8551 IF ( l_debug = 1 ) THEN
8552 print_debug ( 'Exitting update_serial_status - unexpected error:'
8553 || l_progress
8554 || ' '
8555 || TO_CHAR ( SYSDATE, 'YYYY-MM-DD HH:DD:SS' )
8556 );
8557 END IF;
8558
8559 -- Get message count and data
8560 fnd_msg_pub.count_and_get ( p_encoded => fnd_api.g_false,
8561 p_count => x_msg_count,
8562 p_data => x_msg_data
8563 );
8564 WHEN OTHERS THEN
8565 ROLLBACK TO count_update_serial_sp;
8566 x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
8567
8568 IF ( l_debug = 1 ) THEN
8569 print_debug ( 'Exitting update_serial_status - other exceptions:'
8570 || l_progress
8571 || ' '
8572 || TO_CHAR ( SYSDATE, 'YYYY-MM-DD HH:DD:SS' )
8573 );
8574 END IF;
8575
8576 IF SQLCODE IS NOT NULL THEN
8577 inv_mobile_helper_functions.sql_error ( 'INV_RCV_COMMON_APIS.update_serial_status',
8578 l_progress,
8579 SQLCODE
8580 );
8581 END IF;
8582
8583 IF fnd_msg_pub.check_msg_level ( fnd_msg_pub.g_msg_lvl_unexp_error ) THEN
8584 fnd_msg_pub.add_exc_msg ( g_pkg_name, 'update_serial_status' );
8585 END IF;
8586
8587 -- Get message count and data
8588 fnd_msg_pub.count_and_get ( p_encoded => fnd_api.g_false,
8589 p_count => x_msg_count,
8590 p_data => x_msg_data
8591 );
8592 END update_serial_status;
8593
8594 -- This is a wrapper to call inventory insert_range_serial
8595 PROCEDURE insert_range_serial (
8596 p_api_version IN NUMBER,
8597 p_init_msg_list IN VARCHAR2,
8598 p_commit IN VARCHAR2,
8599 p_validation_level IN NUMBER,
8600 p_inventory_item_id IN NUMBER,
8601 p_organization_id IN NUMBER,
8602 p_from_serial_number IN VARCHAR2,
8603 p_to_serial_number IN VARCHAR2,
8604 p_revision IN VARCHAR2,
8605 p_lot_number IN VARCHAR2,
8606 p_current_status IN NUMBER,
8607 p_serial_status_id IN NUMBER,
8608 p_update_serial_status IN VARCHAR2,
8609 x_return_status OUT NOCOPY VARCHAR2,
8610 x_msg_count OUT NOCOPY NUMBER,
8611 x_msg_data OUT NOCOPY VARCHAR2
8612 )
8613 IS
8614 l_object_id NUMBER;
8615 l_success NUMBER;
8616 l_progress VARCHAR2 ( 10 );
8617 l_debug NUMBER := NVL ( FND_PROFILE.VALUE ( 'INV_DEBUG_TRACE' ), 0 );
8618 BEGIN
8619 IF ( l_debug = 1 ) THEN
8620 print_debug ( 'Enter insert_range_serial: 10:'
8621 || TO_CHAR ( SYSDATE, 'YYYY-MM-DD HH:DD:SS' )
8622 );
8623 END IF;
8624
8625 x_return_status := FND_API.G_RET_STS_SUCCESS;
8626 l_progress := '10';
8627 SAVEPOINT count_insert_range_serial_sp;
8628 l_progress := '20';
8629 inv_serial_number_pub.insert_range_serial ( p_api_version => p_api_version,
8630 p_init_msg_list => p_init_msg_list,
8631 p_commit => p_commit,
8632 p_validation_level => p_validation_level,
8633 p_inventory_item_id => p_inventory_item_id,
8634 p_organization_id => p_organization_id,
8635 p_from_serial_number => p_from_serial_number,
8636 p_to_serial_number => p_to_serial_number,
8637 p_initialization_date => SYSDATE,
8638 p_completion_date => NULL,
8639 p_ship_date => NULL,
8640 p_revision => p_revision,
8641 p_lot_number => p_lot_number,
8642 p_current_locator_id => NULL,
8643 p_subinventory_code => NULL,
8644 p_trx_src_id => NULL,
8645 p_unit_vendor_id => NULL,
8646 p_vendor_lot_number => NULL,
8647 p_vendor_serial_number => NULL,
8648 p_receipt_issue_type => NULL,
8649 p_txn_src_id => NULL,
8650 p_txn_src_name => NULL,
8651 p_txn_src_type_id => NULL,
8652 p_transaction_id => NULL,
8653 p_current_status => p_current_status,
8654 p_parent_item_id => NULL,
8655 p_parent_serial_number => NULL,
8656 p_cost_group_id => NULL,
8657 p_transaction_action_id => NULL,
8658 p_transaction_temp_id => NULL,
8659 p_status_id => NULL,
8660 p_inspection_status => NULL,
8661 x_object_id => l_object_id,
8662 x_return_status => x_return_status,
8663 x_msg_count => x_msg_count,
8664 x_msg_data => x_msg_data
8665 );
8666
8667 IF x_return_status <> fnd_api.g_ret_sts_success THEN
8668 FND_MESSAGE.SET_NAME ( 'INV', 'INV_LOT_COMMIT_FAILURE' );
8669 FND_MSG_PUB.ADD;
8670 RAISE FND_API.G_EXC_ERROR;
8671 END IF;
8672
8673 l_progress := '30';
8674
8675 IF p_update_serial_status = 'TRUE' THEN
8676 l_progress := '40';
8677 inv_material_status_grp.update_status ( p_api_version_number => p_api_version,
8678 p_init_msg_lst => NULL,
8679 x_return_status => x_return_status,
8680 x_msg_count => x_msg_count,
8681 x_msg_data => x_msg_data,
8682 p_update_method => inv_material_status_pub.g_update_method_receive,
8683 p_status_id => p_serial_status_id,
8684 p_organization_id => p_organization_id,
8685 p_inventory_item_id => p_inventory_item_id,
8686 p_sub_code => NULL,
8687 p_locator_id => NULL,
8688 p_lot_number => p_lot_number,
8689 p_serial_number => p_from_serial_number,
8690 p_to_serial_number => p_to_serial_number,
8691 p_object_type => 'S'
8692 );
8693 END IF;
8694
8695 IF x_return_status <> fnd_api.g_ret_sts_success THEN
8696 RAISE FND_API.G_EXC_ERROR;
8697 END IF;
8698
8699 l_progress := '50';
8700 serial_check.inv_mark_serial ( from_serial_number => p_from_serial_number,
8701 to_serial_number => p_to_serial_number,
8702 item_id => p_inventory_item_id,
8703 org_id => p_organization_id,
8704 hdr_id => NULL,
8705 temp_id => NULL,
8706 lot_temp_id => NULL,
8707 success => l_success
8708 );
8709 l_progress := '60';
8710
8711 IF ( l_debug = 1 ) THEN
8712 print_debug ( 'Exit insert_range_serial 90:'
8713 || TO_CHAR ( SYSDATE, 'YYYY-MM-DD HH:DD:SS' )
8714 );
8715 END IF;
8716 EXCEPTION
8717 WHEN FND_API.G_EXC_ERROR THEN
8718 ROLLBACK TO count_insert_range_serial_sp;
8719 x_return_status := fnd_api.g_ret_sts_error;
8720
8721 IF ( l_debug = 1 ) THEN
8722 print_debug ( 'Exitting insert_range_serial - execution error:'
8723 || l_progress
8724 || ' '
8725 || TO_CHAR ( SYSDATE, 'YYYY-MM-DD HH:DD:SS' )
8726 );
8727 END IF;
8728
8729 -- Get message count and data
8730 fnd_msg_pub.count_and_get ( p_encoded => fnd_api.g_false,
8731 p_count => x_msg_count,
8732 p_data => x_msg_data
8733 );
8734 WHEN FND_API.G_EXC_UNEXPECTED_ERROR THEN
8735 ROLLBACK TO count_insert_range_serial_sp;
8736
8737 IF ( l_debug = 1 ) THEN
8738 print_debug ( 'Exitting insert_range_serial - unexpected error:'
8739 || l_progress
8740 || ' '
8741 || TO_CHAR ( SYSDATE, 'YYYY-MM-DD HH:DD:SS' )
8742 );
8743 END IF;
8744
8745 x_return_status := fnd_api.g_ret_sts_unexp_error;
8746 -- Get message count and data
8747 fnd_msg_pub.count_and_get ( p_encoded => fnd_api.g_false,
8748 p_count => x_msg_count,
8749 p_data => x_msg_data
8750 );
8751 WHEN OTHERS THEN
8752 ROLLBACK TO count_insert_range_serial_sp;
8753
8754 IF ( l_debug = 1 ) THEN
8755 print_debug ( 'Exitting insert_range_serial - other exceptions:'
8756 || l_progress
8757 || ' '
8758 || TO_CHAR ( SYSDATE, 'YYYY-MM-DD HH:DD:SS' )
8759 );
8760 END IF;
8761
8762 x_return_status := fnd_api.g_ret_sts_unexp_error;
8763
8764 IF SQLCODE IS NOT NULL THEN
8765 inv_mobile_helper_functions.sql_error ( 'INV_RCV_COMMON_APIS.insert_range_serial',
8766 l_progress,
8767 SQLCODE
8768 );
8769 END IF;
8770
8771 IF fnd_msg_pub.check_msg_level ( fnd_msg_pub.g_msg_lvl_unexp_error ) THEN
8772 fnd_msg_pub.add_exc_msg ( g_pkg_name, 'insert_range_serial' );
8773 END IF;
8774
8775 -- Get message count and data
8776 fnd_msg_pub.count_and_get ( p_encoded => fnd_api.g_false,
8777 p_count => x_msg_count,
8778 p_data => x_msg_data
8779 );
8780 END insert_range_serial;
8781
8782 PROCEDURE get_system_quantity (
8783 p_organization_id IN NUMBER,
8784 p_subinventory IN VARCHAR2,
8785 p_locator_id IN NUMBER,
8786 p_parent_lpn_id IN NUMBER,
8787 p_inventory_item_id IN NUMBER,
8788 p_revision IN VARCHAR2,
8789 p_lot_number IN VARCHAR2,
8790 p_uom_code IN VARCHAR2,
8791 x_system_quantity OUT NOCOPY NUMBER
8792 )
8793 IS
8794 l_primary_uom VARCHAR2 ( 3 );
8795 l_serial_number_control_code NUMBER;
8796 l_progress VARCHAR2 ( 10 );
8797 l_converted_quantity NUMBER;
8798 l_loaded_sys_qty NUMBER; -- bug 2640378
8799 l_debug NUMBER := NVL ( FND_PROFILE.VALUE ( 'INV_DEBUG_TRACE' ), 0 );
8800
8801 /* Bug 4886188 -Added the local variables for the lpn details from wlpn*/
8802 l_lpn_subinv VARCHAR2(10) ;
8803 l_lpn_locator_id NUMBER ;
8804 l_lpn_context NUMBER;
8805 /* End of fix for Bug 4886188 */
8806 BEGIN
8807 IF ( l_debug = 1 ) THEN
8808 print_debug ( '***get_system_quantity***' );
8809 END IF;
8810
8811 -- Initialize the output variable
8812 x_system_quantity := 0;
8813 l_progress := '10';
8814
8815 /*
8816 ****** Fix for bug 4886188
8817 ****** If the Lpn Context is 'Issued Out of Stores' or 'Intransit' or 'Packing Context' or 'Loaded to Dock'
8818 ****** system quantity should be shown as 0. Because, ideally the LPN will not be present in that location.
8819 */
8820
8821 IF ( p_parent_lpn_id IS NOT NULL ) THEN
8822
8823 SELECT NVL ( subinventory_code, '###' ),
8824 NVL ( locator_id, -99 ),
8825 lpn_context
8826 INTO l_lpn_subinv,
8827 l_lpn_locator_id,
8828 l_lpn_context
8829 FROM WMS_LICENSE_PLATE_NUMBERS
8830 WHERE lpn_id = p_parent_lpn_id ;
8831
8832 IF ( l_debug = 1 ) THEN
8833 print_debug ( 'l_lpn_subinv: ===> ' || l_lpn_subinv );
8834 print_debug ( 'l_lpn_locator_id: => ' || l_lpn_locator_id );
8835 print_debug ( 'l_lpn_context: => ' || l_lpn_context );
8836 END IF;
8837
8838 IF l_lpn_context = 8 or l_lpn_context = 9 or l_lpn_context = 4 or l_lpn_context = 6 THEN
8839 IF ( l_debug = 1 ) THEN
8840 print_debug ( 'Returning the system quantity as 0' );
8841 END IF;
8842 g_condition:=TRUE ;
8843 return;
8844 END IF;
8845 END IF;
8846 /* End of fix for bug number 4886188 */
8847
8848
8849
8850 SELECT primary_uom_code,
8851 serial_number_control_code
8852 INTO l_primary_uom,
8853 l_serial_number_control_code
8854 FROM mtl_system_items
8855 WHERE inventory_item_id = p_inventory_item_id
8856 AND organization_id = p_organization_id;
8857
8858 l_progress := '20';
8859
8860 IF ( l_serial_number_control_code IN ( 1, 6 ) ) THEN
8861 IF ( l_debug = 1 ) THEN
8862 print_debug ( 'Non serial controlled item' );
8863 END IF;
8864
8865 IF ( p_parent_lpn_id IS NULL ) THEN
8866 IF ( l_debug = 1 ) THEN
8867 print_debug ( 'LPN ID is null' );
8868 END IF;
8869
8870 SELECT NVL ( SUM ( primary_transaction_quantity ), 0 )
8871 INTO x_system_quantity
8872 FROM MTL_ONHAND_QUANTITIES_DETAIL
8873 WHERE inventory_item_id = p_inventory_item_id
8874 AND organization_id = p_organization_id
8875 AND NVL ( containerized_flag, 2 ) = 2
8876 AND subinventory_code = p_subinventory
8877 AND NVL ( locator_id, -99 ) = NVL ( p_locator_id, -99 )
8878 AND ( NVL ( lot_number, 'XX' ) = NVL ( p_lot_number, 'XX' )
8879 OR p_lot_number IS NULL
8880 ) -- Lot number might not have been entered yet
8881 AND NVL ( revision, 'XXX' ) = NVL ( p_revision, 'XXX' );
8882
8883 SELECT NVL ( SUM ( quantity ), 0 )
8884 INTO l_loaded_sys_qty
8885 FROM WMS_LOADED_QUANTITIES_V
8886 WHERE inventory_item_id = p_inventory_item_id
8887 AND organization_id = p_organization_id
8888 AND NVL ( containerized_flag, 2 ) = 2
8889 AND subinventory_code = p_subinventory
8890 AND NVL ( locator_id, -99 ) = NVL ( p_locator_id, -99 )
8891 AND ( NVL ( lot_number, 'XX' ) = NVL ( p_lot_number, 'XX' )
8892 OR p_lot_number IS NULL
8893 )
8894 -- Lot number might not have been entered yet
8895 AND NVL ( revision, 'XXX' ) = NVL ( p_revision, 'XXX' )
8896 AND qty_type = 'LOADED'
8897 AND lpn_id IS NULL
8898 AND content_lpn_id IS NULL; -- bug 2640378
8899
8900 IF ( l_debug = 1 ) THEN
8901 print_debug ( 'Loaded qty is ' || l_loaded_sys_qty );
8902 END IF;
8903
8904 IF l_loaded_sys_qty > 0 THEN
8905 x_system_quantity := x_system_quantity - l_loaded_sys_qty;
8906 END IF; -- bug 2640378
8907 ELSE
8908 IF ( l_debug = 1 ) THEN
8909 print_debug ( 'LPN ID is not null: ' || p_parent_lpn_id );
8910 END IF;
8911
8912 BEGIN
8913 --For R12 we need to consider primary_quantity instead of quantity from WLC (bug 6833992)
8914 SELECT nvl(sum(primary_quantity),0) --BUG3026540
8915 INTO x_system_quantity
8916 FROM WMS_LPN_CONTENTS
8917 WHERE parent_lpn_id = p_parent_lpn_id
8918 AND organization_id = p_organization_id
8919 AND inventory_item_id = p_inventory_item_id
8920 AND ( NVL ( lot_number, 'XX' ) =
8921 NVL ( p_lot_number, 'XX' )
8922 OR p_lot_number IS NULL
8923 )
8924 -- Lot number might not have been entered yet
8925 AND NVL ( revision, 'XXX' ) = NVL ( p_revision, 'XXX' )
8926 AND NVL ( serial_summary_entry, 2 ) = 2;
8927
8928 SELECT NVL ( SUM ( quantity ), 0 )
8929 INTO l_loaded_sys_qty
8930 FROM wms_loaded_quantities_v
8931 WHERE NVL ( lpn_id, NVL ( content_lpn_id, -1 ) ) = p_parent_lpn_id
8932 and inventory_item_id = p_inventory_item_id
8933 and organization_id = p_organization_id;
8934
8935 IF l_loaded_sys_qty > 0 THEN
8936 x_system_quantity := x_system_quantity - l_loaded_sys_qty;
8937 END IF;
8938 -- bug 2640378 does the counter need to know the missing quantity ?
8939
8940 EXCEPTION
8941 WHEN NO_DATA_FOUND THEN
8942 x_system_quantity := 0;
8943 END;
8944 END IF;
8945 ELSIF ( l_serial_number_control_code IN ( 2, 5 ) ) THEN
8946 IF ( l_debug = 1 ) THEN
8947 print_debug ( 'Serial controlled item' );
8948 END IF;
8949
8950 IF ( p_parent_lpn_id IS NULL ) THEN
8951 IF ( l_debug = 1 ) THEN
8952 print_debug ( 'LPN ID is null' );
8953 END IF;
8954
8955 SELECT NVL ( SUM ( DECODE ( current_status, 3, 1, 0 ) ), 0 )
8956 INTO x_system_quantity
8957 FROM mtl_serial_numbers
8958 WHERE lpn_id IS NULL
8959 AND inventory_item_id = p_inventory_item_id
8960 AND current_organization_id = p_organization_id
8961 AND current_subinventory_code = p_subinventory
8962 AND NVL ( current_locator_id, -99 ) = NVL ( p_locator_id, -99 )
8963 AND ( NVL ( lot_number, 'XX' ) = NVL ( p_lot_number, 'XX' )
8964 OR p_lot_number IS NULL
8965 )
8966 -- Lot number might not have been entered yet
8967 AND NVL ( revision, 'XXX' ) = NVL ( p_revision, 'XXX' );
8968
8969 select count(*)
8970 into l_loaded_sys_qty
8971 from mtl_serial_numbers_temp msnt, wms_loaded_quantities_v wl
8972 where ((msnt.transaction_temp_id = wl.transaction_temp_id
8973 and wl.lot_number is null) or
8974 (msnt.transaction_temp_id = wl.serial_transaction_temp_id
8975 and wl.lot_number is not null)
8976 )
8977 and wl.containerized_flag = 2
8978 and wl.inventory_item_id = p_inventory_item_id
8979 and wl.subinventory_code = p_subinventory
8980 and nvl(wl.locator_id,-99) = nvl(p_locator_id,-99)
8981 and (nvl(wl.lot_number,'@@@') = nvl(p_lot_number,'@@@')
8982 or p_lot_number is null)
8983 and nvl(wl.revision,'##') = nvl(p_revision,'##');
8984
8985 IF l_loaded_sys_qty > 0 THEN
8986 x_system_quantity := x_system_quantity - l_loaded_sys_qty;
8987 END IF;
8988 ELSE
8989 IF ( l_debug = 1 ) THEN
8990 print_debug ( 'LPN ID is not null: ' || p_parent_lpn_id );
8991 END IF;
8992
8993 SELECT COUNT ( * )
8994 INTO x_system_quantity
8995 FROM mtl_serial_numbers
8996 WHERE lpn_id = p_parent_lpn_id
8997 AND inventory_item_id = p_inventory_item_id
8998 AND current_organization_id = p_organization_id
8999 AND ( NVL ( lot_number, 'XX' ) = NVL ( p_lot_number, 'XX' )
9000 OR p_lot_number IS NULL
9001 )
9002 -- Lot number might not have been entered yet
9003 AND NVL ( revision, 'XXX' ) = NVL ( p_revision, 'XXX' );
9004
9005 select distinct wl.quantity
9006 into l_loaded_sys_qty
9007 from mtl_serial_numbers msn, wms_loaded_quantities_v wl
9008 where msn.lpn_id = nvl(wl.content_lpn_id,nvl(wl.lpn_id,-1))
9009 and wl.containerized_flag = 1
9010 and msn.inventory_item_id = wl.inventory_item_id
9011 and msn.current_organization_id = wl.ORGANIZATION_ID
9012 and wl.inventory_item_id = p_inventory_item_id
9013 and wl.organization_id = p_organization_id
9014 and msn.lpn_id = p_parent_lpn_id
9015 and (nvl(msn.lot_number,'@@@') = nvl(wl.lot_number,'@@@') or
9016 p_lot_number is null)
9017 AND NVL ( wl.revision, 'XXX' ) = NVL ( p_revision, 'XXX' );
9018
9019 IF l_loaded_sys_qty > 0 THEN
9020 x_system_quantity := x_system_quantity - l_loaded_sys_qty;
9021 END IF;
9022 END IF;
9023 END IF;
9024
9025 l_progress := '30';
9026 l_converted_quantity :=
9027 inv_convert.inv_um_convert ( p_inventory_item_id,
9028 5,
9029 x_system_quantity,
9030 l_primary_uom,
9031 p_uom_code,
9032 NULL,
9033 NULL
9034 );
9035 l_progress := '40';
9036 x_system_quantity := l_converted_quantity;
9037 EXCEPTION
9038 WHEN OTHERS THEN
9039 IF ( l_debug = 1 ) THEN
9040 print_debug ( 'Exiting get_system_quantity - other exceptions:'
9041 || l_progress
9042 || ' '
9043 || TO_CHAR ( SYSDATE, 'YYYY-MM-DD HH:DD:SS' )
9044 );
9045 END IF;
9046 END get_system_quantity;
9047
9048 PROCEDURE clean_up_tasks (
9049 p_transaction_temp_id IN NUMBER
9050 )
9051 IS
9052 l_employee_id NUMBER;
9053 l_progress VARCHAR2 ( 10 );
9054 l_task_temp_id NUMBER;
9055
9056 CURSOR completed_tasks_cursor
9057 IS
9058 SELECT wdt.transaction_temp_id
9059 FROM wms_dispatched_tasks wdt
9060 WHERE wdt.person_id = l_employee_id
9061 AND wdt.task_type = 3
9062 AND NOT EXISTS (
9063 SELECT 'ACTIVE_TASK'
9064 FROM wms_dispatchable_tasks_v
9065 WHERE wms_task_type_id = 3
9066 AND task_id = wdt.transaction_temp_id );
9067
9068 l_debug NUMBER := NVL ( FND_PROFILE.VALUE ( 'INV_DEBUG_TRACE' ), 0 );
9069 BEGIN
9070 IF ( l_debug = 1 ) THEN
9071 print_debug ( '***Calling clean_up_tasks***' );
9072 END IF;
9073
9074 -- Set the savepoint first
9075 SAVEPOINT clean_up_tasks_sp;
9076 l_progress := '10';
9077
9078 -- Get the employee ID first for the person that performed the task
9079 SELECT DISTINCT NVL ( person_id, -999 )
9080 INTO l_employee_id
9081 FROM wms_dispatched_tasks_history
9082 WHERE transaction_id = p_transaction_temp_id AND task_type = 3;
9083
9084 IF ( l_debug = 1 ) THEN
9085 print_debug ( 'The employee ID is: ' || l_employee_id );
9086 END IF;
9087
9088 IF ( l_employee_id = -999 ) THEN
9089 IF ( l_debug = 1 ) THEN
9090 print_debug ( 'The person ID for the completed task is null' );
9091 END IF;
9092
9093 RAISE FND_API.G_EXC_ERROR;
9094 END IF;
9095
9096 l_progress := '20';
9097
9098 FOR v_completed_task IN completed_tasks_cursor
9099 LOOP
9100 l_task_temp_id := v_completed_task.transaction_temp_id;
9101
9102 IF ( l_debug = 1 ) THEN
9103 print_debug ( 'Cleaning up task with temp id: ' || l_task_temp_id );
9104 END IF;
9105
9106 l_progress := '30';
9107
9108 -- Insert a record into the tasks history table
9109 IF ( l_debug = 1 ) THEN
9110 print_debug ( 'Inserting record into tasks history table' );
9111 END IF;
9112
9113 INSERT INTO WMS_DISPATCHED_TASKS_HISTORY
9114 ( task_id,
9115 transaction_id,
9116 organization_id,
9117 user_task_type,
9118 person_id,
9119 effective_start_date,
9120 effective_end_date,
9121 equipment_id,
9122 equipment_instance,
9123 person_resource_id,
9124 machine_resource_id,
9125 status,
9126 dispatched_time,
9127 loaded_time,
9128 drop_off_time,
9129 last_update_date,
9130 last_updated_by,
9131 creation_date,
9132 created_by,
9133 last_update_login,
9134 attribute_category,
9135 attribute1,
9136 attribute2,
9137 attribute3,
9138 attribute4,
9139 attribute5,
9140 attribute6,
9141 attribute7,
9142 attribute8,
9143 attribute9,
9144 attribute10,
9145 attribute11,
9146 attribute12,
9147 attribute13,
9148 attribute14,
9149 attribute15,
9150 task_type,
9151 priority,
9152 task_group_id
9153 )
9154 SELECT task_id,
9155 transaction_temp_id,
9156 organization_id,
9157 user_task_type,
9158 person_id,
9159 effective_start_date,
9160 effective_end_date,
9161 equipment_id,
9162 equipment_instance,
9163 person_resource_id,
9164 machine_resource_id,
9165 6,
9166 dispatched_time,
9167 loaded_time,
9168 drop_off_time,
9169 last_update_date,
9170 last_updated_by,
9171 creation_date,
9172 created_by,
9173 last_update_login,
9174 attribute_category,
9175 attribute1,
9176 attribute2,
9177 attribute3,
9178 attribute4,
9179 attribute5,
9180 attribute6,
9181 attribute7,
9182 attribute8,
9183 attribute9,
9184 attribute10,
9185 attribute11,
9186 attribute12,
9187 attribute13,
9188 attribute14,
9189 attribute15,
9190 task_type,
9191 priority,
9192 task_group_id
9193 FROM WMS_DISPATCHED_TASKS
9194 WHERE TRANSACTION_TEMP_ID = l_task_temp_id AND TASK_TYPE = 3;
9195
9196 l_progress := '40';
9197
9198 -- Now delete the completed task from the dispatched tasks table
9199 IF ( l_debug = 1 ) THEN
9200 print_debug ( 'Deleting the record from the dispatched tasks table'
9201 );
9202 END IF;
9203
9204 DELETE FROM WMS_DISPATCHED_TASKS
9205 WHERE TRANSACTION_TEMP_ID = l_task_temp_id AND TASK_TYPE = 3;
9206 END LOOP;
9207
9208 l_progress := '50';
9209
9210 IF ( l_debug = 1 ) THEN
9211 print_debug ( '***End of clean_up_tasks***' );
9212 END IF;
9213 EXCEPTION
9214 WHEN FND_API.G_EXC_ERROR THEN
9215 ROLLBACK TO clean_up_tasks_sp;
9216
9217 IF ( l_debug = 1 ) THEN
9218 print_debug ( 'Exiting clean_up_tasks - execution error:'
9219 || l_progress
9220 || ' '
9221 || TO_CHAR ( SYSDATE, 'YYYY-MM-DD HH:DD:SS' )
9222 );
9223 END IF;
9224 WHEN FND_API.G_EXC_UNEXPECTED_ERROR THEN
9225 ROLLBACK TO clean_up_tasks_sp;
9226
9227 IF ( l_debug = 1 ) THEN
9228 print_debug ( 'Exiting clean_up_tasks - unexpected error:'
9229 || l_progress
9230 || ' '
9231 || TO_CHAR ( SYSDATE, 'YYYY-MM-DD HH:DD:SS' )
9232 );
9233 END IF;
9234 WHEN OTHERS THEN
9235 ROLLBACK TO clean_up_tasks_sp;
9236
9237 IF ( l_debug = 1 ) THEN
9238 print_debug ( 'Exitting clean_up_tasks - other exceptions:'
9239 || l_progress
9240 || ' '
9241 || TO_CHAR ( SYSDATE, 'YYYY-MM-DD HH:DD:SS' )
9242 );
9243 END IF;
9244 END clean_up_tasks;
9245 END INV_CYC_LOVS;