DBA Data[Home] [Help]

PACKAGE BODY: APPS.INV_PHY_INV_LOVS

Source


1 PACKAGE BODY INV_PHY_INV_LOVS AS
2 /* $Header: INVPINLB.pls 120.7.12010000.2 2008/07/29 13:42:44 ptkumar ship $ */
3 
4 --  Global constant holding the package name
5 G_PKG_NAME               CONSTANT VARCHAR2(30) := 'INV_PHY_INV_LOVS';
6 
7 PROCEDURE print_debug(p_err_msg VARCHAR2)
8 IS
9     l_debug number := NVL(FND_PROFILE.VALUE('INV_DEBUG_TRACE'),0);
10 BEGIN
11 
12    IF (l_debug = 1) THEN
13       inv_mobile_helper_functions.tracelog
14      (p_err_msg   =>  p_err_msg,
15       p_module    =>  'INV_PHY_INV_LOVS',
16       p_level     =>  4);
17    END IF;
18 
19 --   dbms_output.put_line(p_err_msg);
20 END print_debug;
21 
22 
23 --      Name: GET_PHY_INV_LOV
24 --
25 --      Input parameters:
26 --       p_lpn   which restricts LOV SQL to the user input text
27 --       p_organization_id   Organization ID
28 --
29 --      Output parameters:
30 --       x_phy_inv_lov      returns LOV rows as reference cursor
31 --
32 --      Functions: This API returns valid physical inventories
33 --
34 PROCEDURE get_phy_inv_lov
35   (x_phy_inv_lov       OUT  NOCOPY  t_genref,
36    p_phy_inv           IN           VARCHAR2,
37    p_organization_id   IN           NUMBER)
38 
39 IS
40 
41     l_debug number := NVL(FND_PROFILE.VALUE('INV_DEBUG_TRACE'),0);
42 BEGIN
43    OPEN x_phy_inv_lov FOR
44      SELECT physical_inventory_name,
45      physical_inventory_id,
46      description,
47      freeze_date,
48      adjustments_posted,
49      approval_required,
50      cost_variance_neg,
51      cost_variance_pos,
52      approval_tolerance_neg,
53      approval_tolerance_pos,
54      all_subinventories_flag,
55      dynamic_tag_entry_flag
56      FROM mtl_physical_inventories_v
57      WHERE organization_id = p_organization_id
58      AND snapshot_complete = 1
59      AND adjustments_posted <> 1
60      AND physical_inventory_name LIKE (p_phy_inv)
61      ORDER BY physical_inventory_name;
62 END get_phy_inv_lov;
63 
64 
65 --      Name: GET_SERIAL_COUNT_NUMBER
66 --
67 --      Input parameters:
68 --       p_physical_inventory_id    Physical Inventory ID
69 --       p_organization_id          Organization ID
70 --       p_serial_number            Serial Number
71 --       p_inventory_item_id        Inventory Item ID
72 --
73 --      Output parameters:
74 --       x_number            Returns the serial count for the number
75 --                           of physical tags with that particular
76 --                           serial number that has already been counted
77 --                           as present and existing in a given location.
78 --       x_serial_in_scope   Returns 1 if the serial is within the scope
79 --                           of the physical inventory.  Otherwise it will
80 --                           return 0.
81 --
82 --      Functions: This API returns the count of physical tag records
83 --                 for the given serial number inputted.
84 --                 It has also been overloaded so that it will also
85 --                 check if the inputted serial is within the scope
86 --                 of the physical inventory, i.e. exists in a subinventory
87 --                 for which the physical inventory covers
88 --
89 PROCEDURE get_serial_count_number
90   (p_physical_inventory_id   IN          NUMBER            ,
91    p_organization_id         IN          NUMBER            ,
92    p_serial_number           IN          VARCHAR2          ,
93    p_inventory_item_id       IN          NUMBER            ,
94    x_number                  OUT NOCOPY  NUMBER            ,
95    x_serial_in_scope         OUT NOCOPY  NUMBER)
96 IS
97 l_all_sub_flag               NUMBER;
98 l_serial_sub                 VARCHAR2(10);
99 
100     l_debug number := NVL(FND_PROFILE.VALUE('INV_DEBUG_TRACE'),0);
101 BEGIN
102    IF (l_debug = 1) THEN
103       print_debug('***Calling get_serial_count_number***');
104    END IF;
105    -- First get the serial count number to see if the serial has
106    -- already been found for this physical inventory
107    SELECT COUNT(*)
108      INTO x_number
109      FROM mtl_physical_inventory_tags
110      WHERE physical_inventory_id = p_physical_inventory_id
111      AND organization_id = p_organization_id
112      AND serial_num = p_serial_number
113      AND inventory_item_id = p_inventory_item_id
114      AND tag_quantity IS NOT NULL
115      AND tag_quantity <> 0
116      AND void_flag = 2
117      AND adjustment_id IN
118      (SELECT adjustment_id
119       FROM mtl_physical_adjustments
120       WHERE physical_inventory_id = p_physical_inventory_id
121       AND organization_id = p_organization_id
122       AND approval_status IS NULL);
123 
124       -- Now see if the serial is within the scope of the physical
125       -- inventory
126       SELECT all_subinventories_flag
127         INTO l_all_sub_flag
128         FROM mtl_physical_inventories
129         WHERE physical_inventory_id = p_physical_inventory_id
130         AND organization_id = p_organization_id;
131       IF (l_debug = 1) THEN
132          print_debug('All subinventories flag: ' || l_all_sub_flag);
133       END IF;
134 
135       IF (l_all_sub_flag = 1) THEN
136          -- All subinventories are included for this physical inventory
137          -- so the serial should be within the scope
138          x_serial_in_scope := 1;
139        ELSE
140          -- Get the current sub where the serial resides according to the system
141          SELECT NVL(current_subinventory_code, '@@@@@')
142            INTO l_serial_sub
143            FROM mtl_serial_numbers
144            WHERE inventory_item_id = p_inventory_item_id
145            AND serial_number = p_serial_number
146            AND current_organization_id = p_organization_id;
147          IF (l_debug = 1) THEN
148          print_debug('Current subinventory of serial: ' || l_serial_sub);
149          END IF;
150          -- See if the serial's subinventory is one of the subinventories
151          -- associated with the physical inventory
152          SELECT COUNT(*)
153            INTO x_serial_in_scope
154            FROM mtl_physical_subinventories
155            WHERE organization_id = p_organization_id
156            AND physical_inventory_id = p_physical_inventory_id
157            AND subinventory = l_serial_sub;
158       END IF;
159       IF (l_debug = 1) THEN
160          print_debug('Serial count number: ' || x_number);
161          print_debug('Serial in scope: ' || x_serial_in_scope);
162       END IF;
163 
164 END get_serial_count_number;
165 
166 
167 PROCEDURE process_tag
168   (p_physical_inventory_id   IN    NUMBER,
169    p_organization_id         IN    NUMBER,
170    p_subinventory            IN    VARCHAR2,
171    p_locator_id              IN    NUMBER := NULL,
172    p_parent_lpn_id           IN    NUMBER := NULL,
173    p_inventory_item_id       IN    NUMBER,
174    p_revision                IN    VARCHAR2 := NULL,
175    p_lot_number              IN    VARCHAR2 := NULL,
176    p_from_serial_number      IN    VARCHAR2 := NULL,
177    p_to_serial_number        IN    VARCHAR2 := NULL,
178    p_tag_quantity            IN    NUMBER,
179    p_tag_uom                 IN    VARCHAR2,
180    p_dynamic_tag_entry_flag  IN    NUMBER,
181    p_user_id                 IN    NUMBER,
182    p_cost_group_id           IN    NUMBER := NULL
183    --INVCONV, NSRIVAST, START
184    ,p_tag_sec_uom            IN    VARCHAR2 := NULL
185    ,p_tag_sec_quantity       IN    NUMBER   := NULL
186    --INVCONV, NSRIVAST, END
187    )
188 IS
189 l_current_serial         VARCHAR2(30);
190 CURSOR tag_entry IS
191    SELECT *
192      FROM mtl_physical_inventory_tags
193      WHERE physical_inventory_id = p_physical_inventory_id
194      AND organization_id = p_organization_id
195      AND subinventory = p_subinventory
196      AND NVL(locator_id, -99999) = NVL(p_locator_id, -99999)
197      AND NVL(parent_lpn_id, -99999) = NVL(p_parent_lpn_id, -99999)
198      AND inventory_item_id = p_inventory_item_id
199      AND NVL(revision, '@@@@@') = NVL(p_revision, '@@@@@')
200      AND NVL(lot_number, '@@@@@') = NVL(p_lot_number, '@@@@@')
201      AND NVL(serial_num, '@@@@@') = NVL(l_current_serial, '@@@@@')
202      -- AND NVL(cost_group_id, -99999) = NVL(p_cost_group_id, -99999)
203      AND void_flag = 2
204      AND adjustment_id IN
205      (SELECT adjustment_id
206       FROM mtl_physical_adjustments
207       WHERE physical_inventory_id = p_physical_inventory_id
208       AND organization_id = p_organization_id
209       AND approval_status IS NULL);
210 CURSOR discrepant_serial_cursor IS
211    SELECT *
212      FROM mtl_physical_inventory_tags
213      WHERE physical_inventory_id = p_physical_inventory_id
214      AND organization_id = p_organization_id
215      AND NVL(parent_lpn_id, -99999) = NVL(p_parent_lpn_id, -99999)
216      AND inventory_item_id = p_inventory_item_id
217      AND NVL(revision, '@@@@@') = NVL(p_revision, '@@@@@')
218      AND NVL(lot_number, '@@@@@') = NVL(p_lot_number, '@@@@@')
219      AND NVL(serial_num, '@@@@@') = NVL(l_current_serial, '@@@@@')
220      -- AND NVL(cost_group_id, -99999) = NVL(p_cost_group_id, -99999)
221      AND void_flag = 2
222      AND adjustment_id IN
223      (SELECT adjustment_id
224       FROM mtl_physical_adjustments
225       WHERE physical_inventory_id = p_physical_inventory_id
226       AND organization_id = p_organization_id
227       AND approval_status IS NULL);
228 tag_record               MTL_PHYSICAL_INVENTORY_TAGS%ROWTYPE;
229 l_prefix                 VARCHAR2(30);
230 l_quantity               NUMBER;
231 l_from_number            NUMBER;
232 l_to_number              NUMBER;
233 l_errorcode              NUMBER;
234 l_length                 NUMBER;
235 l_padded_length          NUMBER;
236 l_current_number         NUMBER;
237 l_adjustment_id          NUMBER;
238 l_cost_group_id          NUMBER;
239 
240     l_debug number := NVL(FND_PROFILE.VALUE('INV_DEBUG_TRACE'),0);
241 BEGIN
242    IF (l_debug = 1) THEN
243       print_debug('***Calling process_tag with the following parameters***');
244       print_debug('p_physical_inventory_id: ---> ' || p_physical_inventory_id);
245       print_debug('p_organization_id: ---------> ' || p_organization_id);
246       print_debug('p_subinventory: ------------> ' || p_subinventory);
247       print_debug('p_locator_id: --------------> ' || p_locator_id);
248       print_debug('p_parent_lpn_id: -----------> ' || p_parent_lpn_id);
249       print_debug('p_inventory_item_id: -------> ' || p_inventory_item_id);
250       print_debug('p_revision: ----------------> ' || p_revision);
251       print_debug('p_lot_number: --------------> ' || p_lot_number);
252       print_debug('p_from_serial_number: ------> ' || p_from_serial_number);
253       print_debug('p_to_serial_number: --------> ' || p_to_serial_number);
254       print_debug('p_tag_quantity: ------------> ' || p_tag_quantity);
255       print_debug('p_tag_uom: -----------------> ' || p_tag_uom);
256       print_debug('p_dynamic_tag_entry_flag: --> ' || p_dynamic_tag_entry_flag);
257       print_debug('p_user_id: -----------------> ' || p_user_id);
258       print_debug('p_cost_group_id: -----------> ' || p_cost_group_id);
259    END IF;
260 
261    -- First check if the tag item is a serial controlled item
262    IF ((p_from_serial_number IS NOT NULL) AND
263        (p_to_serial_number IS NOT NULL)) THEN
264       IF (l_debug = 1) THEN
265          print_debug('Serial controlled item');
266       END IF;
267 
268       -- Call this API to parse the serial numbers into prefixes and numbers.
269       -- Only call this procedure if the from and to serial numbers differ
270       IF (p_from_serial_number <> p_to_serial_number) THEN
271          IF (NOT MTL_Serial_Check.inv_serial_info
272              ( p_from_serial_number  =>  p_from_serial_number,
273                p_to_serial_number    =>  p_to_serial_number,
274                x_prefix              =>  l_prefix,
275                x_quantity            =>  l_quantity,
276                x_from_number         =>  l_from_number,
277                x_to_number           =>  l_to_number,
278                x_errorcode           =>  l_errorcode)) THEN
279             FND_MESSAGE.SET_NAME('WMS', 'WMS_CONT_INVALID_SER');
280             FND_MSG_PUB.ADD;
281             RAISE FND_API.G_EXC_ERROR;
282          END IF;
283       END IF;
284 
285       -- Check that in the case of a range of serial numbers, that the
286       -- inputted p_tag_quantity equals the amount of items in the serial
287       -- range.  Do this check only if a range of serials is submitted
288       IF (p_from_serial_number <> p_to_serial_number) THEN
289          IF (p_tag_quantity <> l_quantity) THEN
290             FND_MESSAGE.SET_NAME('WMS', 'WMS_CONT_INVALID_X_QTY');
291             FND_MSG_PUB.ADD;
292             RAISE FND_API.G_EXC_ERROR;
293          END IF;
294       END IF;
295 
296       -- Get the serial number length.
297       -- Note that the from and to serial numbers must be of the same length.
298       l_length := length(p_from_serial_number);
299 
300       -- Initialize the current pointer variables
301       l_current_serial := p_from_serial_number;
302       IF (l_from_number IS NOT NULL) THEN
303          l_current_number := l_from_number;
304        ELSE
305          l_current_number := 0;
306       END IF;
307 
308       LOOP
309          -- For each serial number check if a tag entry for it already
310          -- exists or not
311          OPEN tag_entry;
312          FETCH tag_entry INTO tag_record;
313          IF (tag_entry%FOUND) THEN
314             -- Entry already exists so update the row
315             -- Check if an adjustment ID for this tag already exists or not
316             IF (tag_record.adjustment_id IS NULL) THEN
317                find_existing_adjustment
318                  ( p_physical_inventory_id   =>  p_physical_inventory_id,
319                    p_organization_id         =>  p_organization_id,
320                    p_subinventory            =>  p_subinventory,
321                    p_locator_id              =>  p_locator_id,
322                    p_parent_lpn_id           =>  p_parent_lpn_id,
323                    p_inventory_item_id       =>  p_inventory_item_id,
324                    p_revision                =>  p_revision,
325                    p_lot_number              =>  p_lot_number,
326                    p_serial_number           =>  l_current_serial,
327                    p_user_id                 =>  p_user_id,
328                    p_cost_group_id           =>  tag_record.cost_group_id,
329                    x_adjustment_id           =>  l_adjustment_id
330                    );
331              ELSE
332                l_adjustment_id := tag_record.adjustment_id;
333             END IF;
334             update_row( p_tag_id                  =>  tag_record.tag_id,
335                         p_physical_inventory_id   =>  p_physical_inventory_id,
336                         p_organization_id         =>  p_organization_id,
337                         p_subinventory            =>  p_subinventory,
338                         p_locator_id              =>  p_locator_id,
339                         p_parent_lpn_id           =>  p_parent_lpn_id,
340                         p_inventory_item_id       =>  p_inventory_item_id,
341                         p_revision                =>  p_revision,
342                         p_lot_number              =>  p_lot_number,
343                         p_serial_number           =>  l_current_serial,
344                         p_tag_quantity            =>  p_tag_quantity,
345                         p_tag_uom                 =>  p_tag_uom,
346                         p_user_id                 =>  p_user_id,
347                         p_cost_group_id           =>  tag_record.cost_group_id,
348                         p_adjustment_id           =>  l_adjustment_id
349                         );
350             update_adjustment
351               (p_adjustment_id           =>  l_adjustment_id,
352                p_physical_inventory_id   =>  p_physical_inventory_id,
353                p_organization_id         =>  p_organization_id,
354                p_user_id                 =>  p_user_id
355                );
356           ELSE
357             -- Entry does not exist so insert the row
358             IF (p_dynamic_tag_entry_flag = 1) THEN
359                IF (l_debug = 1) THEN
360                print_debug('Dynamic serial tag entry to be inserted');
361                END IF;
362                -- Dynamic tag entries are allowed
363 
364                -- First check to see if a tag exists for this serial number
365                -- already if the serial is found in a discrepant location.
366                -- If a tag already exists, we want to update the tag and
367                -- adjustment record to signify that we have counted it
368                -- already, although it is considered as missing.
369                OPEN discrepant_serial_cursor;
370                FETCH discrepant_serial_cursor INTO tag_record;
371                IF (discrepant_serial_cursor%FOUND) THEN
372                   -- Entry for discrepant serial exists so update the row
373                   -- Check if an adjustment ID for this tag already exists or not
374                   IF (l_debug = 1) THEN
375                   print_debug('Discrepant serial so updating the original tag');
376                   END IF;
377                   IF (tag_record.adjustment_id IS NULL) THEN
378                      find_existing_adjustment
379                        ( p_physical_inventory_id   =>  p_physical_inventory_id,
380                          p_organization_id         =>  p_organization_id,
381                          p_subinventory            =>  tag_record.subinventory,
382                          p_locator_id              =>  tag_record.locator_id,
383                          p_parent_lpn_id           =>  p_parent_lpn_id,
384                          p_inventory_item_id       =>  p_inventory_item_id,
385                          p_revision                =>  p_revision,
386                          p_lot_number              =>  p_lot_number,
387                          p_serial_number           =>  l_current_serial,
388                          p_user_id                 =>  p_user_id,
389                          p_cost_group_id           =>  tag_record.cost_group_id,
390                          x_adjustment_id           =>  l_adjustment_id
391                          );
392                    ELSE
393                      l_adjustment_id := tag_record.adjustment_id;
394                   END IF;
395                   update_row( p_tag_id                  =>  tag_record.tag_id,
396                               p_physical_inventory_id   =>  p_physical_inventory_id,
397                               p_organization_id         =>  p_organization_id,
398                               p_subinventory            =>  tag_record.subinventory,
399                               p_locator_id              =>  tag_record.locator_id,
400                               p_parent_lpn_id           =>  p_parent_lpn_id,
401                               p_inventory_item_id       =>  p_inventory_item_id,
402                               p_revision                =>  p_revision,
403                               p_lot_number              =>  p_lot_number,
404                               p_serial_number           =>  l_current_serial,
405                               p_tag_quantity            =>  0,
406                               p_tag_uom                 =>  p_tag_uom,
407                               p_user_id                 =>  p_user_id,
408                               p_cost_group_id           =>  tag_record.cost_group_id,
409                               p_adjustment_id           =>  l_adjustment_id
410                               );
411                   update_adjustment
412                     (p_adjustment_id           =>  l_adjustment_id,
413                      p_physical_inventory_id   =>  p_physical_inventory_id,
414                      p_organization_id         =>  p_organization_id,
415                      p_user_id                 =>  p_user_id
416                      );
417                END IF;
418                CLOSE discrepant_serial_cursor;
419 
420                -- Now deal with inserting the new dynamic tag entry
421                -- Get the cost group ID for this entry
422                inv_cyc_lovs.get_cost_group_id
423                  (p_organization_id        =>  p_organization_id,
424                   p_subinventory           =>  p_subinventory,
425                   p_locator_id             =>  p_locator_id,
426                   p_parent_lpn_id          =>  p_parent_lpn_id,
427                   p_inventory_item_id      =>  p_inventory_item_id,
428                   p_revision               =>  p_revision,
429                   p_lot_number             =>  p_lot_number,
430                   p_serial_number          =>  l_current_serial,
431                   x_out                    =>  l_cost_group_id);
432                -- Bug# 2607187
433                -- Do not get the default cost group ID.  If the item is
434                -- new and does not exist in onhand, pass a NULL value
435                -- for the cost group ID.  The transaction manager will
436                -- call the cost group rules engine for that if the
437                -- cost group ID passed into MMTT is null.
438                IF (l_cost_group_id = -999) THEN
439                   l_cost_group_id := NULL;
440                END IF;
441                -- Get the default cost group ID based on the given org
442                -- and sub if cost group ID was not retrieved successfully
443                /*IF (l_cost_group_id = -999) THEN
444                   inv_cyc_lovs.get_default_cost_group_id
445                     (p_organization_id        =>  p_organization_id,
446                      p_subinventory           =>  p_subinventory,
447                      x_out                    =>  l_cost_group_id);
448                END IF;
449                -- Default the cost group ID to 1 if nothing can be found
450                IF (l_cost_group_id = -999) THEN
451                   l_cost_group_id := 1;
452                END IF;*/
453 
454                -- Generate a new adjustment ID for this tag
455                find_existing_adjustment
456                  ( p_physical_inventory_id   =>  p_physical_inventory_id,
457                    p_organization_id         =>  p_organization_id,
458                    p_subinventory            =>  p_subinventory,
459                    p_locator_id              =>  p_locator_id,
460                    p_parent_lpn_id           =>  p_parent_lpn_id,
461                    p_inventory_item_id       =>  p_inventory_item_id,
462                    p_revision                =>  p_revision,
463                    p_lot_number              =>  p_lot_number,
464                    p_serial_number           =>  l_current_serial,
465                    p_user_id                 =>  p_user_id,
466                    p_cost_group_id           =>  l_cost_group_id,
467                    x_adjustment_id           =>  l_adjustment_id
468                    );
469                insert_row( p_physical_inventory_id   =>  p_physical_inventory_id,
470                            p_organization_id         =>  p_organization_id,
471                            p_subinventory            =>  p_subinventory,
472                            p_locator_id              =>  p_locator_id,
473                            p_parent_lpn_id           =>  p_parent_lpn_id,
474                            p_inventory_item_id       =>  p_inventory_item_id,
475                            p_revision                =>  p_revision,
476                            p_lot_number              =>  p_lot_number,
477                            p_serial_number           =>  l_current_serial,
478                            p_tag_quantity            =>  p_tag_quantity,
479                            p_tag_uom                 =>  p_tag_uom,
480                            p_user_id                 =>  p_user_id,
481                            p_cost_group_id           =>  l_cost_group_id,
482                            p_adjustment_id           =>  l_adjustment_id
483                            );
484                update_adjustment
485                  (p_adjustment_id           =>  l_adjustment_id,
486                   p_physical_inventory_id   =>  p_physical_inventory_id,
487                   p_organization_id         =>  p_organization_id,
488                   p_user_id                 =>  p_user_id
489                   );
490              ELSE
491                -- Dynamic tag entries are not allowed
492                -- This shouldn't happen if the mobile form's LOV
493                -- statements are correctly set
494                FND_MESSAGE.SET_NAME('INV','INV_NO_DYNAMIC_TAGS');
495                FND_MSG_PUB.ADD;
496                --RAISE FND_API.G_EXC_ERROR;
497             END IF;
498          END IF;
499          CLOSE tag_entry;
500 
501          EXIT WHEN l_current_serial = p_to_serial_number;
502          -- Increment the current serial number if serial range inputted
503          IF (p_from_serial_number <> p_to_serial_number) THEN
504             l_current_number := l_current_number + 1;
505             l_padded_length := l_length - length(l_current_number);
506             l_current_serial := RPAD(l_prefix, l_padded_length, '0') ||
507               l_current_number;
508          END IF;
509       END LOOP;
510 
511     ELSE -- Item is not serial controlled
512       IF (l_debug = 1) THEN
513          print_debug('Non-Serial controlled item');
514       END IF;
515       OPEN tag_entry;
516       FETCH tag_entry INTO tag_record;
517       IF (tag_entry%FOUND) THEN
518          -- Check if an adjustment ID for this tag already exists or not
519          IF (tag_record.adjustment_id IS NULL) THEN
520             find_existing_adjustment
521               ( p_physical_inventory_id   =>  p_physical_inventory_id,
522                 p_organization_id         =>  p_organization_id,
523                 p_subinventory            =>  p_subinventory,
524                 p_locator_id              =>  p_locator_id,
525                 p_parent_lpn_id           =>  p_parent_lpn_id,
526                 p_inventory_item_id       =>  p_inventory_item_id,
527                 p_revision                =>  p_revision,
528                 p_lot_number              =>  p_lot_number,
529                 p_serial_number           =>  NULL,
530                 p_user_id                 =>  p_user_id,
531                 p_cost_group_id           =>  tag_record.cost_group_id,
532                 x_adjustment_id           =>  l_adjustment_id
533                 );
534           ELSE
535             l_adjustment_id := tag_record.adjustment_id;
536          END IF;
537          update_row( p_tag_id                  =>  tag_record.tag_id,
538                      p_physical_inventory_id   =>  p_physical_inventory_id,
539                      p_organization_id         =>  p_organization_id,
540                      p_subinventory            =>  p_subinventory,
541                      p_locator_id              =>  p_locator_id,
542                      p_parent_lpn_id           =>  p_parent_lpn_id,
543                      p_inventory_item_id       =>  p_inventory_item_id,
544                      p_revision                =>  p_revision,
545                      p_lot_number              =>  p_lot_number,
546                      p_serial_number           =>  NULL,
547                      p_tag_quantity            =>  p_tag_quantity,
548                      p_tag_uom                 =>  p_tag_uom,
549                      p_user_id                 =>  p_user_id,
550                      p_cost_group_id           =>  tag_record.cost_group_id,
551                      p_adjustment_id           =>  l_adjustment_id
552                     ,p_tag_sec_quantity        =>  p_tag_sec_quantity    --INVCONV, NSRIVAST
553                      );
554          update_adjustment
555            (p_adjustment_id           =>  l_adjustment_id,
556             p_physical_inventory_id   =>  p_physical_inventory_id,
557             p_organization_id         =>  p_organization_id,
558             p_user_id                 =>  p_user_id
559             );
560        ELSE
561          IF (p_dynamic_tag_entry_flag = 1) THEN
562             IF (l_debug = 1) THEN
563             print_debug('Dynamic non-serial tag entry to be inserted');
564             END IF;
565             -- Dynamic tag entries are allowed
566 
567             -- Get the cost group ID for this entry
568             inv_cyc_lovs.get_cost_group_id
569               (p_organization_id        =>  p_organization_id,
570                p_subinventory           =>  p_subinventory,
571                p_locator_id             =>  p_locator_id,
572                p_parent_lpn_id          =>  p_parent_lpn_id,
573                p_inventory_item_id      =>  p_inventory_item_id,
574                p_revision               =>  p_revision,
575                p_lot_number             =>  p_lot_number,
576                p_serial_number          =>  l_current_serial,
577                x_out                    =>  l_cost_group_id);
578             -- Bug# 2607187
579             -- Do not get the default cost group ID.  If the item is
580             -- new and does not exist in onhand, pass a NULL value
581             -- for the cost group ID.  The transaction manager will
582             -- call the cost group rules engine for that if the
583             -- cost group ID passed into MMTT is null.
584             IF (l_cost_group_id = -999) THEN
585                l_cost_group_id := NULL;
586             END IF;
587             -- Get the default cost group ID based on the given org
588             -- and sub if cost group ID was not retrieved successfully
589             /*IF (l_cost_group_id = -999) THEN
590                inv_cyc_lovs.get_default_cost_group_id
591                  (p_organization_id        =>  p_organization_id,
592                   p_subinventory           =>  p_subinventory,
593                   x_out                    =>  l_cost_group_id);
594             END IF;
595             -- Default the cost group ID to 1 if nothing can be found
596             IF (l_cost_group_id = -999) THEN
597                l_cost_group_id := 1;
598             END IF;*/
599 
600             -- Generate a new adjustment ID for this tag
601             find_existing_adjustment
602               ( p_physical_inventory_id   =>  p_physical_inventory_id,
603                 p_organization_id         =>  p_organization_id,
604                 p_subinventory            =>  p_subinventory,
605                 p_locator_id              =>  p_locator_id,
606                 p_parent_lpn_id           =>  p_parent_lpn_id,
607                 p_inventory_item_id       =>  p_inventory_item_id,
608                 p_revision                =>  p_revision,
609                 p_lot_number              =>  p_lot_number,
610                 p_serial_number           =>  NULL,
611                 p_user_id                 =>  p_user_id,
612                 p_cost_group_id           =>  l_cost_group_id,
613                 x_adjustment_id           =>  l_adjustment_id
614                 );
615             insert_row( p_physical_inventory_id   =>  p_physical_inventory_id,
616                         p_organization_id         =>  p_organization_id,
617                         p_subinventory            =>  p_subinventory,
618                         p_locator_id              =>  p_locator_id,
619                         p_parent_lpn_id           =>  p_parent_lpn_id,
620                         p_inventory_item_id       =>  p_inventory_item_id,
621                         p_revision                =>  p_revision,
622                         p_lot_number              =>  p_lot_number,
623                         p_serial_number           =>  NULL,
624                         p_tag_quantity            =>  p_tag_quantity,
625                         p_tag_uom                 =>  p_tag_uom,
626                         p_user_id                 =>  p_user_id,
627                         p_cost_group_id           =>  l_cost_group_id,
628                         p_adjustment_id           =>  l_adjustment_id
629                         --INVCONV, NSRIVAST, START
630                         ,p_tag_sec_quantity       =>    p_tag_sec_quantity
631                         ,p_tag_sec_uom            =>    p_tag_sec_uom
632                         --INVCONV, NSRIVAST, END
633 
634                         );
635             update_adjustment
636               (p_adjustment_id           =>  l_adjustment_id,
637                p_physical_inventory_id   =>  p_physical_inventory_id,
638                p_organization_id         =>  p_organization_id,
639                p_user_id                 =>  p_user_id
640                );
641           ELSE
642             -- Dynamic tag entries are not allowed
643             -- This shouldn't happen if the mobile form's LOV
644             -- statements are correctly set
645             FND_MESSAGE.SET_NAME('INV','INV_NO_DYNAMIC_TAGS');
646             FND_MSG_PUB.ADD;
647             --RAISE FND_API.G_EXC_ERROR;
648          END IF;
649       END IF;
650    END IF;
651 
652 END process_tag;
653 
654 
655 PROCEDURE insert_row
656   (p_physical_inventory_id   IN    NUMBER,
657    p_organization_id         IN    NUMBER,
658    p_subinventory            IN    VARCHAR2,
659    p_locator_id              IN    NUMBER,
660    p_parent_lpn_id           IN    NUMBER,
661    p_inventory_item_id       IN    NUMBER,
662    p_revision                IN    VARCHAR2,
663    p_lot_number              IN    VARCHAR2,
664    p_serial_number           IN    VARCHAR2,
665    p_tag_quantity            IN    NUMBER,
666    p_tag_uom                 IN    VARCHAR2,
667    p_user_id                 IN    NUMBER,
668    p_cost_group_id           IN    NUMBER,
669    p_adjustment_id           IN    NUMBER
670    --INVCONV, NSRIVAST, START
671    ,p_tag_sec_quantity       IN    NUMBER   := NULL
672    ,p_tag_sec_uom            IN    VARCHAR2 := NULL
673    --INVCONV, NSRIVAST, END
674    )
675 IS
676 l_tag_id                        NUMBER;
677 l_tag_number                    VARCHAR2(40);
678 l_next_tag_number               VARCHAR2(40);
679 l_tag_qty_at_standard_uom       NUMBER;
680 l_outermost_lpn_id              NUMBER;
681 CURSOR tag_number_cursor IS
682    SELECT next_tag_number
683      FROM mtl_physical_inventories
684      WHERE physical_inventory_id = p_physical_inventory_id
685      AND organization_id = p_organization_id;
686 l_return_status                 VARCHAR2(300);
687 l_msg_count                     NUMBER;
688 l_msg_data                      VARCHAR2(300);
689 l_lpn_list                      WMS_Container_PUB.LPN_Table_Type;
690 l_temp_bool                     BOOLEAN;
691 l_prefix                        VARCHAR2(30);
692 l_quantity                      NUMBER;
693 l_from_number                   NUMBER;
694 l_to_number                     NUMBER;
695 l_errorcode                     NUMBER;
696 l_length                        NUMBER;
697 l_padded_length                 NUMBER;
698 l_item_standard_uom             VARCHAR2(3);
699 l_employee_id                   NUMBER;
700 
701     l_debug number := NVL(FND_PROFILE.VALUE('INV_DEBUG_TRACE'),0);
702 BEGIN
703    IF (l_debug = 1) THEN
704       print_debug('***insert_row***');
705    END IF;
706    -- Get the next tag ID for this new record
707    SELECT mtl_physical_inventory_tags_s.nextval
708      INTO l_tag_id
709      FROM dual;
710    IF (l_debug = 1) THEN
711       print_debug('Dynamic tag ID: ' || l_tag_id);
712    END IF;
713 
714    -- Generate a new tag number for this record
715    OPEN tag_number_cursor;
716    FETCH tag_number_cursor INTO l_tag_number;
717    IF tag_number_cursor%NOTFOUND THEN
718       -- No value set for next_tag_number so manually
719       -- generate the next sequence value
720       SELECT MAX(tag_number)
721         INTO l_tag_number
722         FROM mtl_physical_inventory_tags
723         WHERE physical_inventory_id = p_physical_inventory_id
724         AND organization_id = p_organization_id;
725       -- Now parse the tag number and increment the numerical part
726       l_temp_bool := MTL_Serial_Check.inv_serial_info
727         ( p_from_serial_number  =>  l_tag_number,
728           p_to_serial_number    =>  NULL,
729           x_prefix              =>  l_prefix,
730           x_quantity            =>  l_quantity,
731           x_from_number         =>  l_from_number,
732           x_to_number           =>  l_to_number,
733           x_errorcode           =>  l_errorcode);
734       l_length := length(l_tag_number);
735       l_from_number := l_from_number + 1;
736       l_padded_length := l_length - length(l_from_number);
737       l_tag_number := RPAD(l_prefix, l_padded_length, '0') ||
738         l_from_number;
739    END IF;
740    CLOSE tag_number_cursor;
741 
742    -- Update the next_tag_number column in the physical inventories table
743    -- since we have just generated a new tag number value here
744    l_temp_bool := MTL_Serial_Check.inv_serial_info
745      ( p_from_serial_number  =>  l_tag_number,
746        p_to_serial_number    =>  NULL,
747        x_prefix              =>  l_prefix,
748        x_quantity            =>  l_quantity,
749        x_from_number         =>  l_from_number,
750        x_to_number           =>  l_to_number,
751        x_errorcode           =>  l_errorcode);
752    l_length := length(l_tag_number);
753    l_from_number := l_from_number + 1;
754    l_padded_length := l_length - length(l_from_number);
755    l_next_tag_number := RPAD(NVL(l_prefix, '0'), l_padded_length, '0') ||
756      l_from_number;
757    UPDATE MTL_PHYSICAL_INVENTORIES
758      SET next_tag_number = l_next_tag_number
759      WHERE physical_inventory_id = p_physical_inventory_id
760      AND organization_id = p_organization_id;
761    IF (l_debug = 1) THEN
762       print_debug('Update physical inventory with next tag number: ' || l_next_tag_number);
763    END IF;
764 
765    -- Calculate the tag quantity at standard uom
766    SELECT primary_uom_code
767      INTO l_item_standard_uom
768      FROM mtl_system_items
769      WHERE inventory_item_id = p_inventory_item_id
770      AND organization_id = p_organization_id;
771    -- I assume that the primary_uom_code is always given for an item
772    l_tag_qty_at_standard_uom := inv_convert.inv_um_convert
773      ( item_id              =>  p_inventory_item_id,
774        precision            =>  5,
775        from_quantity        =>  p_tag_quantity,
776        from_unit            =>  p_tag_uom,
777        to_unit              =>  l_item_standard_uom,
778        from_name            =>  NULL,
779        to_name              =>  NULL);
780    -- Conversion will return -99999 if unsuccessful so need to check for this
781    IF (l_tag_qty_at_standard_uom = -99999) THEN
782       FND_MESSAGE.SET_NAME('WMS', 'WMS_CONT_INVALID_CONVERSION');
783       FND_MSG_PUB.ADD;
784       RAISE FND_API.G_EXC_ERROR;
785    END IF;
786 
787    -- Get the outermost LPN ID for this record if necessary
788    IF (p_parent_lpn_id IS NOT NULL) THEN
789       --Bug2935754 starts
790       /*
791       WMS_CONTAINER_PUB.GET_OUTERMOST_LPN
792         ( p_api_version       =>  1.0,
793           x_return_status     =>  l_return_status,
794           x_msg_count         =>  l_msg_count,
795           x_msg_data          =>  l_msg_data,
796           p_lpn_id            =>  p_parent_lpn_id,
797           x_lpn_list          =>  l_lpn_list);
798       l_outermost_lpn_id := l_lpn_list(1).lpn_id;
799       */
800    BEGIN
801      SELECT  outermost_lpn_id
802        INTO  l_outermost_lpn_id
803        FROM  WMS_LICENSE_PLATE_NUMBERS
804        WHERE lpn_id = p_parent_lpn_id;
805    EXCEPTION
806      WHEN OTHERS THEN
807        IF (l_debug = 1) THEN
808          print_debug('Unable to fetch outermost LPN for LPN ID: ' || p_parent_lpn_id);
809        END IF;
810        RAISE FND_API.G_EXC_ERROR;
811    END;
812    --Bug2935754 ends
813 
814       IF (l_debug = 1) THEN
815          print_debug('LPN ID passed in so get the outermost LPN: ' || l_outermost_lpn_id);
816       END IF;
817    END IF;
818 
819   print_debug('Deriving the employee id based on user ID: ' || p_user_id);
820 
821    --Bug 6600166, raising error if user is not a valid employee
822    BEGIN
823      SELECT fus.employee_id
824      INTO   l_employee_id
825      FROM   mtl_employees_current_view mec, fnd_user fus
826      WHERE  fus.user_id = p_user_id
827      AND    mec.employee_id = fus.employee_id
828      AND    mec.organization_id = p_organization_id;
829    EXCEPTION
830     WHEN OTHERS THEN
831      FND_MESSAGE.SET_NAME('INV', 'INV_EMP');
832      FND_MSG_PUB.ADD;
833      RAISE FND_API.G_EXC_ERROR;
834    END;
835 
836      print_debug('the employee id is: ' || l_employee_id);
837 
838    -- Insert the new record
839    IF (l_debug = 1) THEN
840       print_debug('Inserting the new record here');
841    END IF;
842    INSERT INTO MTL_PHYSICAL_INVENTORY_TAGS
843      (tag_id,
844       physical_inventory_id,
845       organization_id,
846       last_update_date,
847       last_updated_by,
848       creation_date,
849       created_by,
850       last_update_login,
851       void_flag,
852       tag_number,
853       adjustment_id,
854       inventory_item_id,
855       tag_quantity,
856       tag_uom,
857       tag_quantity_at_standard_uom,
858       standard_uom,
859       subinventory,
860       locator_id,
861       lot_number,
862       revision,
863       serial_num,
864       counted_by_employee_id,
865       parent_lpn_id,
866       outermost_lpn_id,
867       cost_group_id
868       --INVCONV, NSRIVAST, START
869       ,tag_secondary_uom
870       ,tag_secondary_quantity
871       --INVCONV, NSRIVAST, END
872       ) VALUES
873      (l_tag_id,
874       p_physical_inventory_id,
875       p_organization_id,
876       SYSDATE,
877       p_user_id,
878       SYSDATE,
879       p_user_id,
880       p_user_id,
881       2,
882       l_tag_number,
883       p_adjustment_id,
884       p_inventory_item_id,
885       p_tag_quantity,
886       p_tag_uom,
887       l_tag_qty_at_standard_uom,
888       l_item_standard_uom,
889       p_subinventory,
890       p_locator_id,
891       p_lot_number,
892       p_revision,
893       p_serial_number,
894       l_employee_id,
895       p_parent_lpn_id,
896       l_outermost_lpn_id,
897       p_cost_group_id
898       --INVCONV, NSRIVAST, START
899      ,p_tag_sec_uom
900      ,p_tag_sec_quantity
901       --INVCONV, NSRIVAST, END
902       );
903 
904 EXCEPTION
905  WHEN fnd_api.g_exc_error THEN
906    raise fnd_api.g_exc_error;
907  WHEN OTHERS THEN
908    print_debug(SQLERRM);
909    raise fnd_api.g_exc_unexpected_error;
910 
911 END insert_row;
912 
913 
914 PROCEDURE update_row
915   (p_tag_id                  IN    NUMBER,
916    p_physical_inventory_id   IN    NUMBER,
917    p_organization_id         IN    NUMBER,
918    p_subinventory            IN    VARCHAR2,
919    p_locator_id              IN    NUMBER,
920    p_parent_lpn_id           IN    NUMBER,
921    p_inventory_item_id       IN    NUMBER,
922    p_revision                IN    VARCHAR2,
923    p_lot_number              IN    VARCHAR2,
924    p_serial_number           IN    VARCHAR2,
925    p_tag_quantity            IN    NUMBER,
926    p_tag_uom                 IN    VARCHAR2,
927    p_user_id                 IN    NUMBER,
928    p_cost_group_id           IN    NUMBER,
929    p_adjustment_id           IN    NUMBER
930    ,p_tag_sec_quantity       IN    NUMBER   := NULL     --INVCONV, NSRIVAST, START
931    )
932 IS
933 l_tag_qty_at_standard_uom       NUMBER;
934 l_outermost_lpn_id              NUMBER;
935 l_item_standard_uom             VARCHAR2(3);
936 l_return_status                 VARCHAR2(300);
937 l_msg_count                     NUMBER;
938 l_msg_data                      VARCHAR2(300);
939 l_lpn_list                      WMS_Container_PUB.LPN_Table_Type;
940 l_employee_id                   NUMBER;
941 
942     l_debug number := NVL(FND_PROFILE.VALUE('INV_DEBUG_TRACE'),0);
943 BEGIN
944    IF (l_debug = 1) THEN
945       print_debug('***update_row***');
946    END IF;
947    -- Calculate the tag quantity at standard uom
948    SELECT primary_uom_code
949      INTO l_item_standard_uom
950      FROM mtl_system_items
951      WHERE inventory_item_id = p_inventory_item_id
952      AND organization_id = p_organization_id;
953    -- I assume that the primary_uom_code is always given for an item
954    l_tag_qty_at_standard_uom := inv_convert.inv_um_convert
955      ( item_id              =>  p_inventory_item_id,
956        precision            =>  5,
957        from_quantity        =>  p_tag_quantity,
958        from_unit            =>  p_tag_uom,
959        to_unit              =>  l_item_standard_uom,
960        from_name            =>  NULL,
961        to_name              =>  NULL);
962    -- Conversion will return -99999 if unsuccessful so need to check for this
963    IF (l_tag_qty_at_standard_uom = -99999) THEN
964       FND_MESSAGE.SET_NAME('WMS', 'WMS_CONT_INVALID_CONVERSION');
965       FND_MSG_PUB.ADD;
966       RAISE FND_API.G_EXC_ERROR;
967    END IF;
968 
969    -- Get the outermost LPN ID for this record if necessary
970    IF (p_parent_lpn_id IS NOT NULL) THEN
971       --Bug2935754 starts
972       /*
973       WMS_CONTAINER_PUB.GET_OUTERMOST_LPN
974         ( p_api_version       =>  1.0,
975           x_return_status     =>  l_return_status,
976           x_msg_count         =>  l_msg_count,
977           x_msg_data          =>  l_msg_data,
978           p_lpn_id            =>  p_parent_lpn_id,
979           x_lpn_list          =>  l_lpn_list);
980       l_outermost_lpn_id := l_lpn_list(1).lpn_id;
981       */
982    BEGIN
983      SELECT  outermost_lpn_id
984        INTO  l_outermost_lpn_id
985        FROM  WMS_LICENSE_PLATE_NUMBERS
986        WHERE lpn_id = p_parent_lpn_id;
987    EXCEPTION
988       WHEN OTHERS THEN
989         IF (l_debug = 1) THEN
990           print_debug('Unable to fetch outermost LPN for LPN ID: ' || p_parent_lpn_id);
991         END IF;
992       RAISE FND_API.G_EXC_ERROR;
993    END;
994    --Bug2935754 ends
995 
996       IF (l_debug = 1) THEN
997          print_debug('LPN ID passed in so get the outermost LPN: ' || l_outermost_lpn_id);
998       END IF;
999    END IF;
1000 
1001   print_debug('Deriving the employee id based on user ID: ' || p_user_id);
1002 
1003   --Bug 6600166, raising error if user is not a valid employee
1004   BEGIN
1005    SELECT fus.employee_id
1006    INTO   l_employee_id
1007    FROM   mtl_employees_current_view mec, fnd_user fus
1008    WHERE  fus.user_id = p_user_id
1009    AND    mec.employee_id = fus.employee_id
1010    AND    mec.organization_id = p_organization_id;
1011   EXCEPTION
1012     WHEN OTHERS THEN
1013      FND_MESSAGE.SET_NAME('INV', 'INV_EMP');
1014      FND_MSG_PUB.ADD;
1015      RAISE FND_API.G_EXC_ERROR;
1016   END;
1017 
1018    print_debug('the employee id is: ' || l_employee_id);
1019 
1020    -- Update the record
1021    IF (l_debug = 1) THEN
1022       print_debug('Updating the physical inventory tag record for tag ID: ' || p_tag_id);
1023    END IF;
1024    UPDATE MTL_PHYSICAL_INVENTORY_TAGS
1025      SET
1026      last_update_date                  =     SYSDATE,
1027      last_updated_by                   =     p_user_id,
1028      last_update_login                 =     p_user_id,
1029      adjustment_id                     =     p_adjustment_id,
1030      inventory_item_id                 =     p_inventory_item_id,
1031      tag_quantity                      =     p_tag_quantity,
1032      tag_uom                           =     p_tag_uom,
1033      tag_quantity_at_standard_uom      =     l_tag_qty_at_standard_uom,
1034      standard_uom                      =     l_item_standard_uom,
1035      subinventory                      =     p_subinventory,
1036      locator_id                        =     p_locator_id,
1037      lot_number                        =     p_lot_number,
1038      revision                          =     p_revision,
1039      serial_num                        =     p_serial_number,
1040      counted_by_employee_id            =     l_employee_id,
1041      parent_lpn_id                     =     p_parent_lpn_id,
1042      outermost_lpn_id                  =     l_outermost_lpn_id,
1043      cost_group_id                     =     p_cost_group_id
1044      ,tag_secondary_quantity           =     p_tag_sec_quantity  --INVCONV, NSRIVAST, START
1045      WHERE tag_id = p_tag_id;
1046 
1047    IF (SQL%NOTFOUND) THEN
1048       RAISE NO_DATA_FOUND;
1049    END IF;
1050 
1051 END update_row;
1052 
1053 
1054 PROCEDURE update_adjustment
1055   (p_adjustment_id           IN   NUMBER,
1056    p_physical_inventory_id   IN   NUMBER,
1057    p_organization_id         IN   NUMBER,
1058    p_user_id                 IN   NUMBER
1059    )
1060 IS
1061 l_adj_count_quantity    NUMBER;
1062 -- Variables needed for calling the label printing API
1063 l_inventory_item_id     NUMBER;
1064 -- Increased lot size to 80 Char - Mercy Thomas - B4625329
1065 l_lot_number            VARCHAR2(80);
1066 l_serial_number         VARCHAR2(30);
1067 l_lpn_id                NUMBER;
1068 l_subinventory          VARCHAR2(10);
1069 l_locator_id            NUMBER;
1070 l_adjustment_quantity   NUMBER;
1071 l_standard_uom_code     VARCHAR2(3);
1072 l_label_status          VARCHAR2(300) := NULL;
1073 l_return_status         VARCHAR2(3000);
1074 l_msg_count             NUMBER;
1075 l_msg_data              VARCHAR2(3000);
1076 
1077     l_debug number := NVL(FND_PROFILE.VALUE('INV_DEBUG_TRACE'),0);
1078 BEGIN
1079    IF (l_debug = 1) THEN
1080       print_debug('***update_adjustment***');
1081    END IF;
1082    SELECT NVL(SUM(tag_quantity_at_standard_uom),0)
1083      INTO l_adj_count_quantity
1084      FROM mtl_physical_inventory_tags
1085      WHERE adjustment_id = p_adjustment_id
1086      AND organization_id = p_organization_id
1087      AND physical_inventory_id = p_physical_inventory_id
1088      AND void_flag = 2;
1089 
1090    IF (l_debug = 1) THEN
1091       print_debug('Updating the physical adjustment record for adjustment ID: ' || p_adjustment_id);
1092    END IF;
1093    UPDATE mtl_physical_adjustments
1094      SET last_update_date = SYSDATE,
1095      last_updated_by = NVL(p_user_id, -1),
1096      count_quantity = l_adj_count_quantity,
1097      adjustment_quantity = NVL(l_adj_count_quantity, NVL(system_quantity,0))
1098      - NVL(system_quantity,0),
1099      approval_status = NULL,
1100      approved_by_employee_id = NULL
1101      WHERE adjustment_id = p_adjustment_id
1102      AND physical_inventory_id = p_physical_inventory_id
1103      AND organization_id = p_organization_id;
1104 
1105    -- Get the adjustment record values needed for label printing
1106    IF (l_debug = 1) THEN
1107       print_debug('Get the adjustment record values for label printing');
1108    END IF;
1109    SELECT inventory_item_id, lot_number, serial_number, parent_lpn_id,
1110      subinventory_name, locator_id, NVL(adjustment_quantity, 0)
1111      INTO l_inventory_item_id, l_lot_number, l_serial_number,
1112      l_lpn_id, l_subinventory, l_locator_id, l_adjustment_quantity
1113      FROM mtl_physical_adjustments
1114      WHERE adjustment_id = p_adjustment_id
1115      AND physical_inventory_id = p_physical_inventory_id
1116      AND organization_id = p_organization_id;
1117 
1118    -- Get the primary UOM for the inventory item
1119    IF (l_debug = 1) THEN
1120       print_debug('Get the primary UOM code: ' || 'Item ID: ' || l_inventory_item_id || ': ' || 'Org ID: ' || p_organization_id);
1121    END IF;
1122    SELECT primary_uom_code
1123      INTO l_standard_uom_code
1124      FROM mtl_system_items
1125      WHERE inventory_item_id = l_inventory_item_id
1126      AND organization_id = p_organization_id;
1127 
1128    -- Call the label printing API if an adjustment is required
1129    IF (l_debug = 1) THEN
1130       print_debug('Adjustment quantity: ' || l_adjustment_quantity);
1131    END IF;
1132    IF (l_adjustment_quantity <> 0) THEN
1133       IF (l_debug = 1) THEN
1134          print_debug('Calling print_label_manual_wrap with the following input parameters');
1135          print_debug('p_business_flow_code: -> ' || 9);
1136       END IF;
1137       --print_debug('p_label_type: ---------> ' || 1);
1138       IF (l_debug = 1) THEN
1139          print_debug('p_organization_id: ----> ' || p_organization_id);
1140          print_debug('p_inventory_item_id: --> ' || l_inventory_item_id);
1141          print_debug('p_lot_number: ---------> ' || l_lot_number);
1142          print_debug('p_fm_serial_number: ---> ' || l_serial_number);
1143          print_debug('p_to_serial_number: ---> ' || l_serial_number);
1144          print_debug('p_lpn_id: -------------> ' || l_lpn_id);
1145          print_debug('p_subinventory_code: --> ' || l_subinventory);
1146          print_debug('p_locator_id: ---------> ' || l_locator_id);
1147          print_debug('p_quantity: -----------> ' || l_adjustment_quantity);
1148          print_debug('p_uom: ----------------> ' || l_standard_uom_code);
1149          print_debug('p_no_of_copies: -------> ' || 1);
1150       END IF;
1151 
1152       -- Bug# 2301732
1153       -- Make the call to the label printing API more robust
1154       -- by trapping for exceptions when calling it
1155       -- Bug# 2412674
1156       -- Don't pass in the value for the label type
1157       BEGIN
1158          inv_label.print_label_manual_wrap
1159            ( x_return_status      =>  l_return_status        ,
1160              x_msg_count          =>  l_msg_count            ,
1161              x_msg_data           =>  l_msg_data             ,
1162              x_label_status       =>  l_label_status         ,
1163              p_business_flow_code =>  9                      ,
1164              --p_label_type         =>  1                      ,
1165              p_organization_id    =>  p_organization_id      ,
1166              p_inventory_item_id  =>  l_inventory_item_id    ,
1167              p_lot_number         =>  l_lot_number           ,
1168              p_fm_serial_number   =>  l_serial_number        ,
1169              p_to_serial_number   =>  l_serial_number        ,
1170              p_lpn_id             =>  l_lpn_id               ,
1171              p_subinventory_code  =>  l_subinventory         ,
1172              p_locator_id         =>  l_locator_id           ,
1173              p_quantity           =>  l_adjustment_quantity  ,
1174              p_uom                =>  l_standard_uom_code    ,
1175              p_no_of_copies       =>  1
1176              );
1177       EXCEPTION
1178          WHEN OTHERS THEN
1179             IF (l_debug = 1) THEN
1180             print_debug('Error while calling label printing API');
1181             END IF;
1182             FND_MESSAGE.SET_NAME('INV', 'INV_RCV_CRT_PRINT_LABEL_FAILE');
1183             FND_MSG_PUB.ADD;
1184       END;
1185       IF (l_debug = 1) THEN
1186          print_debug('After calling label printing API: ' || l_return_status || ', ' || l_label_status || ', ' || l_msg_data);
1187       END IF;
1188 
1189       IF (l_return_status <> FND_API.G_RET_STS_SUCCESS) THEN
1190          FND_MESSAGE.SET_NAME('INV', 'INV_RCV_CRT_PRINT_LABEL_FAILE');
1191          FND_MSG_PUB.ADD;
1192       END IF;
1193 
1194    END IF;
1195 
1196 END update_adjustment;
1197 
1198 
1199 
1200 PROCEDURE find_existing_adjustment
1201   (p_physical_inventory_id   IN           NUMBER,
1202    p_organization_id         IN           NUMBER,
1203    p_subinventory            IN           VARCHAR2,
1204    p_locator_id              IN           NUMBER,
1205    p_parent_lpn_id           IN           NUMBER,
1206    p_inventory_item_id       IN           NUMBER,
1207    p_revision                IN           VARCHAR2,
1208    p_lot_number              IN           VARCHAR2,
1209    p_serial_number           IN           VARCHAR2,
1210    p_user_id                 IN           NUMBER,
1211    p_cost_group_id           IN           NUMBER,
1212    x_adjustment_id           OUT   NOCOPY NUMBER
1213    )
1214 IS
1215 l_rev_code                NUMBER;
1216 l_org_locator_type        NUMBER;
1217 l_sub_locator_type        NUMBER;
1218 l_location_control_code   NUMBER;
1219 l_lot_control_code        NUMBER;
1220 l_serial_control_code     NUMBER;
1221 l_adj_id                  NUMBER:= -1;
1222 l_actual_cost             NUMBER;
1223 l_outermost_lpn_id        NUMBER;
1224 l_return_status           VARCHAR2(300);
1225 l_msg_count               NUMBER;
1226 l_msg_data                VARCHAR2(300);
1227 l_lpn_list                WMS_Container_PUB.LPN_Table_Type;
1228 l_approval_status         NUMBER:= -1;
1229 
1230     l_debug number := NVL(FND_PROFILE.VALUE('INV_DEBUG_TRACE'),0);
1231 BEGIN
1232    IF (l_debug = 1) THEN
1233       print_debug('***find_existing_adjustment***');
1234    END IF;
1235    -- Get the required information for the local variables
1236    -- Locator control type for the org
1237    SELECT stock_locator_control_code
1238      INTO l_org_locator_type
1239      FROM mtl_parameters
1240      WHERE organization_id = p_organization_id;
1241 
1242    -- Locator control type for the sub
1243    SELECT locator_type
1244      INTO l_sub_locator_type
1245      FROM mtl_secondary_inventories
1246      WHERE secondary_inventory_name = p_subinventory
1247      AND organization_id = p_organization_id;
1248 
1249    -- Locator control type for the item plus revision, lot, and serial
1250    -- control codes
1251    SELECT revision_qty_control_code, location_control_code,
1252      lot_control_code, serial_number_control_code
1253      INTO l_rev_code, l_location_control_code,
1254      l_lot_control_code, l_serial_control_code
1255      FROM mtl_system_items
1256      WHERE inventory_item_id = p_inventory_item_id
1257      AND organization_id = p_organization_id;
1258 
1259    -- Get the adjustment ID if it is existing
1260    IF (l_debug = 1) THEN
1261       print_debug('Try to find the adjustment ID if it exists');
1262    END IF;
1263    SELECT MIN(ADJUSTMENT_ID)
1264      INTO l_adj_id
1265      FROM MTL_PHYSICAL_ADJUSTMENTS
1266      WHERE ORGANIZATION_ID = p_organization_id
1267      AND PHYSICAL_INVENTORY_ID = p_physical_inventory_id
1268      AND INVENTORY_ITEM_ID = p_inventory_item_id
1269      AND SUBINVENTORY_NAME = p_subinventory
1270      AND ( NVL(REVISION,'@@@@@') = NVL(p_revision,'@@@@@')
1271            OR l_rev_code = 1 )
1272      AND NVL(parent_lpn_id, -99999) = NVL(p_parent_lpn_id, -99999) --Bug 6929248 Posted adjustments should not be allowed to enter tags
1273      AND (approval_status=3 OR NVL(cost_group_id, -99999) = NVL(p_cost_group_id, -99999))
1274      AND (NVL(LOCATOR_ID, -99999) = NVL(p_locator_id, -99999)
1275           OR l_org_locator_type = 1
1276           OR (l_org_locator_type = 4
1277               AND (l_sub_locator_type = 1
1278                    OR (l_sub_locator_type = 5
1279                        AND l_location_control_code = 1)))
1280           OR (l_location_control_code = 5
1281               AND l_location_control_code = 1))
1282      AND ( NVL(LOT_NUMBER,'@@@@@') = NVL(p_lot_number,'@@@@@')
1283            OR l_lot_control_code = 1 )
1284      AND ( NVL(SERIAL_NUMBER,'@@@@@') = NVL(p_serial_number,'@@@@@')
1285            OR l_serial_control_code = 1 )
1286      GROUP BY ORGANIZATION_ID,
1287      PHYSICAL_INVENTORY_ID,
1288      INVENTORY_ITEM_ID,
1289      SUBINVENTORY_NAME,
1290      REVISION,
1291      LOCATOR_ID,
1292      PARENT_LPN_ID,
1293      COST_GROUP_ID,
1294      LOT_NUMBER,
1295      SERIAL_NUMBER;
1296 
1297  /* Bug 4350316, if the corresponding adjustment is posted, not allowing the user to enter a dynamic tag*/
1298 
1299      IF l_adj_id IS NOT NULL THEN
1300        select approval_status
1301        into l_approval_status
1302        from mtl_physical_adjustments
1303        where adjustment_id = l_adj_id
1304        and physical_inventory_id = p_physical_inventory_id;
1305 
1306        if (nvl(l_approval_status,0) = 3) then
1307         print_debug('Error: The corresponding adjustment_id '||l_adj_id||' is already posted');
1308         fnd_message.set_name('INV','INV_PHYSICAL_ADJ_POSTED');
1309         fnd_message.set_token('TOKEN1', l_adj_id);
1310         fnd_msg_pub.add;
1311         raise fnd_api.g_exc_error;
1312        end if;
1313      END IF;
1314 
1315 
1316    x_adjustment_id := l_adj_id;
1317 
1318 EXCEPTION
1319    WHEN NO_DATA_FOUND THEN
1320       -- insert new adjustment row
1321       IF (l_debug = 1) THEN
1322          print_debug('No adjustment record found so insert a new one');
1323       END IF;
1324 
1325    -- Get the actual cost of the item in the current tag
1326    IF (l_debug = 1) THEN
1327       print_debug('Get the actual cost of the item');
1328    END IF;
1329 
1330     /* Bug# 2942493
1331     ** Instead of duplicating the code, reusing the common utility to
1332     ** to get the item cost. That way its easier to maintain.
1333     */
1334 
1335     INV_UTILITIES.GET_ITEM_COST(
1336        v_org_id     => p_organization_id,
1337        v_item_id    => p_inventory_item_id,
1338        v_locator_id => p_locator_id,
1339        v_item_cost  => l_actual_cost);
1340 
1341     IF (l_actual_cost = -999) THEN
1342       l_actual_cost := 0;
1343     END IF;
1344 
1345 -- Get a valid adjustment ID for the new record
1346 SELECT mtl_physical_adjustments_s.NEXTVAL
1347   INTO l_adj_id
1348   FROM dual;
1349 IF (l_debug = 1) THEN
1350    print_debug('New adjustment ID: ' || l_adj_id);
1351 END IF;
1352 
1353 -- Get the outermost LPN ID if necessary
1354 IF (p_parent_lpn_id IS NOT NULL) THEN
1355    --Bug2935754 starts
1356    /*
1357    WMS_CONTAINER_PUB.GET_OUTERMOST_LPN
1358      ( p_api_version       =>  1.0,
1359        x_return_status     =>  l_return_status,
1360        x_msg_count         =>  l_msg_count,
1361        x_msg_data          =>  l_msg_data,
1362        p_lpn_id            =>  p_parent_lpn_id,
1363        x_lpn_list          =>  l_lpn_list);
1364    l_outermost_lpn_id := l_lpn_list(1).lpn_id;
1365    */
1366 
1367    BEGIN
1368      SELECT  outermost_lpn_id
1369        INTO  l_outermost_lpn_id
1370        FROM  WMS_LICENSE_PLATE_NUMBERS
1371        WHERE lpn_id = p_parent_lpn_id;
1372    EXCEPTION
1373      WHEN OTHERS THEN
1374       IF (l_debug = 1) THEN
1375         print_debug('Unable to fetch outermost LPN for LPN ID: ' || p_parent_lpn_id);
1376       END IF;
1377       RAISE FND_API.G_EXC_ERROR;
1378    END;
1379    --Bug2935754 ends
1380 
1381    IF (l_debug = 1) THEN
1382       print_debug('LPN ID passed in so get the outermost LPN: ' || l_outermost_lpn_id);
1383    END IF;
1384 END IF;
1385 
1386 -- Insert the new adjustment record
1387 IF (l_debug = 1) THEN
1388    print_debug('Inserting the new physical adjustment record');
1389 END IF;
1390 INSERT INTO mtl_physical_adjustments
1391   (     adjustment_id,
1392         organization_id,
1393         physical_inventory_id,
1394         inventory_item_id,
1395         subinventory_name,
1396         system_quantity,
1397         last_update_date,
1398         last_updated_by,
1399         creation_date,
1400         created_by,
1401         last_update_login,
1402         count_quantity,
1403         adjustment_quantity,
1404         revision,
1405         locator_id,
1406         parent_lpn_id,
1407         outermost_lpn_id,
1408         cost_group_id,
1409         lot_number,
1410         serial_number,
1411         actual_cost )
1412   VALUES ( l_adj_id,
1413            p_organization_id,
1414            p_physical_inventory_id,
1415            p_inventory_item_id,
1416            p_subinventory,
1417            0,
1418            SYSDATE,
1419            p_user_id,
1420            SYSDATE,
1421            p_user_id,
1422            p_user_id,
1423            0,
1424            0,
1425            p_revision,
1426            p_locator_id,
1427            p_parent_lpn_id,
1428            l_outermost_lpn_id,
1429            p_cost_group_id,
1430            p_lot_number,
1431            p_serial_number,
1432            l_actual_cost);
1433 
1434 x_adjustment_id := l_adj_id;
1435 
1436 END find_existing_adjustment;
1437 
1438 
1439 
1440 PROCEDURE process_summary
1441   (p_physical_inventory_id   IN    NUMBER,
1442    p_organization_id         IN    NUMBER,
1443    p_subinventory            IN    VARCHAR2,
1444    p_locator_id              IN    NUMBER := NULL,
1445    p_parent_lpn_id           IN    NUMBER := NULL,
1446    p_dynamic_tag_entry_flag  IN    NUMBER,
1447    p_user_id                 IN    NUMBER
1448    )
1449 IS
1450 l_current_lpn            NUMBER;
1451 l_temp_uom_code          VARCHAR2(3);
1452 CURSOR nested_lpn_cursor IS
1453    SELECT *
1454      FROM WMS_LICENSE_PLATE_NUMBERS
1455      START WITH lpn_id = p_parent_lpn_id
1456      CONNECT BY parent_lpn_id = PRIOR lpn_id;
1457 CURSOR lpn_contents_cursor IS
1458    SELECT *
1459      FROM WMS_LPN_CONTENTS
1460      WHERE parent_lpn_id = l_current_lpn
1461      AND NVL(serial_summary_entry, 2) = 2;
1462 CURSOR lpn_serial_contents_cursor IS
1463    SELECT *
1464      FROM MTL_SERIAL_NUMBERS
1465      WHERE lpn_id = l_current_lpn;
1466 
1467     l_debug number := NVL(FND_PROFILE.VALUE('INV_DEBUG_TRACE'),0);
1468 BEGIN
1469    IF (l_debug = 1) THEN
1470       print_debug('***process_summary***');
1471    END IF;
1472    -- Use the cursor that searches through all levels in the parent child relationship
1473    FOR v_lpn_id IN nested_lpn_cursor LOOP
1474       l_current_lpn := v_lpn_id.lpn_id;
1475 
1476       -- Process the tag for the LPN item itself if it is associated with
1477       -- an inventory item
1478       IF (v_lpn_id.inventory_item_id IS NOT NULL) THEN
1479          -- Get the primary UOM for the container inventory item
1480          SELECT primary_uom_code
1481            INTO l_temp_uom_code
1482            FROM mtl_system_items
1483            WHERE inventory_item_id = v_lpn_id.inventory_item_id
1484            AND organization_id = v_lpn_id.organization_id;
1485 
1486          IF (l_debug = 1) THEN
1487          print_debug('Counting an LPN');
1488          END IF;
1489          process_tag
1490            (p_physical_inventory_id   =>  p_physical_inventory_id,
1491             p_organization_id         =>  p_organization_id,
1492             p_subinventory            =>  p_subinventory,
1493             p_locator_id              =>  p_locator_id,
1494             p_parent_lpn_id           =>  v_lpn_id.parent_lpn_id,
1495             p_inventory_item_id       =>  v_lpn_id.inventory_item_id,
1496             p_revision                =>  v_lpn_id.revision,
1497             p_lot_number              =>  v_lpn_id.lot_number,
1498             p_from_serial_number      =>  v_lpn_id.serial_number,
1499             p_to_serial_number        =>  v_lpn_id.serial_number,
1500             p_tag_quantity            =>  1,
1501             p_tag_uom                 =>  l_temp_uom_code,
1502             p_dynamic_tag_entry_flag  =>  p_dynamic_tag_entry_flag,
1503             p_user_id                 =>  p_user_id,
1504             p_cost_group_id           =>  v_lpn_id.cost_group_id
1505             );
1506       END IF;
1507 
1508       -- Process the tags for the LPN content items
1509       FOR v_lpn_content IN lpn_contents_cursor LOOP
1510 
1511          IF (l_debug = 1) THEN
1512          print_debug('Counting an LPN content item');
1513          END IF;
1514          process_tag
1515            (p_physical_inventory_id   =>  p_physical_inventory_id,
1516             p_organization_id         =>  p_organization_id,
1517             p_subinventory            =>  p_subinventory,
1518             p_locator_id              =>  p_locator_id,
1519             p_parent_lpn_id           =>  v_lpn_content.parent_lpn_id,
1520             p_inventory_item_id       =>  v_lpn_content.inventory_item_id,
1521             p_revision                =>  v_lpn_content.revision,
1522             p_lot_number              =>  v_lpn_content.lot_number,
1523             p_from_serial_number      =>  NULL,
1524             p_to_serial_number        =>  NULL,
1525             p_tag_quantity            =>  v_lpn_content.quantity,
1526             p_tag_uom                 =>  v_lpn_content.uom_code,
1527             p_dynamic_tag_entry_flag  =>  p_dynamic_tag_entry_flag,
1528             p_user_id                 =>  p_user_id,
1529             p_cost_group_id           =>  v_lpn_content.cost_group_id
1530             );
1531 
1532       END LOOP;
1533 
1534       -- Process the tags for serialized items
1535       FOR v_lpn_serial_content IN lpn_serial_contents_cursor LOOP
1536          -- Get the primary UOM for the serialized item
1537          SELECT primary_uom_code
1538            INTO l_temp_uom_code
1539            FROM mtl_system_items
1540            WHERE inventory_item_id = v_lpn_serial_content.inventory_item_id
1541            AND organization_id = v_lpn_serial_content.current_organization_id;
1542 
1543          IF (l_debug = 1) THEN
1544          print_debug('Counting an LPN serial controlled item');
1545          END IF;
1546          process_tag
1547            (p_physical_inventory_id   =>  p_physical_inventory_id,
1548             p_organization_id         =>  p_organization_id,
1549             p_subinventory            =>  p_subinventory,
1550             p_locator_id              =>  p_locator_id,
1551             p_parent_lpn_id           =>  v_lpn_serial_content.lpn_id,
1552             p_inventory_item_id       =>  v_lpn_serial_content.inventory_item_id,
1553             p_revision                =>  v_lpn_serial_content.revision,
1554             p_lot_number              =>  v_lpn_serial_content.lot_number,
1555             p_from_serial_number      =>  v_lpn_serial_content.serial_number,
1556             p_to_serial_number        =>  v_lpn_serial_content.serial_number,
1557             p_tag_quantity            =>  1,
1558             p_tag_uom                 =>  l_temp_uom_code,
1559             p_dynamic_tag_entry_flag  =>  p_dynamic_tag_entry_flag,
1560             p_user_id                 =>  p_user_id,
1561             p_cost_group_id           =>  v_lpn_serial_content.cost_group_id
1562             );
1563 
1564       END LOOP;
1565 
1566    END LOOP;
1567 
1568 END process_summary;
1569 
1570 --Fix for bug #4654210
1571    PROCEDURE unmark_serials
1572      (p_physical_inventory_id   IN    NUMBER,
1573       p_organization_id         IN    NUMBER,
1574       p_item_id                 IN    NUMBER,
1575       x_status                 OUT    NOCOPY NUMBER
1576      )
1577    IS
1578       l_debug number := NVL(FND_PROFILE.VALUE('INV_DEBUG_TRACE'),0);
1579    BEGIN
1580       IF (l_debug = 1) THEN
1581          print_debug('***unmark_serials***');
1582       END IF;
1583 
1584       IF (p_physical_inventory_id IS NULL) THEN
1585          IF (l_debug = 1) THEN
1586              print_debug('Physical Inventory Id is not provided. Returning from the Procedure');
1587          END IF;
1588          x_status := -1;
1589       ELSIF (p_organization_id IS NULL) THEN
1590          IF (l_debug = 1) THEN
1591              print_debug('Organization Id is not provided. Returning from the Procedure');
1592          END IF;
1593          x_status := -1;
1594       ELSIF (p_item_id IS NULL) THEN
1595          IF (l_debug = 1) THEN
1596              print_debug('Inventory Item Id is not provided. Returning from the Procedure');
1597          END IF;
1598          x_status := -1;
1599       ELSE
1600 
1601          UPDATE mtl_serial_numbers
1602          SET    group_mark_id = -1
1603          WHERE  inventory_item_id = p_item_id
1604          AND    serial_number in
1605              (SELECT DISTINCT serial_num
1606               FROM   mtl_physical_inventory_tags
1607               WHERE  organization_id      = p_organization_id
1608               AND   physical_inventory_id = p_physical_inventory_id
1609               AND   inventory_item_id     = p_item_id
1610               AND   serial_num is not null
1611               )
1612          AND nvl(group_mark_id,-1) <> -1;
1613 
1614          IF (l_debug = 1) THEN
1615              print_debug('Updated ' || SQL%ROWCOUNT || ' Records in mtl_serial_numbers for the inventory_item_id ' || p_item_id);
1616              print_debug('*** end unmark_serials***');
1617          END IF;
1618 
1619          x_status := 0;
1620       END IF;
1621 
1622    END unmark_serials;
1623 
1624    --End of Fix for bug # 4654210
1625 
1626 -- Fix for 5660272 to get the serial uniquiness type or a given organization
1627 PROCEDURE GET_SERIAL_NUMBER_TYPE
1628   (	x_serial_number_type OUT NOCOPY	NUMBER,
1629 	p_organization_id   IN		NUMBER
1630   )
1631  IS
1632  BEGIN
1633   SELECT	NVL(SERIAL_NUMBER_TYPE, 0)
1634   INTO		x_serial_number_type
1635   FROM		MTL_PARAMETERS
1636   WHERE		ORGANIZATION_ID = p_organization_id;
1637 EXCEPTION
1638   WHEN NO_DATA_FOUND THEN
1639     x_serial_number_type :=0;
1640 END;
1641 --End of Fix for bug # 5660272
1642 -- Fix for 5660272 to check for the validity of the serial number --
1643 PROCEDURE VALIDATE_SERIAL_STATUS
1644    (    x_status             OUT NOCOPY NUMBER,               -- 1 FOR SUCCESS AND ANY OTHER VALUE FOR FAILURE
1645         x_organization_code  OUT NOCOPY VARCHAR2,
1646         x_current_status     OUT NOCOPY VARCHAR2,
1647         p_serial_num         IN         VARCHAR2,
1648         p_organization_id    IN         NUMBER,
1649         p_subinventory_code  IN         VARCHAR2,
1650         p_locator_id         IN         NUMBER,
1651         p_inventory_item_id  IN         NUMBER,
1652         p_serial_number_type IN         NUMBER
1653     )
1654 IS
1655   l_valid_serial NUMBER := 0;
1656   l_debug NUMBER := NVL(FND_PROFILE.VALUE('INV_DEBUG_TRACE'),0);
1657 BEGIN
1658   x_status := 0;
1659 IF (l_debug = 1) THEN
1660     print_debug('Start Validating the serial for the current status');
1661   END IF;
1662   l_valid_serial := 0;
1663 
1664   /*
1665    * Checking if the serial number exist with same serial number in the same subinventory
1666    * organization and locator for the same item.
1667    * Bug# 6354645:
1668    * Added the condition to check for inventory_item_id as the same serial number can be assigned
1669    * to 2 different items in the same org/sub/locator if the serial uniqueness is 'Within Inventory Items'
1670    * This is to avoid TOO_MANY_ROWS_FOUND exception.
1671    */
1672   BEGIN
1673     SELECT      1,MP.ORGANIZATION_CODE,ML.MEANING
1674     INTO        l_valid_serial,x_organization_code,x_current_status
1675     FROM        MTL_SERIAL_NUMBERS MSN , MTL_PARAMETERS MP, MFG_LOOKUPS ML
1676     WHERE       SERIAL_NUMBER like p_serial_num
1677     AND         MSN.INVENTORY_ITEM_ID = p_inventory_item_id
1678     AND         MSN.CURRENT_ORGANIZATION_ID = p_organization_id
1679     AND         MSN.CURRENT_ORGANIZATION_ID = MP.ORGANIZATION_ID
1680     AND         MSN.CURRENT_STATUS = ML.LOOKUP_CODE
1681     AND         MSN.CURRENT_SUBINVENTORY_CODE like p_subinventory_code
1682     AND         NVL(MSN.CURRENT_LOCATOR_ID,-9999) = NVL(p_locator_id, -9999)
1683     AND         ML.LOOKUP_TYPE like 'SERIAL_NUM_STATUS'
1684     AND         CURRENT_STATUS = 3;
1685   EXCEPTION
1686   WHEN NO_DATA_FOUND THEN
1687     l_valid_serial :=0;
1688   END;
1689 
1690   -- If the serial number type is 0. Invalid serial Control Option, so error out. Very rare case.
1691   IF p_serial_number_type = 0 THEN
1692     x_status := -1;
1693     RETURN;
1694   END IF;
1695 
1696   --Changed the return value from -1 to 1. Because this will not be a error case. for bug 5903566
1697   IF  l_valid_serial = 1 THEN
1698     -- Serial Number is present in the org/subinv/loc given by user. Hence return Success.
1699     x_status := 1;
1700     RETURN;
1701 
1702   -- New Serial Given here. So check if it violates the serial Number Uniqueness logic.
1703   ELSIF l_valid_serial = 0 THEN
1704     IF p_serial_number_type = 3 THEN
1705       /*
1706        * If serial uniquiness is accross organizations (3)
1707        * serial should not exist anywhere
1708        */
1709       SELECT    MP.ORGANIZATION_CODE,ML.MEANING
1710       INTO      x_organization_code,x_current_status
1711       FROM      MTL_SERIAL_NUMBERS MSN, MTL_PARAMETERS MP,MFG_LOOKUPS ML
1712       WHERE     SERIAL_NUMBER like p_serial_num
1713       AND       MSN.CURRENT_ORGANIZATION_ID = MP.ORGANIZATION_ID
1714       AND       MSN.CURRENT_STATUS = ML.LOOKUP_CODE
1715       AND       ML.LOOKUP_TYPE like 'SERIAL_NUM_STATUS'
1716       AND       CURRENT_STATUS NOT IN (1,4);
1717     ELSIF p_serial_number_type IN (1,4) THEN
1718       /*
1719        * If serial uniquiness is within inventory (1,4)
1720        * serial should not exist in same org, same item
1721        */
1722        SELECT    MP.ORGANIZATION_CODE,ML.MEANING
1723        INTO      x_organization_code,x_current_status
1724        FROM      MTL_SERIAL_NUMBERS MSN, MTL_PARAMETERS MP,MFG_LOOKUPS ML
1725        WHERE     MSN.SERIAL_NUMBER like p_serial_num
1726        AND       MSN.INVENTORY_ITEM_ID = p_inventory_item_id
1727        AND       MSN.CURRENT_ORGANIZATION_ID = MP.ORGANIZATION_ID
1728        AND       MSN.CURRENT_STATUS = ML.LOOKUP_CODE
1729        AND       ML.LOOKUP_TYPE like 'SERIAL_NUM_STATUS'
1730        AND       CURRENT_STATUS NOT IN (1,4);
1731     ELSIF p_serial_number_type = 2 THEN
1732       /*
1733        * If serial uniquiness is within organization (2)
1734        * serial should first be unique within inventory items and
1735        * then within organizations.
1736        * Added the below condition because it could be the case that the
1737        * same serial could be assigned to the same item in a different org.
1738        */
1739       BEGIN
1740 
1741         SELECT  MP.ORGANIZATION_CODE,ML.MEANING
1742         INTO    x_organization_code,x_current_status
1743         FROM    MTL_SERIAL_NUMBERS MSN, MTL_PARAMETERS MP,MFG_LOOKUPS ML
1744         WHERE   MSN.SERIAL_NUMBER like p_serial_num
1745         AND     MSN.INVENTORY_ITEM_ID = p_inventory_item_id
1746         AND     MSN.CURRENT_ORGANIZATION_ID = MP.ORGANIZATION_ID
1747         AND     MSN.CURRENT_STATUS = ML.LOOKUP_CODE
1748         AND     ML.LOOKUP_TYPE like 'SERIAL_NUM_STATUS'
1749         AND     CURRENT_STATUS NOT IN (1,4);
1750 
1751         x_status := -1;
1752         RETURN;
1753       EXCEPTION
1754         WHEN NO_DATA_FOUND THEN
1755           NULL;-- SETTING NULL HERE TO EXECUTE THE SECOND QUERY.
1756       END;
1757       /*
1758        * If serial uniquiness is within organization (2)
1759        * serial should not exist in same org
1760        */
1761       SELECT    MP.ORGANIZATION_CODE,ML.MEANING
1762       INTO      x_organization_code,x_current_status
1763       FROM      MTL_SERIAL_NUMBERS MSN, MTL_PARAMETERS MP,MFG_LOOKUPS ML
1764       WHERE     MSN.SERIAL_NUMBER like p_serial_num
1765       AND       MSN.CURRENT_ORGANIZATION_ID = p_organization_id
1766       AND       MSN.CURRENT_ORGANIZATION_ID = MP. ORGANIZATION_ID
1767       AND       MSN.CURRENT_STATUS = ML.LOOKUP_CODE
1768       AND       ML.LOOKUP_TYPE like 'SERIAL_NUM_STATUS'
1769       AND       CURRENT_STATUS NOT IN (1,4);
1770 
1771     END IF;
1772   END IF;
1773   x_status := -1;
1774 EXCEPTION
1775   WHEN NO_DATA_FOUND THEN  -- No Data Found means the given new serial doesnt violate any of the serial uniqueness conditions.
1776     IF (l_debug = 1) THEN
1777       print_debug('Serial Number status is valid so go ahaead');
1778     END IF;
1779     x_status := 1;
1780 END  VALIDATE_SERIAL_STATUS;
1781 
1782 --End of Fix for bug # 5660272
1783 
1784 
1785 
1786 END INV_PHY_INV_LOVS;