DBA Data[Home] [Help]

PACKAGE BODY: APPS.INV_QUANTITY_TREE_PVT

Source


1 PACKAGE BODY inv_quantity_tree_pvt as
2 /* $Header: INVVQTTB.pls 120.27.12010000.6 2008/12/24 10:41:29 sanjeevs ship $*/
3 
4 g_pkg_name CONSTANT VARCHAR2(30) := 'INV_Quantity_Tree_PVT';
5 g_is_lot_control  BOOLEAN := FALSE;
6 /* Jalaj Srivastava Bug 5590287. g_not_initialized global var no longer used */
7 --g_not_initialized  BOOLEAN := TRUE;
8 
9 --
10 -- synonyms used in this program
11 --     qoh          quantity on hand
12 --     rqoh         reservable quantity on hand
13 --     qr           quantity reserved
14 --     att          available to transact
15 --     atr          available to reserve
16 -- invConv changes begin
17 --    sqoh          secondary quantity on hand
18 --    srqoh         secondary reservable quantity on hand
19 --    sqr           secondary quantity reserved
20 --    satt          secondary available to transact
21 --    satr          secondary available to reserve
22 -- invConv changes end
23 --------------------------------------------------
24 -- Data Types Definition
25 --------------------------------------------------
26 -- rootinfo_rec_type is the record type for a
27 -- record that points to a tree
28 TYPE rootinfo_rec_type IS RECORD
29   (   organization_id          NUMBER
30    ,  inventory_item_id        NUMBER
31    ,  is_DUOM_control          BOOLEAN             -- invConv changes
32    ,  is_revision_control      BOOLEAN
33    ,  is_lot_control           BOOLEAN
34    ,  is_serial_control        BOOLEAN
35    ,  is_lot_status_enabled    BOOLEAN
36    ,  neg_inv_allowed          BOOLEAN
37    ,  tree_mode                NUMBER
38    ,  include_suggestion       BOOLEAN
39    ,  asset_sub_only           BOOLEAN
40    ,  demand_source_type_id    NUMBER
41    ,  demand_source_header_id  NUMBER
42    ,  demand_source_line_id    NUMBER
43    ,  demand_source_name       VARCHAR2(30)
44    ,  demand_source_delivery   NUMBER
45    ,  asset_inventory_only     BOOLEAN
46    ,  lot_expiration_date      DATE
47    ,  grade_code               VARCHAR2(150)        -- invConv changes
48    ,  need_refresh             BOOLEAN
49    ,  item_node_index          INTEGER
50    ,  onhand_source            NUMBER
51    ,  pick_release             NUMBER
52    ,  hash_string              VARCHAR2(1000)
53    ,  unit_effective           NUMBER
54    );
55 --
56 TYPE rootinfo_tbl_type IS TABLE OF rootinfo_rec_type
57   INDEX BY BINARY_INTEGER;
58 --
59 -- tree level constants
60 g_item_level       CONSTANT INTEGER := 1;
61 g_revision_level   CONSTANT INTEGER := 2;
62 g_lot_level        CONSTANT INTEGER := 3;
63 g_sub_level        CONSTANT INTEGER := 4;
64 g_locator_level    CONSTANT INTEGER := 5;
65 g_lpn_level        CONSTANT INTEGER := 6;
66 g_cost_group_level CONSTANT INTEGER := 7;
67 --
68 
69 -- node_rec_type is the record type for
70 -- a tree node. It contains a superset of
71 -- attributes for revision,
72 -- invConv change : is_reservable_sub is NOW used as reservable flag for
73 --            each subinv, locator, lot, serial.
74 -- invConv note : this rec_type is not used anymore.
75 TYPE node_rec_type IS RECORD
76   (   node_level          INTEGER      -- qualifies the type of the node
77    ,  revision            VARCHAR2(3)  -- valid if the node is a revision node
78    ,  lot_number          VARCHAR2(80) -- valid if the node is a lot node    -- invConv change (size)
79    ,  subinventory_code   VARCHAR2(10) -- valid if the node is a sub node
80    ,  is_reservable_sub   BOOLEAN      -- valid if the node is reservable   -- invConv change (comment)
81    ,  locator_id          NUMBER       -- valid if the node is a locator node
82    ,  qoh                 NUMBER
83    ,  rqoh                NUMBER
84    ,  qr                  NUMBER
85    ,  qs                  NUMBER
86    ,  att                 NUMBER
87    ,  atr                 NUMBER
88    ,  pqoh                NUMBER     -- packed quantity on hand
89    ,  sqoh                NUMBER     -- invConv change
90    ,  srqoh               NUMBER     -- invConv change
91    ,  sqr                 NUMBER     -- invConv change
92    ,  sqs                 NUMBER     -- invConv change
93    ,  satt                NUMBER     -- invConv change
94    ,  satr                NUMBER     -- invConv change
95    ,  spqoh               NUMBER     -- packed quantity on hand     -- invConv change
96    ,  check_mark          BOOLEAN
97    ,  next_sibling_index  INTEGER
98    ,  first_child_index   INTEGER
99    ,  last_child_index    INTEGER
100    ,  parent_index        INTEGER
101    ,  lpn_id              NUMBER
102    ,  cost_group_id       NUMBER     -- valid if the node is a cost group node
103    ,  next_hash_record    NUMBER
104    ,  hash_string         VARCHAR2(300)              -- invConv change (size + 50 + 150)
105    ,  node_index          INTEGER    --used by backup/restore tree
106    ,  qs_adj1             NUMBER     --Bug 4294336
107    ,  sqs_adj1            NUMBER     --Bug 4294336
108    );
109 --
110 TYPE node_tbl_type IS TABLE OF node_rec_type
111   INDEX BY BINARY_INTEGER;
112 
113 --
114 --Bug 1384720 - performance improvement
115 -- record keeps track of demand info only
116 -- Now, each transaction which queries the quantity tree has a
117 --  different demand record.  But the underlying tree (root_id)
118 --  might be the same for all the demand records.  Multiple
119 --  demand records can reference the same tree (represented by root_id).
120 --
121 TYPE demandinfo_rec_type IS RECORD
122   (   root_id                  INTEGER
123    ,  tree_mode                NUMBER
124    ,  pick_release             NUMBER
125    ,  demand_source_type_id    NUMBER
126    ,  demand_source_header_id  NUMBER
127    ,  demand_source_line_id    NUMBER
128    ,  demand_source_name       VARCHAR2(30)
129    ,  demand_source_delivery   NUMBER
130    );
131 --
132 TYPE demand_tbl_type IS TABLE OF demandinfo_rec_type
133    INDEX BY BINARY_INTEGER;
134 --
135 --Bug 1384720 - performance improvement,
136 --  This record holds information about the reservations for a transaction.
137 TYPE rsvinfo_rec_type IS RECORD
138   (   revision            VARCHAR2(3)
139    ,  lot_number          VARCHAR2(80)                  -- invConv change (size)
140    ,  subinventory_code   VARCHAR2(10)
141    ,  locator_id          NUMBER
142    ,  lpn_id              NUMBER
143    ,  quantity            NUMBER
144    ,  secondary_quantity  NUMBER                        -- invCon change
145    );
146 --
147 TYPE rsvinfo_tbl_type IS TABLE OF rsvinfo_rec_type
148    INDEX BY BINARY_INTEGER;
149 
150 TYPE all_root_rec_type IS RECORD
151    (  root_id    NUMBER
152     , next_root  NUMBER
153     , last_root  NUMBER
154    );
155 
156 TYPE all_root_tbl_type IS TABLE OF all_root_rec_type
157    INDEX BY BINARY_INTEGER;
158 
159 TYPE backup_tree_rec_type IS RECORD
160    (  root_id    NUMBER
161     , first_node NUMBER
162     , last_node  NUMBER
163    );
164 
165 TYPE backup_tree_tbl_type IS TABLE of backup_tree_rec_type
166    INDEX BY BINARY_INTEGER;
167 
168 TYPE item_reservable_rec_type IS RECORD
169    (  value   BOOLEAN
170     , org_id  NUMBER
171    );
172 
173 -- Bug 5535030: PICK RELEASE PERFORMANCE ISSUES
174 TYPE sub_reservable_rec_type IS RECORD
175    (  reservable_type   NUMBER
176     , org_id            VARCHAR2(100)
177     , subinventory_code VARCHAR2(10)
178    );
179 
180 TYPE bulk_num_tbl_type IS TABLE OF NUMBER
181    INDEX BY BINARY_INTEGER;
182 TYPE bulk_date_tbl_type IS TABLE OF DATE
183    INDEX BY BINARY_INTEGER;
184 TYPE bulk_varchar_3_tbl_type IS TABLE OF VARCHAR2(3)
185    INDEX BY BINARY_INTEGER;
186 TYPE bulk_varchar_10_tbl_type IS TABLE OF VARCHAR2(10)
187    INDEX BY BINARY_INTEGER;
188 TYPE bulk_varchar_30_tbl_type IS TABLE OF VARCHAR2(30)
189    INDEX BY BINARY_INTEGER;
190 TYPE item_reservable_type IS TABLE OF item_reservable_rec_type
191    INDEX BY BINARY_INTEGER;
192 -- invConv changes begin : lot_number = 80char.
193 TYPE bulk_varchar_80_tbl_type IS TABLE OF VARCHAR2(80)
194    INDEX BY BINARY_INTEGER;
195 -- invConv changes end.
196 
197 -- Bug 5535030: PICK RELEASE PERFORMANCE ISSUES
198 TYPE sub_reservable_type IS TABLE OF sub_reservable_rec_type
199    INDEX BY BINARY_INTEGER;
200 
201 --------------------------------------------------
202 -- Global Variables
203 --------------------------------------------------
204 --
205 -- rootinfo array, counter and tree node array and counter
206 g_rootinfos                   rootinfo_tbl_type;      -- rootinfo array
207 g_nodes                       node_tbl_type;          -- tree node array
208 g_rootinfo_counter            INTEGER := 0;           -- size of rootinfo arry
209 g_org_item_trees              bulk_num_tbl_type;
210 g_all_roots                   all_root_tbl_type;
211 g_all_roots_counter           NUMBER := 0;
212 g_max_hash_rec                NUMBER := 0;
213 g_saveroots                   rootinfo_tbl_type;      -- savepoint rootinfos
214 g_savenodes                   node_tbl_type;          -- savepoint tree nodes
215 
216 g_save_rsv_tree_id  INTEGER :=0;            -- savepoint rsv tree id -- bug 6683013
217 g_save_rsv_counter  NUMBER := 0;            -- savepoint rsv counter -- bug 6683013
218 g_saversvnode       rsvinfo_tbl_type;       -- savepoint rsv nodes   -- bug 6683013
219 
220 
221 g_backup_trees                backup_tree_tbl_type;   --used by new backup_tree procedure
222 g_backup_nodes                node_tbl_type;          --used by new backup_tree procedure
223 
224 g_demand_info                 demand_tbl_type;
225 g_demand_counter              INTEGER := 0;
226 g_rsv_info                    rsvinfo_tbl_type;       -- all rsvs which are currently applied to the tree
227 g_rsv_counter                 INTEGER :=0;
228 g_rsv_tree_id                 INTEGER :=0;            -- tree for which rsv_info corresponds
229 
230 g_backup_tree_counter         INTEGER := 0;           --used by new backup_tree procedure
231 g_backup_node_counter         INTEGER := 0;           --used by new backup_tree procedure
232 
233 g_rsv_qty_counter             INTEGER := 0;
234 g_rsv_qty_node_level          bulk_num_tbl_type;
235 g_rsv_qty_revision            bulk_varchar_3_tbl_type;
236 g_rsv_qty_lot_number          bulk_varchar_80_tbl_type;      -- invConv change (size)
237 g_rsv_qty_subinventory_code   bulk_varchar_10_tbl_type;
238 g_rsv_qty_locator_id          bulk_num_tbl_type;
239 g_rsv_qty_lpn_id              bulk_num_tbl_type;
240 g_rsv_qty_cost_group_id       bulk_num_tbl_type;
241 g_rsv_qty_qoh                 bulk_num_tbl_type;
242 g_rsv_qty_atr                 bulk_num_tbl_type;
243 g_rsv_qty_sqoh                bulk_num_tbl_type;      -- invConv change
244 g_rsv_qty_satr                bulk_num_tbl_type;      -- invConv change
245 --
246 -- pjm support
247 --BENCHMARK - added unit effective info to tree node
248 g_unit_eff_enabled            VARCHAR(1) := NULL;
249 
250 --holds the Packed Quantity on hand for the last node queried using query_tree
251 g_pqoh                        NUMBER := NULL;
252 g_spqoh                       NUMBER := NULL;         -- invConv change
253 
254 -- dummy lpn_id for Loose quantities
255 g_loose_lpn_id                NUMBER := -99999;
256 
257 g_organization_id             NUMBER := NULL;
258 g_lock_timeout                NUMBER := NULL;
259 
260 g_hash_string                 VARCHAR2(1000) := NULL;
261 g_empty_root_index            NUMBER := NULL;
262 
263 --Variable indicating whether debugging is turned on
264 g_debug                       NUMBER := NULL;
265 
266 --Performance improvement, check whether it is a pick release session
267 g_is_pickrelease              BOOLEAN := FALSE;
268 
269 -- Added to improve performance of check_is_item_reservable procedure
270 g_is_item_reservable          item_reservable_type;
271 
272 -- Bug 5535030: PICK RELEASE PERFORMANCE ISSUES
273 g_is_sub_reservable           sub_reservable_type;
274 
275 -- SRSRIRAN Bug# 4666553
276 -- Added p_level parameter with default as 14
277 PROCEDURE print_debug(p_message IN VARCHAR2, p_level IN NUMBER DEFAULT 14) IS
278 BEGIN
279    IF g_debug IS NULL THEN
280       g_debug :=  NVL(FND_PROFILE.VALUE('INV_DEBUG_TRACE'),0);
281    END IF;
282 
283    IF (g_debug = 1) THEN
284       inv_log_util.trace(p_message, 'INV_QUANTITY_TREE_PVT', p_level);
285    END IF;
286 END;
287 
288 --------------------------------------------------
289 -- Private Procedures and Functions
290 --------------------------------------------------
291 
292 -- Function
293 --   demand_source_equals
294 -- Description
295 --   Compare whether two demand sources are the same.
296 -- Notes
297 --   The following condition is checked for equality
298 --   Point 1 is required, and if point 2 or 3 or 4 is true, the
299 --   answer is yes
300 --   1. p_demand_source_header_id1 and p_demand_source_header_id2
301 --      are equal and both not null
302 --   2. for demand_source_type_id of oe (2) or internal order (8)
303 --      , p_demand_source_header_id and demand_source_header_id are equal
304 ---     both not null, and p_demand_source_line_id and demand_source_line_id
305 --      are equal and both not null and p_demand_source_delivery and
306 --      demand_source_delivery are equals and both not null
307 --      and p_demand_source_name and demand_source_name are equal
308 --      or both null
309 --   or
310 --   3. for demand_source_type_id other than oe and internal order,
311 --      p_demand_source_header_id and demand_source_header_id are both null
312 --      and p_demand_source_name and demand_source_name are equal and both
313 --      not null
314 --   or
315 --   4. for demand_source_type_id other than oe and internal order,
316 --      p_demand_source_header_id and demand_source_header_id are equal
317 --      and both not null and p_demand_source_line_id are equal or both null
318 --      and p_demand_source_name and demand_source_name are equal or both
319 --      null
320 -- Return Value
321 --   'Y' if the two demand sources are the same; 'N' otherwise
322 Function demand_source_equals
323   (  p_demand_source_type_id1   NUMBER
324     ,p_demand_source_header_id1 NUMBER
325     ,p_demand_source_line_id1   NUMBER
326     ,p_demand_source_delivery1  NUMBER
327     ,p_demand_source_name1      VARCHAR2
328     ,p_demand_source_type_id2   NUMBER
329     ,p_demand_source_header_id2 NUMBER
330     ,p_demand_source_line_id2   NUMBER
331     ,p_demand_source_delivery2  NUMBER
332     ,p_demand_source_name2      VARCHAR2
333   ) RETURN VARCHAR2 IS
334      l_true  VARCHAR2(1) := 'Y';
335      l_false VARCHAR2(1) := 'F';
336 BEGIN
337    -- first check source type
338    IF   p_demand_source_type_id1 <> p_demand_source_type_id2
339      OR p_demand_source_type_id1 IS NOT NULL AND p_demand_source_type_id2 IS NULL
340      OR p_demand_source_type_id1 IS NULL     AND p_demand_source_type_id2 IS NOT NULL THEN
341       RETURN l_false;
342    END IF;
343    -- so here we have the same source type
344    -- check the rest
345    IF    p_demand_source_type_id1 IN (2,8)
346      AND p_demand_source_header_id1 = p_demand_source_header_id2
347      AND p_demand_source_line_id1 = p_demand_source_line_id2
348      AND p_demand_source_delivery1 = p_demand_source_delivery2
349      AND (p_demand_source_name1 = p_demand_source_name2
350           OR p_demand_source_name1 IS NULL
351           AND p_demand_source_name2 IS NULL) THEN
352       RETURN l_true;
353    ELSIF p_demand_source_header_id1 IS NULL
354      AND p_demand_source_header_id2 IS NULL
355      AND p_demand_source_name1 = p_demand_source_name2 THEN
356       RETURN l_true;
357    ELSIF p_demand_source_header_id1 = p_demand_source_header_id2
358      AND (p_demand_source_line_id1 = p_demand_source_line_id2
359           OR p_demand_source_line_id1 IS NULL
360           AND p_demand_source_line_id2 IS NULL)
361      AND (p_demand_source_name1 = p_demand_source_name2
362           OR p_demand_source_name1 IS NULL
363           AND p_demand_source_name2 IS NULL) THEN
364       RETURN l_true;
365    END IF;
366    --
367    RETURN l_false;
368 END;
369 --
370 
371 -- NO invConv change, because build_sql is obsolete.
372 -- Begin of build_sql
373 -------------------------------------------------------------------------------
374 -- Procedure                                                                 --
375 --   build_sql                                                               --
376 --                                                                           --
377 -- Description                                                               --
378 --   build the sql statement for the tree creation                           --
379 --                                                                           --
380 -- Notes                                                                     --
381 --   This procedure is also used by the pick and put away engine to build    --
382 --   the picking base sql                                                    --
383 --                                                                           --
384 -- Input Parameters                                                          --
385 --   p_mode                                                                  --
386 --     equals inv_quantity_tree_pvt.g_reservation_mode or                    --
387 --     inv_quantity_tree_pvt.g_transaction_mode                              --
388 --   p_is_lot_control                                                        --
389 --     true or false                                                         --
390 --   p_asset_sub_only                                                        --
391 --     true or false                                                         --
392 --   p_include_suggestion                                                    --
393 --     always true now
394 --   p_lot_expiration_date                                                   --
395 --     if not null, only consider lots that will not expire at the date      --
396 --     or ealier                                                             --
397 --                                                                           --
398 -- Output Parameters                                                         --
399 --   x_return_status                                                         --
400 --     standard output parameter. Possible values are                        --
401 --     1. fnd_api.g_ret_sts_success     for success                          --
402 --     2. fnd_api.g_ret_sts_exc_error   for expected error                   --
403 --     3. fnd_api.g_ret_sts_unexp_error for unexpected error                 --
404 -------------------------------------------------------------------------------
405 PROCEDURE build_sql
406   (
407      x_return_status       OUT NOCOPY VARCHAR2
408    , p_mode                IN  INTEGER
409    , p_is_lot_control      IN  BOOLEAN
410    , p_asset_sub_only      IN  BOOLEAN
411    , p_include_suggestion  IN  BOOLEAN  -- now it is ignored and the code always include suggestions
412    , p_lot_expiration_date IN  DATE
413    , p_onhand_source    IN  NUMBER
414    , p_pick_release     IN  NUMBER
415    , x_sql_statement       OUT NOCOPY long
416    , p_is_revision_control IN  BOOLEAN
417    ) IS
418       l_return_status        VARCHAR2(1) := fnd_api.g_ret_sts_success;
419       --
420       l_stmt                 long;
421       l_asset_sub_where      long;
422       l_revision_select      long;
423       l_lot_select           long;
424       l_lot_select2          long;
425       l_lot_from             long;
426       l_lot_where            long;
427       l_lot_expiration_where long;
428       l_lot_group            long;
429       l_reservable_where     long;
430       l_reservation_where    long;
431       l_onhand_source_where  long;
432 
433       --
434       l_reservation_stmt     long;
435       l_onhand_stmt          long;
436       l_pending_txn_stmt     long;
437       l_suggestion_stmt      long;
438       l_temp_sugg_txn_stmt   long;
439       l_onhand_qty_part      VARCHAR2(3000);
440       l_mmtt_qty_part        VARCHAR2(3000);
441       l_mtlt_qty_part        VARCHAR2(3000);
442 BEGIN
443 
444    --Bug 4294336
445    --The following three columns have been additionally selected
446    --transaction_action_id , transfer_subinventory_code and transfer_locator_id
447 
448    -- pjm support
449    --
450    --bug 2363739 - added call to pjm_unit_eff.unit_item_effective in
451    -- build cursor, so that if build_sql is called from within the
452    -- quantity tree API, g_unit_eff_enabled is already populated.
453    -- However, we need to keep this check here since build_sql
454    -- could be called by outside APIs.
455    IF g_unit_eff_enabled IS NULL THEN
456       SELECT pjm_unit_eff.enabled INTO g_unit_eff_enabled FROM dual;
457    END IF;
458    IF g_unit_eff_enabled <> 'Y' THEN
459       l_onhand_qty_part := ' moq.primary_transaction_quantity ';
460       l_mmtt_qty_part := ' mmtt.primary_quantity ';
461       l_mtlt_qty_part := ' mtlt.primary_quantity ';
462     ELSE
463       l_onhand_qty_part := ' decode(:demand_source_line_id, NULL,
464    sum(moq.primary_transaction_quantity), pjm_ueff_onhand.onhand_quantity
465    (:demand_source_line_id,moq.inventory_item_id,moq.organization_id
466     ,moq.revision,moq.subinventory_code,moq.locator_id,moq.lot_number,moq.lpn_id,moq.cost_group_id)
467    ) ';
468       l_mmtt_qty_part := ' decode(:demand_source_line_id, NULL, mmtt.primary_quantity, Nvl(pjm_ueff_onhand.txn_quantity(:demand_source_line_id,mmtt.transaction_temp_id,mmtt.lot_number,
469    ''Y'',mmtt.inventory_item_id, mmtt.organization_id, mmtt.transaction_source_type_id,
470    mmtt.transaction_source_id, mmtt.rcv_transaction_id,
471    sign(mmtt.primary_quantity)
472         ),mmtt.primary_quantity)) ';
473       l_mtlt_qty_part := ' decode(:demand_source_line_id, NULL, mtlt.primary_quantity, Nvl(pjm_ueff_onhand.txn_quantity(:demand_source_line_id,mmtt.transaction_temp_id,mtlt.lot_number,
474    ''Y'',mmtt.inventory_item_id, mmtt.organization_id, mmtt.transaction_source_type_id,
475    mmtt.transaction_source_id, mmtt.rcv_transaction_id,
476    sign(mmtt.primary_quantity)
477    ) ,mtlt.primary_quantity)) ';
478    END IF;
479    --
480    --bug 1384720 - performance improvments
481    -- build only one tree for both reservation and txn mode
482    -- deal with reservations
483    --IF p_mode IN (g_transaction_mode, g_loose_only_mode) THEN
484    IF p_mode IN (g_loose_only_mode) THEN
485       -- the following is modified to simplify the logic
486       -- bitang, 1/18/2000
487       -- Bug 2346202: Changed the NVL value to -9999 as that is the
488       --   value which is defaulted if these values are not passed
489       --   in INVPQTTB.pls.
490       l_reservation_where := '
491    AND NOT
492    ( :demand_source_type_id = mr.demand_source_type_id AND
493      :demand_source_header_id = mr.demand_source_header_id AND
494      Nvl(:demand_source_line_id, -9999) = Nvl(mr.demand_source_line_id,-9999) AND
495      Nvl(:demand_source_name, ''@@@###@@#'') = Nvl(mr.demand_source_name,''@@@###@@#'') AND
496      Nvl(:demand_source_delivery,-9999) = Nvl(mr.demand_source_delivery,-9999)
497       ';
498        -- In pick release, we should never pick from staging locations.
499        -- Thus, even if the quantity in a staging locator is reserved
500        -- for this transaction, it should not appear as available. So
501        -- ignore reservations only if staging_flag = N.  Bug 1402426
502        if p_pick_release = g_pick_release_yes THEN
503           l_reservation_where := l_reservation_where ||
504            ' AND Nvl(mr.staged_flag, ''N'') = ''N''
505       )';
506        else
507           l_reservation_where := l_reservation_where || ')';
508        end if;
509    -- in no lpn rsvs mode, don't include reservations against an LPN.
510    ELSIF p_mode = g_no_lpn_rsvs_mode THEN
511       l_reservation_where := '
512         AND mr.lpn_id IS NULL';
513    ELSE
514       l_reservation_where := NULL;
515    END IF;
516    --
517    -- the quantity type for reservation should be 3, which means
518    -- resevation for other demands. In reservation mode, all existing reservations
519    -- should be considered in the quantity computation.
520    -- bitang, 1/18/2000
521    l_reservation_stmt := '
522      -- reservations
523      SELECT
524           mr.organization_id                   organization_id
525         , mr.inventory_item_id                 inventory_item_id
526         , mr.revision                          revision
527         , mr.lot_number                        lot_number
528         , mr.subinventory_code                 subinventory_code
529         , mr.locator_id                        locator_id
530         , mr.primary_reservation_quantity
531            - Nvl(mr.detailed_quantity,0)       primary_quantity
532         , To_date(NULL)                        date_received
533         , 3                                    quantity_type
534         , to_number(NULL)            cost_group_id
535         , lpn_id               lpn_id
536         , to_number(NULL)                      transaction_action_id
537         , to_char(NULL)                        transfer_subinventory_code
538         , to_number(NULL)                      transfer_locator_id
539      FROM mtl_reservations mr
540      WHERE
541           Nvl(mr.supply_source_type_id, 13) = 13
542       AND mr.primary_reservation_quantity > Nvl(mr.detailed_quantity,0) '
543         || l_reservation_where;
544 
545    -- deal with onhand quantities
546    -- if containerized_flag is 1, then quantity is in container(s)
547    l_onhand_stmt := '
548      UNION ALL
549      -- onhand quantities
550      SELECT
551           moq.organization_id                  organization_id
552         , moq.inventory_item_id                inventory_item_id
553         , moq.revision                         revision
554         , moq.lot_number                       lot_number
555         , moq.subinventory_code                subinventory_code
556         , moq.locator_id                       locator_id
557         , ' || l_onhand_qty_part || '
558         , To_date(NULL)                        date_received
559         , 1                                    quantity_type
560    , moq.cost_group_id                    cost_group_id
561    , moq.lpn_id                lpn_id
562         , to_number(NULL)                      transaction_action_id
563         , to_char(NULL)                        transfer_subinventory_code
564         , to_number(NULL)                      transfer_locator_id
565      FROM
566           mtl_onhand_quantities_detail       moq ';
567 
568 
569    -- dealing with pending transactions in mmtt
570    -- and picking suggestions
571    --
572    -- Notes: the put away suggestions are not considered either
573    -- as reservation nor as pending transactions because of the
574    -- way the integration between reservation and suggestion
575    -- is currently implemented. A put away suggestion with transaction_status
576    -- as 2, is not a reservation since the corresponding quantity
577    -- has not been moved to the destination; it is not a pending
578    -- transaction because the quantity that will be moved from source
579    -- location to destination location is not available as onhand.
580    -- The reason is that once it is moved, the pick confirm process might transfer
581    -- an existing reservation for that quantity to the new destination.
582    --
583    -- WARNING: the value of transaction_action_id is used to
584    -- decide whether a suggestion is a picking or it is a
585    -- put away, so any changes to the transaction id
586    -- should be reflected in the decode portion in the where clause
587    IF p_is_lot_control THEN
588       -- here we assume that even there is only one lot number
589       -- involved in a transaction, a child record would be
590       -- created in the mtl_transaction_lots_temp table.
591       l_pending_txn_stmt := '
592        UNION ALL
593    -- pending transactions and picking suggestions
594    -- in mmtt with lot number in mmtt
595    --changed by jcearley on 12/8/99
596    --added 1 to decode statement so that we make sure the
597    --issue qtys in mmtt are seen as negative.
598    --This problem arose because create_suggestions stores
599    --the suggested transactions in mmtt as a positive number.
600    --changed by jcearley on 2/24/00
601    --added decode stmt to quantity_type.  If record is a
602    --suggestion, qty-type is 5 (txn suggestion).  If it is
603    --a pending txn, qty_type is 1 (quantity on hand).
604         --also, added another decode stmt to primary qty.  If the
605    --record is a suggestion, we want the primary_qty to be positive,
606    --like a reservation
607         --
608    -- added 5/23/00
609         -- if quantity is in an lpn, then it is containerized
610         -- Bug 2127112 - packed mmtt recs can have either lpn_id or
611         --   content lpn_id populated. To handle this, changed
612         -- how containerized is determined for MMTT recs. Assuming
613         -- that lpn_Id and content_lpn_id are always positive,
614         -- the existence of either causes containerized to be 1 (since
615         -- lpn_id will be greater than 1).  If both are null,
616         -- containerized will be 0 (0 is less than 1).
617        SELECT
618             mmtt.organization_id                 organization_id
619           , mmtt.inventory_item_id               inventory_item_id
620           , mmtt.revision                        revision
621           , mmtt.lot_number                      lot_number
622           , mmtt.subinventory_code               subinventory_code
623           , mmtt.locator_id                      locator_id
624           , Decode (mmtt.transaction_status, 2, 1
625         , Decode(mmtt.transaction_action_id
626           , 1, -1, 2, -1, 28, -1, 3, -1, 5, -1,
627                Sign(mmtt.primary_quantity))
628        )
629        * round(Abs('|| l_mmtt_qty_part || '), 5)
630           , Decode(mmtt.transaction_action_id
631              , 1, To_date(NULL)
632              , 2, To_date(NULL)
633              , 28, To_date(NULL)
634              , 3, To_date(NULL)
635              , 5, To_date(NULL)
636              , Decode(Sign(mmtt.primary_quantity)
637                   , -1, To_date(NULL)
638                   , mmtt.transaction_date))      date_received
639           , Decode(mmtt.transaction_status, 2, 5, 1)  quantity_type
640           , mmtt.cost_group_id               cost_group_id
641           , NVL(mmtt.allocated_lpn_id,NVL(mmtt.content_lpn_id,mmtt.lpn_id)) lpn_id
642           , Decode(mmtt.transaction_status, 2 , mmtt.transaction_action_id, to_number(NULL)) transaction_action_id
643           , Decode(mmtt.transaction_status, 2 , mmtt.transfer_subinventory, to_char(NULL)) transfer_subinventory_code
644           , Decode(mmtt.transaction_status, 2 , mmtt.transfer_to_location, to_number(NULL))  transfer_locator_id
645        FROM
646             mtl_material_transactions_temp mmtt
647        WHERE
648              mmtt.posting_flag = ''Y''
649     AND mmtt.lot_number IS NOT NULL
650     AND mmtt.subinventory_code IS NOT NULL
651     AND (Nvl(mmtt.transaction_status,0) <> 2 OR -- pending txns
652          -- only picking side of the suggested transactions are used
653          Nvl(mmtt.transaction_status,0) = 2 AND
654          mmtt.transaction_action_id IN (1,2,28,3,21,29,32,34)
655          )
656          -- dont look at scrap and costing txns
657          AND mmtt.transaction_action_id NOT IN (24,30)
658 
659        UNION ALL
660         -- pending transactions and suggestions in mmtt with lot numbers in lots_temp
661    --changed by jcearley on 12/8/99
662    --added 1 to decode statement so that we make sure the
663    --issue qtys in mmtt are seen as negative.
664    --This problem arose because create_suggestions stores
665    --the suggested transactions in mmtt as a positive number.
666    -- added 5/23/00
667         -- if quantity is in an lpn, then it is containerized.
668         -- Bug 2127112 - packed mmtt recs can have either lpn_id or
669         --   content lpn_id populated. To handle this, changed
670         -- how containerized is determined for MMTT recs. Assuming
671         -- that lpn_Id and content_lpn_id are always positive,
672         -- the existence of either causes containerized to be 1 (since
673         -- lpn_id will be greater than 1).  If both are null,
674         -- containerized will be 0 (0 is less than 1).
675        SELECT
676             mmtt.organization_id                 organization_id
677           , mmtt.inventory_item_id               inventory_item_id
678           , mmtt.revision                        revision
679           , mtlt.lot_number                      lot_number
680           , mmtt.subinventory_code               subinventory_code
681           , mmtt.locator_id                      locator_id
682           , Decode(mmtt.transaction_status, 2, 1
683        , Decode(mmtt.transaction_action_id
684          , 1, -1, 2, -1, 28, -1, 3, -1, 5, -1,
685          Sign(mmtt.transaction_quantity))
686             )
687        * round(abs('||l_mtlt_qty_part||'),5)
688           , Decode(mmtt.transaction_action_id
689              , 1, To_date(NULL)
690              , 2, To_date(NULL)
691              , 28, To_date(NULL)
692              , 3, To_date(NULL)
693              , 5, To_date(NULL)
694              , Decode(Sign(mmtt.primary_quantity)
695                   , -1, To_date(NULL)
696                   , mmtt.transaction_date))      date_received
697           , Decode(mmtt.transaction_status, 2, 5, 1)  quantity_type
698           , mmtt.cost_group_id          cost_group_id
699           , NVL(mmtt.allocated_lpn_id,NVL(mmtt.content_lpn_id,mmtt.lpn_id)) lpn_id
700           , Decode(mmtt.transaction_status, 2 , mmtt.transaction_action_id, to_number(NULL)) transaction_action_id
701           , Decode(mmtt.transaction_status, 2 , mmtt.transfer_subinventory, to_char(NULL)) transfer_subinventory_code
702           , Decode(mmtt.transaction_status, 2 , mmtt.transfer_to_location, to_number(NULL))  transfer_locator_id
703        FROM
704             mtl_material_transactions_temp mmtt
705           , mtl_transaction_lots_temp      mtlt
706        WHERE
707               mmtt.posting_flag = ''Y''
708      AND mmtt.transaction_temp_id = mtlt.transaction_temp_id
709      AND mmtt.lot_number IS NULL
710      AND mmtt.subinventory_code IS NOT NULL
711      AND (Nvl(mmtt.transaction_status,0) <> 2 OR -- pending txns
712          -- only picking side of the suggested transactions are used
713          Nvl(mmtt.transaction_status,0) = 2 AND
714          mmtt.transaction_action_id IN (1,2,28,3,21,29,32,34)
715          )
716          -- dont look at scrap and costing txns
717          AND mmtt.transaction_action_id NOT IN (24,30)
718        UNION ALL
719        -- receiving side of transfers with lot numbers in lots_temp
720        -- added 5/23/00
721        -- if quantity is in an lpn, then it is containerized
722        SELECT
723             Decode(mmtt.transaction_action_id
724                , 3, mmtt.transfer_organization
725                , mmtt.organization_id)           organization_id
726           , mmtt.inventory_item_id               inventory_item_id
727           , mmtt.revision                        revision
728           , mtlt.lot_number                      lot_number
729           , mmtt.transfer_subinventory           subinventory_code
730      , mmtt.transfer_to_location            locator_id
731      , round(Abs('||l_mtlt_qty_part||') ,5)
732           , mmtt.transaction_date                date_received
733           , 1                                    quantity_type
734           , mmtt.transfer_cost_group_id       cost_group_id
735      , NVL(mmtt.content_lpn_id,mmtt.transfer_lpn_id) lpn_id
736           , to_number(NULL)                      transaction_action_id
737           , to_char(NULL)                        transfer_subinventory_code
738           , to_number(NULL)                      transfer_locator_id
739 
740        FROM
741             mtl_material_transactions_temp mmtt
742           , mtl_transaction_lots_temp      mtlt
743        WHERE
744               mmtt.posting_flag = ''Y''
745           AND mmtt.transaction_action_id IN (2,28,3,5)
746           AND mmtt.lot_number IS NULL
747           AND mmtt.transaction_temp_id = mtlt.transaction_temp_id
748           AND Nvl(mmtt.transaction_status,0) <> 2 -- pending txns only
749          -- dont look at scrap and costing txns
750           AND mmtt.transaction_action_id NOT IN (24,30)
751          -- receiving side of transfers with lot number in MMTT
752          -- added 5/23/00
753          -- if quantity is in an lpn, then it is containerized
754        UNION ALL
755        SELECT
756             Decode(mmtt.transaction_action_id
757                , 3, mmtt.transfer_organization
758                , mmtt.organization_id)           organization_id
759           , mmtt.inventory_item_id               inventory_item_id
760           , mmtt.revision                        revision
761           , mmtt.lot_number                      lot_number
762           , mmtt.transfer_subinventory           subinventory_code
763           , mmtt.transfer_to_location            locator_id
764           , round(Abs('||l_mmtt_qty_part||'),5)
765           , mmtt.transaction_date                date_received
766           , 1                                    quantity_type
767           , mmtt.transfer_cost_group_id       cost_group_id
768      , NVL(mmtt.content_lpn_id,mmtt.transfer_lpn_id) lpn_id
769           , to_number(NULL)                      transaction_action_id
770           , to_char(NULL)                        transfer_subinventory_code
771           , to_number(NULL)                      transfer_locator_id
772        FROM
773             mtl_material_transactions_temp mmtt
774        WHERE
775               mmtt.posting_flag = ''Y''
776           AND mmtt.transaction_action_id IN (2,28,3,5)
777      AND Nvl(mmtt.transaction_status,0) <> 2 -- pending txns only
778          -- dont look at scrap and costing txns
779          AND mmtt.transaction_action_id NOT IN (24,30)
780           AND mmtt.lot_number IS NOT NULL ';
781      ELSE  -- without lot control
782       l_pending_txn_stmt := '
783        UNION ALL
784        -- pending transactions in mmtt
785    --changed by jcearley on 12/8/99
786    --added 1 to decode statement so that we make sure the
787    --issue qtys in mmtt are seen as negative.
788    --This problem arose because create_suggestions stores
789    --the suggested transactions in mmtt as a positive number.
790        -- added 5/23/00
791        -- if quantity is in an lpn, then it is containerized
792         -- Bug 2127112 - packed mmtt recs can have either lpn_id or
793         --   content lpn_id populated. To handle this, changed
794         -- how containerized is determined for MMTT recs. Assuming
795         -- that lpn_Id and content_lpn_id are always positive,
796         -- the existence of either causes containerized to be 1 (since
797         -- lpn_id will be greater than 1).  If both are null,
798         -- containerized will be 0 (0 is less than 1).
799        SELECT
800             mmtt.organization_id                 organization_id
801           , mmtt.inventory_item_id               inventory_item_id
802           , mmtt.revision                        revision
803           , NULL                                 lot_number
804           , mmtt.subinventory_code               subinventory_code
805           , mmtt.locator_id                      locator_id
806           , Decode(mmtt.transaction_status, 2, 1
807        , Decode(mmtt.transaction_action_id
808          , 1, -1, 2, -1, 28, -1, 3, -1, 5, -1,
809       Sign(mmtt.primary_quantity))
810        )
811        * round(Abs('|| l_mmtt_qty_part || '),5)
812           , Decode(mmtt.transaction_action_id
813              , 1, To_date(NULL)
814              , 2, To_date(NULL)
815              , 28, To_date(NULL)
816              , 3, To_date(NULL)
817              , 5, To_date(NULL)
818              , Decode(Sign(mmtt.primary_quantity)
819                   , -1, To_date(NULL)
820                   , mmtt.transaction_date))      date_received
821           , Decode(mmtt.transaction_status, 2, 5, 1) quantity_type
822           , mmtt.cost_group_id       cost_group_id
823           , NVL(mmtt.allocated_lpn_id,NVL(mmtt.content_lpn_id,mmtt.lpn_id)) lpn_id
824           , Decode(mmtt.transaction_status, 2 , mmtt.transaction_action_id, to_number(NULL)) transaction_action_id
825           , Decode(mmtt.transaction_status, 2 , mmtt.transfer_subinventory, to_char(NULL)) transfer_subinventory_code
826           , Decode(mmtt.transaction_status, 2 , mmtt.transfer_to_location, to_number(NULL))  transfer_locator_id
827        FROM
828             mtl_material_transactions_temp mmtt
829        WHERE
830               mmtt.posting_flag = ''Y''
831      AND mmtt.subinventory_code IS NOT NULL
832      AND (Nvl(mmtt.transaction_status,0) <> 2 OR -- pending txns
833          -- only picking side of the suggested transactions are used
834          Nvl(mmtt.transaction_status,0) = 2 AND
835          mmtt.transaction_action_id IN (1,2,28,3,21,29,32,34)
836          )
837          -- dont look at scrap and costing txns
838          AND mmtt.transaction_action_id NOT IN (24,30)
839        UNION ALL
840        -- receiving side of transfers
841        -- added 5/23/00
842        -- if quantity is in an lpn, then it is containerized
843        SELECT
844             Decode(mmtt.transaction_action_id
845                , 3, mmtt.transfer_organization
846                , mmtt.organization_id)           organization_id
847           , mmtt.inventory_item_id               inventory_item_id
848           , mmtt.revision                        revision
849           , NULL                                 lot_number
850           , mmtt.transfer_subinventory           subinventory_code
851           , mmtt.transfer_to_location            locator_id
852           , round(Abs('||l_mmtt_qty_part||'),5)
853           , mmtt.transaction_date                date_received
854           , 1                                    quantity_type
855           , mmtt.transfer_cost_group_id          cost_group_id
856      , NVL(mmtt.content_lpn_id,mmtt.transfer_lpn_id) lpn_id
857           , to_number(NULL)                      transaction_action_id
858           , to_char(NULL)                        transfer_subinventory_code
859           , to_number(NULL)                      transfer_locator_id
860        FROM
861             mtl_material_transactions_temp mmtt
862        WHERE
863               mmtt.posting_flag = ''Y''
864      AND Nvl(mmtt.transaction_status,0) <> 2 -- pending txns only
865           AND mmtt.transaction_action_id IN (2,28,3,5) ';
866    END IF;
867 
868    -- common restrictions
869    IF p_asset_sub_only THEN
870       l_asset_sub_where := '
871         AND Nvl(sub.asset_inventory,1) = 1';
872     ELSE
873       l_asset_sub_where := NULL;
874    END IF;
875    l_onhand_source_where := NULL;
876    IF p_onhand_source IN (g_atpable_only,g_atpable_nettable_only) THEN
877    l_onhand_source_where := '
878     AND Nvl(sub.inventory_atp_code, 1) = 1';
879    END IF;
880    IF p_onhand_source IN (g_nettable_only,g_atpable_nettable_only) THEN
881    l_onhand_source_where := l_onhand_source_where || '
882     AND Nvl(sub.availability_type, 1) = 1';
883    END IF;
884 
885    --bug 1384720 - performanc improvements
886    -- need 2 lot selects - one for inner query, one for outer
887    IF p_is_lot_control THEN
888       l_lot_select := '
889         , x.lot_number            lot_number ';
890       l_lot_select2 := '
891         , lot.expiration_date     lot_expiration_date';
892       l_lot_from := '
893         , mtl_lot_numbers  lot';
894       l_lot_where := '
895         AND x.organization_id   = lot.organization_id   (+)
896         AND x.inventory_item_id = lot.inventory_item_id (+)
897         AND x.lot_number        = lot.lot_number        (+) ';
898       l_lot_group := '
899         , x.lot_number ';
900     ELSE
901       l_lot_select := '
902         , NULL                    lot_number';
903       l_lot_select2 := '
904         , To_date(NULL)           lot_expiration_date';
905       l_lot_from := NULL;
906       l_lot_where := NULL;
907       l_lot_group := NULL;
908    END IF;
909 
910    IF p_is_lot_control AND p_lot_expiration_date IS NOT NULL THEN
911       l_lot_expiration_where := '
912         AND (lot.expiration_date IS NULL OR
913              lot.expiration_date > :lot_expiration_date) ';
914     ELSE
915       l_lot_expiration_where := NULL;
916    END IF;
917 
918    --Bug 1830809 - If revision control is passed in a No, set
919    -- revision to be NULL.
920    IF p_is_revision_control THEN
921       l_revision_select := '
922         , x.revision            revision';
923    ELSE
924       l_revision_select := '
925         , NULL                  revision';
926    END IF;
927 
928 /* --bug 1384720 - performance improvements
929    -- do not build special tree for rsv mode
930    IF p_mode = inv_quantity_tree_pvt.g_reservation_mode THEN
931       l_reservable_where := '
932         AND Nvl(sub.reservable_type,1) = 1 ';
933     ELSE
934       l_reservable_where := NULL;
935    END IF;
936 */
937    --bug 1384720
938    -- Moved group by statement into subquery.  This minimizes
939    -- the number of joins to the lot and sub tables.
940 
941   -- bug 2752979 : adding group by to l_onhand_stmt for only PJM unit eff items.
942 
943   IF g_unit_eff_enabled = 'Y' THEN
944      l_onhand_stmt := l_onhand_stmt ||
945                         'GROUP BY moq.organization_id,moq.inventory_item_id,moq.revision,
946                                   moq.subinventory_code,moq.locator_id,moq.lot_number,moq.lpn_id,
947                                   moq.cost_group_id, moq. transaction_action_id
948                                   moq.transfer_subinventory_code, moq.transfer_locator_id ' ;
949   END IF;
950 
951 
952    l_stmt := '
953      SELECT
954           x.organization_id       organization_id
955         , x.inventory_item_id     inventory_item_id
956         , x.revision              revision
957    , x.lot_number      lot_number '
958         || l_lot_select2 || '
959         , x.subinventory_code     subinventory_code
960         , sub.reservable_type     reservable_type
961         , x.locator_id            locator_id
962         , x.primary_quantity      primary_quantity
963         , x.date_received         date_received
964         , x.quantity_type         quantity_type
965         , x.cost_group_id         cost_group_id
966         , x.lpn_id        lpn_id
967         , x.transaction_action_id       transaction_action_id
968         , x.transfer_subinventory_code  transfer_subinventory_code
969         , x.transfer_locator_id         transfer_locator_id
970      FROM (
971        SELECT
972            x.organization_id       organization_id
973          , x.inventory_item_id     inventory_item_id '
974          || l_revision_select || l_lot_select || '
975          , x.subinventory_code     subinventory_code
976          , x.locator_id            locator_id
977          , SUM(x.primary_quantity) primary_quantity
978          , MIN(x.date_received)    date_received
979          , x.quantity_type         quantity_type
980          , x.cost_group_id         cost_group_id
981          , x.lpn_id        lpn_id
982          , x.transaction_action_id       transaction_action_id
983          , x.transfer_subinventory_code  transfer_subinventory_code
984          , x.transfer_locator_id         transfer_locator_id
985         FROM (' || l_reservation_stmt
986           || l_onhand_stmt
987           || l_pending_txn_stmt
988           || l_suggestion_stmt
989                || l_temp_sugg_txn_stmt || '
990              ) x
991         WHERE x.organization_id    = :organization_id
992           AND x.inventory_item_id  = :inventory_item_id
993         GROUP BY
994            x.organization_id, x.inventory_item_id, x.revision '
995           || l_lot_group || '
996           , x.subinventory_code, x.locator_id
997           , x.quantity_type, x.cost_group_id, x.lpn_id
998           , x.transaction_action_id , x.transfer_subinventory_code
999           , x.transfer_locator_id
1000        ) x
1001         , mtl_secondary_inventories sub '
1002         || l_lot_from || '
1003      WHERE
1004         x.organization_id    = sub.organization_id          (+)
1005         AND x.subinventory_code  = sub.secondary_inventory_name (+) '
1006         || l_lot_where || l_lot_expiration_where || l_asset_sub_where
1007         || l_onhand_source_where || l_reservable_where  ;
1008 
1009    --inv_pp_debug.send_long_to_pipe(l_stmt);
1010    x_return_status := l_return_status;
1011    x_sql_statement := l_stmt;
1012 
1013 EXCEPTION
1014     WHEN OTHERS THEN
1015     x_return_status := fnd_api.g_ret_sts_unexp_error;
1016 END build_sql;
1017 -- End of build_sql .. NO invConv change.
1018 
1019 procedure showsql( p_sql_text IN long )
1020   IS
1021      p_n NUMBER;
1022      p_v VARCHAR2(1);
1023 BEGIN
1024    --dbm_s_output.enable(5000000);
1025    --FOR p_n IN 1..length(p_sql_text) LOOP
1026    --   p_v := Substr(p_sql_text,p_n,1);
1027    --   IF p_v = Chr(10) THEN
1028    --      dbm_s_output.new_line;
1029    --    ELSE
1030    --  dbm_s_output.put(p_v);
1031    --   END IF;
1032    --END LOOP;
1033    --dbm_s_output.new_line;
1034 --EXCEPTION
1035    --WHEN OTHERS THEN
1036    --   NULL;
1037    NULL;
1038 END showsql;
1039 
1040 -- NO invConv change, because build_cursor is obsolete.
1041 -- Benchmark - obsolete
1042 -- Procedure
1043 --   build_cursor
1044 -- Description
1045 --   this procedure calls the build_sql procedure to get the sql statment and
1046 --   parse it, bind variables, and return the cursor
1047 -- NO invConv change, because build_cursor is obsolete.
1048 PROCEDURE build_cursor
1049   (
1050      x_return_status           OUT NOCOPY VARCHAR2
1051    , p_organization_id         IN  NUMBER
1052    , p_inventory_item_id       IN  NUMBER
1053    , p_mode                    IN  INTEGER
1054    , p_demand_source_type_id   IN  NUMBER   DEFAULT NULL
1055    , p_demand_source_header_id IN  NUMBER   DEFAULT NULL
1056    , p_demand_source_line_id   IN  NUMBER   DEFAULT NULL
1057    , p_demand_source_name      IN  VARCHAR2 DEFAULT NULL
1058    , p_demand_source_delivery  IN  NUMBER   DEFAULT NULL
1059    , p_is_lot_control          IN  BOOLEAN
1060    , p_asset_sub_only          IN  BOOLEAN
1061    , p_include_suggestion      IN  BOOLEAN
1062    , p_lot_expiration_date     IN  DATE
1063    , p_onhand_source        IN  NUMBER
1064    , p_pick_release         IN  NUMBER
1065    , x_cursor                  OUT NOCOPY NUMBER
1066    , p_is_revision_control     IN  BOOLEAN DEFAULT TRUE
1067    ) IS
1068       l_return_status       VARCHAR2(1) := fnd_api.g_ret_sts_success;
1069       l_cursor              NUMBER;
1070       l_sql                 LONG;
1071       l_last_error_pos      NUMBER;
1072       l_temp_str            VARCHAR2(30);
1073       l_err                 VARCHAR2(240);
1074       l_pos                 NUMBER;
1075 BEGIN
1076    l_cursor := dbms_sql.open_cursor;
1077 
1078    --bug 2363739 - we now call unit_effective_item instead of
1079    -- enabled in the pjm_unit_eff API.  This will improve performance
1080    -- by limiting the number of times we use the PJM function to determine
1081    -- onhand quantity in build_sql.  Made the call here, and not in
1082    -- build_sql, becuase the procedure takes the org and item as parameters.
1083    g_unit_eff_enabled := pjm_unit_eff.unit_effective_item(
1084     x_item_id => p_inventory_item_id
1085    ,x_organization_id => p_organization_id);
1086 
1087    build_sql
1088      (l_return_status, p_mode, p_is_lot_control,
1089       p_asset_sub_only, p_include_suggestion,
1090       p_lot_expiration_date,p_onhand_source,
1091       p_pick_release,
1092       l_sql, p_is_revision_control);
1093 
1094    IF l_return_status <> fnd_api.g_ret_sts_success THEN
1095       RAISE fnd_api.g_exc_unexpected_error;
1096    END IF;
1097 
1098    -- print the sql statement to dbms_output
1099    --dbms_output.put_line('start build sql');
1100    --inv_ppcommon_pvt.showsql(l_sql);
1101    --dbms_output.put_line('end build sql');
1102    BEGIN
1103       dbms_sql.parse(l_cursor,l_sql,dbms_sql.v7);
1104    EXCEPTION
1105       WHEN OTHERS THEN
1106          l_last_error_pos := dbms_sql.last_error_position();
1107          l_temp_str := Substr(l_sql, l_last_error_pos-5, 30);
1108          RAISE;
1109    END;
1110 
1111    dbms_sql.bind_variable(l_cursor, ':organization_id', p_organization_id);
1112    dbms_sql.bind_variable(l_cursor, ':inventory_item_id', p_inventory_item_id);
1113    --Bug 1387420 - performance
1114    -- no longer check rsvs for txn mode
1115    --IF p_mode IN (g_transaction_mode, g_loose_only_mode) OR
1116    IF p_mode IN (g_loose_only_mode) THEN
1117       dbms_sql.bind_variable(l_cursor, ':demand_source_type_id', p_demand_source_type_id);
1118       dbms_sql.bind_variable(l_cursor, ':demand_source_header_id', p_demand_source_header_id);
1119       dbms_sql.bind_variable(l_cursor, ':demand_source_name', p_demand_source_name);
1120       dbms_sql.bind_variable(l_cursor, ':demand_source_delivery', p_demand_source_delivery);
1121    END IF;
1122    --
1123    --Bug 1387420 - performance
1124    -- no longer check rsvs for txn mode
1125    --IF p_mode IN (g_transaction_mode, g_loose_only_mode) OR
1126    IF p_mode IN (g_loose_only_mode) OR g_unit_eff_enabled = 'Y' THEN
1127       -- Bug 2346202: Since the value of -9999 for demand_source_line_id is
1128       --   equivalent to that being NULL, changed the setting the value of
1129       --   bind variable appropriately.
1130       IF(p_demand_source_line_id = -9999) THEN
1131          dbms_sql.bind_variable(l_cursor, ':demand_source_line_id', to_number(NULL));
1132       ELSE
1133          dbms_sql.bind_variable(l_cursor, ':demand_source_line_id', p_demand_source_line_id);
1134       END IF;
1135    END IF;
1136 
1137    --
1138    IF p_is_lot_control AND p_lot_expiration_date IS NOT NULL THEN
1139       dbms_sql.bind_variable(l_cursor, ':lot_expiration_date'
1140                              , p_lot_expiration_date);
1141    END IF;
1142 
1143    x_cursor := l_cursor;
1144    x_return_status := l_return_status;
1145 
1146 EXCEPTION
1147    WHEN OTHERS THEN
1148 --       dbms_output.put_line('last_error_position : '
1149 --             || dbms_sql.last_error_position);
1150 --       l_err := Substr(Sqlerrm,1,240);
1151 --       dbms_output.put_line(l_err);
1152 --       l_err := Substr(Sqlerrm,1,240);
1153 --       dbms_output.put_line(l_err);
1154 --       l_pos := dbms_sql.last_error_position;
1155 --       l_err := Substr(l_sql,1,240);
1156 --       dbms_output.put_line(l_err);
1157 --       dbms_output.put_line(Sqlerrm);
1158 --       dbms_output.put_line('start');
1159 --       inv_ppcommon_pvt.showsql(l_sql);
1160       x_return_status := fnd_api.g_ret_sts_unexp_error ;
1161       IF fnd_msg_pub.check_msg_level(fnd_msg_pub.g_msg_lvl_unexp_error)
1162         THEN
1163          fnd_msg_pub.add_exc_msg
1164            (  g_pkg_name
1165               , 'Build_Cursor'
1166               );
1167       END IF;
1168 END build_cursor;
1169 -- End of build_cursor .. NO invConv change.
1170 
1171 -------------------------------------------------------------------------------
1172 -- Procedure                                                                 --
1173 --   test_build_sql                                                          --
1174 --                                                                           --
1175 -- Description                                                               --
1176 --   This is a server side test procedure for build_sql. It calls            --
1177 --   build_sql with the input values to build a sql statement. Then          --
1178 --   it execute the statement to print out query result to dbms_output.      --
1179 --   You should turn on serveroutput to see the output.                      --
1180 --                                                                           --
1181 -- Input Parameters                                                          --
1182 --   p_mode                                                                  --
1183 --     equals inv_quantity_tree_pvt.g_reservation_mode or                    --
1184 --     inv_quantity_tree_pvt.g_transaction_mode                              --
1185 --   p_organization_id                                                       --
1186 --     organization_id                                                       --
1187 --   p_inventory_item_id                                                     --
1188 --     inventory_item_id                                                     --
1189 --   p_is_lot_control                                                        --
1190 --     true or false                                                         --
1191 --   p_asset_sub_only                                                        --
1192 --     true or false                                                         --
1193 --   p_include_suggestion                                                    --
1194 --     true or false     should be true only for pick/put engine             --
1195 --   p_lot_expiration_date                                                   --
1196 --     if not null, only consider lots that will not expire before           --
1197 --     or at the date                                                        --
1198 --   p_demand_source_type_id                                                 --
1199 --     demand_source_type_id                                                 --
1200 --   p_demand_source_header_id                                               --
1201 --     demand_source_header_id                                               --
1202 --   p_demand_source_line_id                                                 --
1203 --     demand_source_line_id                                                 --
1204 --   p_demand_source_name                                                    --
1205 --     demand_source_name                                                    --
1206 -------------------------------------------------------------------------------
1207 -- NO invConv change because build_cursor is obsolete.
1208 PROCEDURE test_build_sql
1209   (
1210      p_organization_id          IN  NUMBER
1211    , p_inventory_item_id        IN  NUMBER
1212    , p_mode                     IN  INTEGER
1213    , p_is_lot_control           IN  BOOLEAN
1214    , p_asset_sub_only           IN  BOOLEAN
1215    , p_include_suggestion       IN  BOOLEAN
1216    , p_lot_expiration_date      IN  DATE
1217    , p_demand_source_type_id    IN  NUMBER
1218    , p_demand_source_header_id  IN  NUMBER
1219    , p_demand_source_line_id    IN  NUMBER
1220    , p_demand_source_name       IN  VARCHAR2
1221    , p_demand_source_delivery   IN  NUMBER
1222    , p_onhand_source    IN  NUMBER DEFAULT g_all_subs
1223    ) IS
1224      l_cursor NUMBER;
1225      l_return_status VARCHAR2(1);
1226      l_revision VARCHAR2(3);
1227 -- Increased lot size to 80 Char - Mercy Thomas - B4625329
1228      l_lot_number VARCHAR2(80);
1229      l_subinventory_code VARCHAR2(10);
1230      l_lot_expiration_date DATE;
1231      l_reservable_type NUMBER;
1232      l_primary_quantity NUMBER;
1233      l_date_received DATE;
1234      l_quantity_type NUMBER;
1235      l_dummy INTEGER;
1236      l_locator_id NUMBER;
1237      l_inventory_item_id NUMBER;
1238      l_organization_id NUMBER;
1239      l_cost_group_id NUMBER;
1240 BEGIN
1241    build_cursor
1242      (
1243         x_return_status           => l_return_status
1244       , p_organization_id         => p_organization_id
1245       , p_inventory_item_id       => p_inventory_item_id
1246       , p_mode                    => p_mode
1247       , p_demand_source_type_id   => p_demand_source_type_id
1248       , p_demand_source_header_id => p_demand_source_header_id
1249       , p_demand_source_line_id   => p_demand_source_line_id
1250       , p_demand_source_name      => p_demand_source_name
1251       , p_demand_source_delivery  => p_demand_source_delivery
1252       , p_is_lot_control          => p_is_lot_control
1253       , p_asset_sub_only          => p_asset_sub_only
1254       , p_include_suggestion      => p_include_suggestion
1255       , p_lot_expiration_date     => p_lot_expiration_date
1256       , p_onhand_source      => p_onhand_source
1257       , p_pick_release       => 0
1258       , x_cursor                  => l_cursor
1259       );
1260 
1261    IF l_return_status <> fnd_api.g_ret_sts_success THEN
1262       RAISE fnd_api.g_exc_unexpected_error;
1263    END IF;
1264 
1265    dbms_sql.define_column(l_cursor,1,l_organization_id);
1266    dbms_sql.define_column(l_cursor,2,l_inventory_item_id);
1267    dbms_sql.define_column(l_cursor,3,l_revision,3);
1268    dbms_sql.define_column(l_cursor,4,l_lot_number,30);
1269    dbms_sql.define_column(l_cursor,5,l_lot_expiration_date);
1270    dbms_sql.define_column(l_cursor,6,l_subinventory_code,10);
1271    dbms_sql.define_column(l_cursor,7,l_reservable_type);
1272    dbms_sql.define_column(l_cursor,8,l_locator_id);
1273    dbms_sql.define_column(l_cursor,9,l_primary_quantity);
1274    dbms_sql.define_column(l_cursor,10,l_date_received);
1275    dbms_sql.define_column(l_cursor,11,l_quantity_type);
1276    dbms_sql.define_column(l_cursor,12,l_cost_group_id);
1277 
1278    l_dummy := dbms_sql.execute(l_cursor);
1279    LOOP
1280       IF dbms_sql.fetch_rows(l_cursor) = 0 THEN
1281          EXIT;
1282       END IF;
1283       dbms_sql.column_value(l_cursor,1,l_organization_id);
1284       dbms_sql.column_value(l_cursor,2,l_inventory_item_id);
1285       dbms_sql.column_value(l_cursor,3,l_revision);
1286       dbms_sql.column_value(l_cursor,4,l_lot_number);
1287       dbms_sql.column_value(l_cursor,5,l_lot_expiration_date);
1288       dbms_sql.column_value(l_cursor,6,l_subinventory_code);
1289       dbms_sql.column_value(l_cursor,7,l_reservable_type);
1290       dbms_sql.column_value(l_cursor,8,l_locator_id);
1291       dbms_sql.column_value(l_cursor,9,l_primary_quantity);
1292       dbms_sql.column_value(l_cursor,10,l_date_received);
1293       dbms_sql.column_value(l_cursor,11,l_quantity_type);
1294       dbms_sql.column_value(l_cursor,12,l_cost_group_id);
1295 --       dbms_output.put_line('________________________________________________');
1296 --       dbms_output.put('org '||l_organization_id);
1297 --       dbms_output.put(', item '||l_inventory_item_id);
1298 --       dbms_output.put(', rev '||l_revision);
1299 --       dbms_output.put(', lot '||l_lot_number);
1300 --       dbms_output.put(', lotdate: '|| fnd_date.date_to_canonical(l_lot_expiration_date));
1301 --       dbms_output.put(', sub '||l_subinventory_code);
1302 --       dbms_output.put(', rsvtype '|| To_char(l_reservable_type));
1303 --       dbms_output.put(', loc '||To_char(l_locator_id));
1304 --       dbms_output.put(', priqty '|| To_char(l_primary_quantity));
1305 --       dbms_output.put(', datercv '||To_char(l_date_received));
1306 --       dbms_output.put_line(', qtytype '||l_quantity_type);
1307    END LOOP;
1308    dbms_sql.close_cursor(l_cursor);
1309 
1310 END test_build_sql;
1311 -- End of test_build_sql ... NO invConv change.
1312 
1313 -- Procedure
1314 --   print_rootinfo
1315 -- Description
1316 --   print the data in a rootinfo record specified by the input
1317 PROCEDURE print_rootinfo
1318   (p_tree_id IN INTEGER
1319    ) IS
1320 BEGIN
1321 
1322    IF (1=1) THEN
1323       RETURN;
1324    END IF;
1325 
1326 --    print_debug('organization_id: '
1327 --                         || To_char(g_rootinfos(p_tree_id).organization_id));
1328 --    print_debug('inventory_item_id: '
1329 --                         || To_char(g_rootinfos(p_tree_id).inventory_item_id));
1330 --    IF g_rootinfos(p_tree_id).is_revision_control THEN
1331 --       print_debug('is_revision_control: TRUE');
1332 --     ELSE
1333 --       print_debug('is_revision_control: FALSE');
1334 --    END IF;
1335 
1336 --    IF g_rootinfos(p_tree_id).is_lot_control THEN
1337 --       print_debug('is_lot_control: TRUE');
1338 --     ELSE
1339 --       print_debug('is_lot_control: FALSE');
1340 --    END IF;
1341 
1342 --    IF g_rootinfos(p_tree_id).is_serial_control THEN
1343 --       print_debug('is_serial_control: TRUE');
1344 --     ELSE
1345 --       print_debug('is_serial_control: FALSE');
1346 --    END IF;
1347 
1348 --    IF g_rootinfos(p_tree_id).neg_inv_allowed THEN
1349 --       print_debug('neg_inv_allowed: TRUE');
1350 --     ELSE
1351 --       print_debug('neg_inv_allowed: FALSE');
1352 --    END IF;
1353 
1354 --    IF g_rootinfos(p_tree_id).tree_mode = g_reservation_mode THEN
1355 --       print_debug('tree_mode: reservation mode');
1356 --     ELSIF g_rootinfos(p_tree_id).tree_mode = g_transaction_mode THEN
1357 --       print_debug('tree_mode: transaction mode');
1358 --     ELSE
1359 --       print_debug('tree_mode: invalid - '
1360 --                            || To_char(g_rootinfos(p_tree_id).tree_mode));
1361 --    END IF;
1362 
1363 --    print_debug
1364 --      ('demand_source_type_id: '
1365 --       || To_char(g_rootinfos(p_tree_id).demand_source_type_id));
1366 --    print_debug
1367 --      ('demand_source_header_id: '
1368 --       || To_char(g_rootinfos(p_tree_id).demand_source_header_id));
1369 --    print_debug
1370 --      ('demand_source_line_id: '
1371 --       || To_char(g_rootinfos(p_tree_id).demand_source_line_id));
1372 --    print_debug('demand_source_name: '
1373 --                         || g_rootinfos(p_tree_id).demand_source_name);
1374 --    print_debug('demand_source_delivery: '
1375 --                         || g_rootinfos(p_tree_id).demand_source_delivery);
1376 --    IF g_rootinfos(p_tree_id).need_refresh THEN
1377 --       print_debug('need_refresh: TRUE');
1378 --     ELSE
1379 --       print_debug('need_refresh: FALSE');
1380 --    END IF;
1381 
1382 --    print_debug
1383 --      ('lot_expiration_date: '
1384 --       || fnd_date.date_to_canonical
1385 --       (g_rootinfos(p_tree_id).lot_expiration_date));
1386 --    print_debug('item_node_index: '
1387 --                         || To_char(g_rootinfos(p_tree_id).item_node_index));
1388 --    print_debug('_____end of rootinfo '||To_char(p_tree_id));
1389 
1390 END print_rootinfo;
1391 
1392 -- Procedure
1393 --   print_tree_node
1394 -- Description
1395 --   print the data in a tree node specified by the input
1396 PROCEDURE print_tree_node
1397   (p_node_index IN INTEGER
1398    ) IS
1399    l_node_level         INTEGER;
1400    l_node_index         INTEGER;
1401 
1402    l_found              BOOLEAN;
1403    l_root_id            NUMBER;
1404    l_return_status      VARCHAR2(1) := fnd_api.g_ret_sts_success;
1405    l_reservable         VARCHAR2(10);
1406    b_reservable         BOOLEAN;
1407    l_status_id          NUMBER;
1408    l_zone_control       NUMBER;
1409    l_location_control   NUMBER;
1410 
1411    z_node               VARCHAR2(200);
1412    zz_node              VARCHAR2(200);
1413    z_reservable         VARCHAR2(200);
1414    z_check              VARCHAR2(200);
1415    z_lot                VARCHAR2(200);
1416    z_sub                VARCHAR2(200);
1417    z_loc                VARCHAR2(200);
1418    z_rev                VARCHAR2(200);
1419    z_qoh                VARCHAR2(200);
1420    z_rqoh               VARCHAR2(200);
1421    z_qr                 VARCHAR2(200);
1422    z_qs                 VARCHAR2(200);
1423    z_att                VARCHAR2(200);
1424    z_atr                VARCHAR2(200);
1425    z_sqr                VARCHAR2(200);
1426    z_sqs                VARCHAR2(200);
1427    z_satt               VARCHAR2(200);
1428    z_satr               VARCHAR2(200);
1429    z_qs_adj1            VARCHAR2(200);
1430    z_lpn                VARCHAR2(200);
1431 BEGIN
1432 
1433    IF g_debug IS NULL THEN
1434       g_debug :=  NVL(FND_PROFILE.VALUE('INV_DEBUG_TRACE'),0);
1435    END IF;
1436 
1437    -- Bug 6332112 : Removed if g_debug and indented the complete procedure
1438    l_reservable  := 'Y';
1439    IF p_node_index <> 0 THEN
1440        l_node_level := g_nodes(p_node_index).node_level;
1441 
1442        IF l_node_level = g_item_level THEN
1443           z_node := rpad('Item', 5);
1444           zz_node := 'Item';
1445 
1446        ELSIF l_node_level = g_revision_level THEN
1447           z_node := rpad('Rev', 5);
1448           zz_node := 'Revision';
1449 
1450        ELSIF l_node_level = g_lot_level THEN
1451           z_node := rpad('Lot', 5);
1452           zz_node := 'Lot';
1453 
1454        ELSIF l_node_level = g_sub_level THEN
1455           z_node := rpad('Sub', 5);
1456           zz_node := 'SubInventory';
1457 
1458        ELSIF l_node_level = g_locator_level THEN
1459           z_node := rpad('Loc', 5);
1460           zz_node := 'Locator';
1461 
1462        END IF;   -- l_node_level
1463 
1464        b_reservable := g_nodes(p_node_index).is_reservable_sub;
1465 
1466        IF b_reservable THEN
1467            l_reservable := ' Y';
1468        ELSE
1469            l_reservable := ' N';
1470        END IF;
1471 
1472 
1473        z_rev        := rpad(NVL(g_nodes(p_node_index).revision, '...'), 5);
1474        z_lot        := rpad(NVL(g_nodes(p_node_index).lot_number, '...'), 10);
1475        z_sub        := rpad(NVL(g_nodes(p_node_index).subinventory_code, '...'), 10);
1476        z_loc        := rpad(NVL(to_char(g_nodes(p_node_index).locator_id), '...'), 7);
1477        z_lpn        := rpad(NVL(to_char(g_nodes(p_node_index).lpn_id), '...'), 7);
1478        z_qoh        := lpad(to_char(g_nodes(p_node_index).qoh), 7);
1479        z_rqoh       := lpad(to_char(g_nodes(p_node_index).rqoh), 7);
1480        z_qr         := lpad(to_char(g_nodes(p_node_index).qr), 7);
1481        z_qs         := lpad(to_char(g_nodes(p_node_index).qs), 7);
1482        z_att        := lpad(to_char(g_nodes(p_node_index).att), 7);
1483        z_atr        := lpad(to_char(g_nodes(p_node_index).atr), 7);
1484        z_qs_adj1    := lpad(to_char(g_nodes(p_node_index).qs_adj1), 8);
1485        z_reservable := rpad( l_reservable, 4);
1486 
1487        IF g_nodes(p_node_index).check_mark THEN
1488           z_check := rpad('TRUE', 6);
1489        ELSE
1490           z_check := rpad('FALSE', 6);
1491        END IF;
1492 
1493        print_debug('     '||z_node||z_rev||z_lot||z_sub||z_loc||z_lpn||z_qoh||z_rqoh||z_qr||z_qs||z_att||z_atr||z_qs_adj1||z_reservable||z_check,12);
1494        print_debug('    -'||RPad('-',105,'-'),12);
1495 
1496        l_node_index := g_nodes(p_node_index).first_child_index;
1497 --
1498        WHILE l_node_index <> 0 LOOP
1499             print_tree_node(l_node_index);
1500             l_node_index := g_nodes(l_node_index).next_sibling_index;
1501        END LOOP;
1502    END IF;
1503 END print_tree_node;
1504 
1505 PROCEDURE print_tree
1506   (p_tree_id IN INTEGER
1507    ) IS
1508 
1509    l_root_id INTEGER;
1510 BEGIN
1511 
1512 --   IF p_tree_id > g_rootinfo_counter THEN
1513 --      RETURN;
1514 --   END IF;
1515    IF g_debug IS NULL THEN
1516       g_debug :=  NVL(FND_PROFILE.VALUE('INV_DEBUG_TRACE'),0);
1517    END IF;
1518 
1519    IF (g_debug = 1) THEN
1520       l_root_id := g_demand_info(p_tree_id).root_id;
1521       print_debug(' ',12);
1522       print_debug('  print tree: number='||To_char(p_tree_id)||' id='||l_root_id
1523              ||' for item='||g_rootinfos(l_root_id).inventory_item_id||' org='||g_rootinfos(l_root_id).organization_id,12);
1524       IF g_rootinfos(l_root_id).organization_id IS NOT NULL THEN
1525          print_debug('  _____start of tree '|| To_char(l_root_id),12);
1526          -- print_rootinfo(p_tree_id);
1527 
1528          -- invConv :added table header
1529          print_debug('     '||rpad('Node',5)||rpad('Rev',5)||rpad('Lot',10)||rpad('Sub',10)||rpad('Loc',7)||rpad('Lpn',7)||
1530                      lpad('qoh',7)||lpad('rqoh',7)||lpad('qr',7)||lpad('qs',7)||lpad('att',7)||lpad('atr',7)||
1531                      lpad('qs_adj1',8)||rpad(' Rsv',4)||rpad(' Marked',7) ,12);
1532 
1533          print_debug('    -'||RPad('-',105,'-'),12);
1534          print_tree_node(g_rootinfos(l_root_id).item_node_index);
1535          print_debug('  _____end of tree '||To_char(l_root_id),12);
1536        ELSE
1537          print_debug ('Error: tree '||To_char(l_root_id) || ' does not exist',12);
1538       END IF;
1539    END IF;
1540 
1541 END print_tree;
1542 
1543 PROCEDURE zero_tree_node
1544   (x_return_status   OUT NOCOPY VARCHAR2
1545    , p_node_index    IN  INTEGER
1546    ) IS
1547    l_return_status     VARCHAR2(1) := fnd_api.g_ret_sts_success;
1548    l_node_index        INTEGER;
1549 BEGIN
1550    l_node_index := p_node_index;
1551    IF l_node_index <>0 THEN
1552       g_nodes(l_node_index).qoh   := 0;
1553       g_nodes(l_node_index).rqoh  := 0;
1554       g_nodes(l_node_index).qs    := 0;
1555       g_nodes(l_node_index).qr    := 0;
1556       g_nodes(l_node_index).atr   := 0;
1557       g_nodes(l_node_index).att   := 0;
1558       g_nodes(l_node_index).pqoh  := 0;
1559       -- invConv changes begin
1560       g_nodes(l_node_index).sqoh  := 0;
1561       g_nodes(l_node_index).srqoh := 0;
1562       g_nodes(l_node_index).sqs   := 0;
1563       g_nodes(l_node_index).sqr   := 0;
1564       g_nodes(l_node_index).satr  := 0;
1565       g_nodes(l_node_index).satt  := 0;
1566       g_nodes(l_node_index).spqoh := 0;
1567       -- invConv changes end
1568 
1569       l_node_index := g_nodes(l_node_index).first_child_index;
1570       WHILE l_node_index<>0 LOOP
1571          zero_tree_node(l_return_status, l_node_index);
1572 
1573          IF l_return_status = fnd_api.g_ret_sts_error THEN
1574             RAISE fnd_api.g_exc_error;
1575          End IF ;
1576 
1577          IF l_return_status = fnd_api.g_ret_sts_unexp_error THEN
1578             RAISE fnd_api.g_exc_unexpected_error;
1579          End IF;
1580 
1581          l_node_index := g_nodes(l_node_index).next_sibling_index;
1582       END LOOP;
1583    END IF;
1584    x_return_status := l_return_status;
1585 
1586 EXCEPTION
1587    WHEN fnd_api.g_exc_error THEN
1588         x_return_status := fnd_api.g_ret_sts_error;
1589 
1590    WHEN fnd_api.g_exc_unexpected_error THEN
1591         x_return_status := fnd_api.g_ret_sts_unexp_error ;
1592 
1593    WHEN OTHERS THEN
1594       x_return_status := fnd_api.g_ret_sts_unexp_error ;
1595 
1596       IF fnd_msg_pub.check_msg_level(fnd_msg_pub.g_msg_lvl_unexp_error)
1597         THEN
1598          fnd_msg_pub.add_exc_msg
1599            (  g_pkg_name
1600               , 'Zero_Tree_Node'
1601               );
1602       END IF;
1603 END zero_tree_node;
1604 
1605 /* BENCHMARK - obsolete - zero_tree_node should be called directly
1606 PROCEDURE zero_tree
1607   (x_return_status  OUT NOCOPY VARCHAR2
1608    , p_tree_id      IN  INTEGER
1609    ) IS
1610       l_return_status     VARCHAR2(1) := fnd_api.g_ret_sts_success;
1611       l_node_index        INTEGER;
1612 BEGIN
1613    l_node_index := g_rootinfos(p_tree_id).item_node_index;
1614 
1615    zero_tree_node(l_return_status, l_node_index);
1616 
1617    IF l_return_status = fnd_api.g_ret_sts_error THEN
1618       RAISE fnd_api.g_exc_error;
1619    End IF ;
1620 
1621    IF l_return_status = fnd_api.g_ret_sts_unexp_error THEN
1622       RAISE fnd_api.g_exc_unexpected_error;
1623    End IF;
1624 
1625    x_return_status := l_return_status;
1626 
1627 EXCEPTION
1628    WHEN fnd_api.g_exc_error THEN
1629         x_return_status := fnd_api.g_ret_sts_error;
1630 
1631    WHEN fnd_api.g_exc_unexpected_error THEN
1632         x_return_status := fnd_api.g_ret_sts_unexp_error ;
1633 
1634    WHEN OTHERS THEN
1635       x_return_status := fnd_api.g_ret_sts_unexp_error ;
1636 
1637       IF fnd_msg_pub.check_msg_level(fnd_msg_pub.g_msg_lvl_unexp_error)
1638         THEN
1639          fnd_msg_pub.add_exc_msg
1640            (  g_pkg_name
1641               , 'Zero_Tree'
1642               );
1643       END IF;
1644 END zero_tree;
1645 */
1646 -- Procedure
1647 --   new_tree_node
1648 -- Description
1649 --   create a new tree node and initialize the all attributes.
1650 --   This is the constrcutor for all kinds of tree nodes:
1651 --   item, revision, lot, sub, and locator. The actual type of the
1652 --   node is qualified by input p_node_level. The pointers to
1653 --   and from the parent node and sibling nodes are also set up here.
1654 PROCEDURE new_tree_node
1655   (   x_return_status       OUT NOCOPY VARCHAR2
1656    ,  p_node_level          IN  INTEGER
1657    ,  p_revision            IN  VARCHAR2 DEFAULT NULL
1658    ,  p_lot_number          IN  VARCHAR2 DEFAULT NULL
1659    ,  p_subinventory_code   IN  VARCHAR2 DEFAULT NULL
1660    ,  p_is_reservable_sub   IN  BOOLEAN  DEFAULT NULL
1661    ,  p_locator_id          IN  NUMBER   DEFAULT NULL
1662    ,  p_lpn_id              IN  NUMBER   DEFAULT NULL
1663    ,  p_cost_group_id       IN  NUMBER   DEFAULT NULL
1664    ,  p_node_index          IN  INTEGER
1665    ,  p_hash_string         IN  VARCHAR2 DEFAULT NULL
1666    ) IS
1667       l_return_status       VARCHAR2(1) := fnd_api.g_ret_sts_success;
1668       l_new_node_index      INTEGER;
1669       l_org_id              NUMBER;
1670       l_parent_index        INTEGER;
1671       l_last_child_index    INTEGER;
1672 BEGIN
1673    -- increment the index for the array
1674    l_new_node_index := p_node_index;
1675 
1676    --initialize the node
1677    g_nodes(l_new_node_index).node_level         := p_node_level;
1678    g_nodes(l_new_node_index).revision           := p_revision;
1679    g_nodes(l_new_node_index).lot_number         := p_lot_number;
1680    g_nodes(l_new_node_index).lot_number         := p_lot_number;
1681    g_nodes(l_new_node_index).subinventory_code  := p_subinventory_code;
1682    g_nodes(l_new_node_index).is_reservable_sub  := p_is_reservable_sub;
1683    g_nodes(l_new_node_index).locator_id         := p_locator_id;
1684    g_nodes(l_new_node_index).qoh                := 0;
1685    g_nodes(l_new_node_index).rqoh               := 0;
1686    g_nodes(l_new_node_index).qr                 := 0;
1687    g_nodes(l_new_node_index).qs                 := 0;
1688    g_nodes(l_new_node_index).att                := 0;
1689    g_nodes(l_new_node_index).atr                := 0;
1690    g_nodes(l_new_node_index).pqoh               := 0;
1691    -- invConv changes begin
1692    g_nodes(l_new_node_index).sqoh               := 0;
1693    g_nodes(l_new_node_index).srqoh              := 0;
1694    g_nodes(l_new_node_index).sqr                := 0;
1695    g_nodes(l_new_node_index).sqs                := 0;
1696    g_nodes(l_new_node_index).satt               := 0;
1697    g_nodes(l_new_node_index).satr               := 0;
1698    g_nodes(l_new_node_index).spqoh              := 0;
1699    -- invConv changes end
1700    g_nodes(l_new_node_index).next_sibling_index := 0;
1701    g_nodes(l_new_node_index).first_child_index  := 0;
1702    g_nodes(l_new_node_index).last_child_index   := 0;
1703    g_nodes(l_new_node_index).parent_index := 0;
1704    g_nodes(l_new_node_index).check_mark         := FALSE;
1705    g_nodes(l_new_node_index).lpn_id             := p_lpn_id;
1706    g_nodes(l_new_node_index).cost_group_id      := p_cost_group_id;
1707    g_nodes(l_new_node_index).hash_string        := p_hash_string;
1708    g_nodes(l_new_node_index).next_hash_record   := 0;
1709    --Bug 4294336
1710    g_nodes(l_new_node_index).qs_adj1            := 0;
1711    g_nodes(l_new_node_index).sqs_adj1           := 0;
1712 
1713    x_return_status := l_return_status;
1714    print_debug('... normal end of new_tree_node');
1715 
1716 EXCEPTION
1717 
1718    WHEN OTHERS THEN
1719       x_return_status := fnd_api.g_ret_sts_unexp_error ;
1720 
1721       IF fnd_msg_pub.check_msg_level(fnd_msg_pub.g_msg_lvl_unexp_error)
1722         THEN
1723          fnd_msg_pub.add_exc_msg
1724            (  g_pkg_name
1725               , 'New_Tree_Node'
1726               );
1727       END IF;
1728 
1729 END new_tree_node;
1730 
1731 
1732 FUNCTION build_hash_string (
1733       x_return_status             OUT NOCOPY VARCHAR2
1734    ,  p_organization_id           IN  NUMBER
1735    ,  p_inventory_item_id         IN  NUMBER
1736    ,  p_tree_mode                 IN  INTEGER
1737    ,  p_is_revision_control       IN  BOOLEAN
1738    ,  p_is_lot_control            IN  BOOLEAN
1739    ,  p_asset_sub_only            IN  BOOLEAN
1740    ,  p_demand_source_type_id     IN  NUMBER
1741    ,  p_demand_source_header_id   IN  NUMBER
1742    ,  p_demand_source_line_id     IN  NUMBER
1743    ,  p_demand_source_name        IN  VARCHAR2
1744    ,  p_lot_expiration_date       IN  DATE
1745    ,  p_onhand_source        IN  NUMBER
1746    ) RETURN VARCHAR2 IS
1747 
1748    l_hash_string VARCHAR2(1000);
1749    l_pjm_enabled VARCHAR2(1);
1750 
1751 BEGIN
1752 
1753    x_return_status := fnd_api.g_ret_sts_success;
1754 
1755    -- Bug 1918356
1756    -- If PJM unit effectivity is enabled, we need to create
1757    -- a new tree for each different sales order line id
1758    -- Bug 2363739 - now call unit_effective_item
1759    l_pjm_enabled := pjm_unit_eff.unit_effective_item(
1760         x_item_id          => p_inventory_item_id
1761       , x_organization_id  => p_organization_id);
1762    IF l_pjm_enabled IS NULL THEN
1763      l_pjm_enabled := 'N';
1764    END IF;
1765    l_hash_string := p_organization_id || ':' || p_inventory_item_id;
1766    IF p_tree_mode IN (1,2) AND l_pjm_enabled <> 'Y' THEN
1767       l_hash_string := l_hash_string || ':1';
1768       -- add place holders for demand info
1769       l_hash_string := l_hash_string || '::::';
1770    ELSE
1771       l_hash_string := l_hash_string || ':' || p_tree_mode;
1772       l_hash_string := l_hash_string
1773         || ':' || p_demand_source_type_id
1774         || ':' || p_demand_source_header_id
1775         || ':' || p_demand_source_line_id
1776         || ':' || p_demand_source_name;
1777    END IF;
1778 
1779    IF p_is_revision_control THEN
1780       l_hash_string := l_hash_string || ':2';
1781    ELSE
1782       l_hash_string := l_hash_string || ':1';
1783    END IF;
1784 
1785    IF p_is_lot_control THEN
1786       l_hash_string := l_hash_string || ':2';
1787    ELSE
1788       l_hash_string := l_hash_string || ':1';
1789    END IF;
1790 
1791    IF p_asset_sub_only THEN
1792       l_hash_string := l_hash_string || ':2';
1793    ELSE
1794       l_hash_string := l_hash_string || ':1';
1795    END IF;
1796 
1797    IF p_lot_expiration_date IS NOT NULL THEN
1798       l_hash_string := l_hash_string || ':' || p_lot_expiration_date;
1799    END IF;
1800 
1801    l_hash_string := l_hash_string || ':' || p_onhand_source;
1802 
1803    RETURN l_hash_string;
1804 EXCEPTION
1805    WHEN OTHERS THEN
1806       x_return_status := fnd_api.g_ret_sts_unexp_error ;
1807 
1808       IF fnd_msg_pub.check_msg_level(fnd_msg_pub.g_msg_lvl_unexp_error)
1809         THEN
1810          fnd_msg_pub.add_exc_msg
1811            (  g_pkg_name
1812               , 'Build_Hash_String'
1813               );
1814       END IF;
1815 
1816 END build_hash_string;
1817 
1818 -- Procedure
1819 --   new_tree
1820 -- Description
1821 --   Create a new tree.
1822 --   1. create and init a rootinfo
1823 --   2. find out negative quantity is allowed for the item and org
1824 PROCEDURE new_tree
1825   (   x_return_status             OUT NOCOPY VARCHAR2
1826    ,  p_organization_id           IN  NUMBER
1827    ,  p_inventory_item_id         IN  NUMBER
1828    ,  p_tree_mode                 IN  INTEGER
1829    ,  p_is_revision_control       IN  BOOLEAN
1830    ,  p_is_lot_control            IN  BOOLEAN
1831    ,  p_is_serial_control         IN  BOOLEAN
1832    ,  p_asset_sub_only            IN  BOOLEAN
1833    ,  p_include_suggestion        IN  BOOLEAN
1834    ,  p_demand_source_type_id     IN  NUMBER
1835    ,  p_demand_source_header_id   IN  NUMBER
1836    ,  p_demand_source_line_id     IN  NUMBER
1837    ,  p_demand_source_name        IN  VARCHAR2
1838    ,  p_demand_source_delivery    IN  NUMBER
1839    ,  p_lot_expiration_date       IN  DATE
1840    ,  p_onhand_source             IN  NUMBER
1841    ,  p_pick_release              IN  NUMBER
1842    ,  p_grade_code                IN  VARCHAR2  DEFAULT NULL       -- invConv change
1843    ,  x_tree_id                   OUT NOCOPY INTEGER
1844    ) IS
1845       l_return_status             VARCHAR2(1) := fnd_api.g_ret_sts_success;
1846       l_item_node_index           INTEGER;
1847       l_negative_inv_receipt_code NUMBER;
1848       l_disable_flag              NUMBER;
1849 
1850       l_hash_string               VARCHAR2(1000);
1851       l_hash_base                 NUMBER;
1852       l_hash_size                 NUMBER;
1853       l_tree_index                NUMBER;
1854       l_org_item_index            NUMBER;
1855       l_first_tree_index          NUMBER;
1856       l_last_tree_index           NUMBER;
1857       l_original_tree_index       NUMBER;
1858       l_original_hash_string      VARCHAR2(1000);
1859 
1860       l_unit_effective            NUMBER;
1861       l_return_value              BOOLEAN;
1862 
1863 BEGIN
1864    print_debug('in new_tree, grade='||p_grade_code);
1865 
1866    l_hash_base := 1;
1867    l_hash_size := power(2, 20);
1868    IF g_hash_string IS NOT NULL THEN
1869      --if not null, we already found hash string in find_rootinfo and don't need to find it again
1870      l_hash_string := g_hash_string;
1871      g_hash_string := NULL;
1872    ELSE
1873      l_hash_string := build_hash_string (
1874         l_return_status
1875       , p_organization_id
1876       , p_inventory_item_id
1877       , p_tree_mode
1878       , p_is_revision_control
1879       , p_is_lot_control
1880       , p_asset_sub_only
1881       , p_demand_source_type_id
1882       , p_demand_source_header_id
1883       , p_demand_source_line_id
1884       , p_demand_source_name
1885       , p_lot_expiration_date
1886       , p_onhand_source);
1887    END IF;
1888 
1889    l_original_hash_string := l_hash_string;
1890    -- Bug 2092207 - hash procedure returning duplicate indices;
1891    --   doubling length of name to try to decrease probability of getting duplicate values
1892    IF g_empty_root_index IS NOT NULL THEN
1893       --if not null, we found an empty slot in find_rootinfo and don't need to look for it again
1894       l_tree_index := g_empty_root_index;
1895       g_empty_root_index := NULL;
1896    ELSE
1897       l_tree_index := dbms_utility.get_hash_value(
1898                           name       => l_hash_string || l_hash_string
1899                         , base       => l_hash_base
1900                         , hash_size  => l_hash_size);
1901 
1902       l_original_tree_index := l_tree_index;
1903 
1904       -- Bug 2092207 - catch duplicate tree indices.  Find next empty tree index
1905       WHILE g_rootinfos.exists(l_tree_index) LOOP
1906          l_tree_index := l_tree_index + 1;
1907          IF l_tree_index >= power(2,20) THEN
1908             l_tree_index := 1;
1909          END IF;
1910          -- if this ever true, we've used all the possible indices. Raise an exception.
1911          IF l_tree_index = l_original_tree_index THEN
1912             RAISE fnd_api.g_exc_unexpected_error;
1913          END IF;
1914       END LOOP;
1915    END IF;
1916 
1917    -- increment the index for the array
1918    --g_rootinfo_counter := g_rootinfo_counter + 1;
1919    g_all_roots_counter := g_all_roots_counter + 1;
1920    g_all_roots(g_all_roots_counter).root_id   := l_tree_index;
1921    g_all_roots(g_all_roots_counter).next_root := 0;
1922    g_all_roots(g_all_roots_counter).last_root := g_all_roots_counter;
1923 
1924    --set values for org/item combo
1925    l_hash_string := p_organization_id || ':' || p_inventory_item_id;
1926    l_org_item_index := dbms_utility.get_hash_value(
1927                          name       => l_hash_string
1928                        , base       => l_hash_base
1929                        , hash_size  => l_hash_size);
1930    IF g_org_item_trees.exists(l_org_item_index) THEN
1931       l_first_tree_index                        := g_org_item_trees(l_org_item_index);
1932       l_last_tree_index                         := g_all_roots(l_first_tree_Index).last_root;
1933       g_all_roots(l_last_tree_index).next_root  := g_all_roots_counter;
1934       g_all_roots(l_first_tree_index).last_root := g_all_roots_counter;
1935    ELSE
1936       g_org_item_trees(l_org_item_index)        := g_all_roots_counter;
1937    END IF;
1938 
1939    -- initialize the rootinfo record
1940    g_rootinfos(l_tree_index).organization_id      := p_organization_id;
1941    g_rootinfos(l_tree_index).inventory_item_id    := p_inventory_item_id;
1942    g_rootinfos(l_tree_index).tree_mode            := p_tree_mode;
1943    g_rootinfos(l_tree_index).is_revision_control  := p_is_revision_control;
1944    g_rootinfos(l_tree_index).is_serial_control    := p_is_serial_control;
1945    g_rootinfos(l_tree_index).is_lot_control       := p_is_lot_control;
1946    g_rootinfos(l_tree_index).asset_sub_only       := p_asset_sub_only    ;
1947    g_rootinfos(l_tree_index).include_suggestion   := p_include_suggestion;
1948    g_rootinfos(l_tree_index).lot_expiration_date  := p_lot_expiration_date;
1949    g_rootinfos(l_tree_index).grade_code           := p_grade_code;               -- invConv change
1950 
1951    -- invConv change (for display)
1952    print_debug('in new_tree org_id ='||g_rootinfos(l_tree_index).organization_id
1953       ||', item='||p_inventory_item_id||', tree_index='||l_tree_index);
1954    print_debug('in new_tree... grade_code='||p_grade_code);
1955 
1956    --only store demand info in tree for loose only mode - otherwise, it's stored in g_demand_info
1957    IF p_tree_mode = g_loose_only_mode THEN
1958       g_rootinfos(l_tree_index).demand_source_type_id   := p_demand_source_type_id;
1959       g_rootinfos(l_tree_index).demand_source_header_id := p_demand_source_header_id;
1960       g_rootinfos(l_tree_index).demand_source_line_id   := p_demand_source_line_id;
1961       g_rootinfos(l_tree_index).demand_source_name      := p_demand_source_name;
1962       g_rootinfos(l_tree_index).demand_source_delivery  := p_demand_source_delivery;
1963    END IF;
1964    g_rootinfos(l_tree_index).onhand_source             := p_onhand_source;
1965    g_rootinfos(l_tree_index).pick_release              := p_pick_release;
1966    g_rootinfos(l_tree_index).need_refresh              := TRUE;
1967    g_rootinfos(l_tree_index).hash_string               := l_original_hash_string;
1968 
1969    -- determine index for item node.  Rather than call the dbms hash utility,
1970    -- we'll just use the value for g_max_hash_rec. If this is the first tree
1971    -- to be created for this session, g_max_hash_rec will not have been
1972    -- initialized.  In that case, we'll use an index of 1.
1973    IF g_max_hash_rec <> 0 THEN
1974       g_max_hash_rec    := g_max_hash_rec + 1;
1975       l_item_node_index := g_max_hash_rec;
1976    ELSE
1977     /* Bug 2901076 : Setting l_item_node_index for the case where the first record
1978     has no onhand and availability */
1979       g_max_hash_rec := power(2,29) + 1;
1980       l_item_node_index := g_max_hash_rec;
1981    END IF;
1982    -- create the corresponding item tree node
1983    new_tree_node
1984      (  x_return_status => l_return_status
1985       , p_node_level    => g_item_level
1986       , p_node_index    => l_item_node_index
1987       );
1988 
1989    IF l_return_status = fnd_api.g_ret_sts_error THEN
1990       RAISE fnd_api.g_exc_error;
1991    End IF ;
1992 
1993    IF l_return_status = fnd_api.g_ret_sts_unexp_error THEN
1994       RAISE fnd_api.g_exc_unexpected_error;
1995    End IF;
1996 
1997    g_rootinfos(l_tree_index).item_node_index := l_item_node_index;
1998 
1999    l_return_value := INV_CACHE.set_org_rec(p_organization_id);
2000    IF NOT l_return_value THEN
2001       RAISE fnd_api.g_exc_unexpected_error;
2002    END IF;
2003    l_negative_inv_receipt_code := INV_CACHE.org_rec.negative_inv_receipt_code;
2004 
2005    IF (l_negative_inv_receipt_code = 1) THEN
2006       g_rootinfos(l_tree_index).neg_inv_allowed := TRUE;
2007    ELSE
2008       g_rootinfos(l_tree_index).neg_inv_allowed := FALSE;
2009    END IF;
2010 
2011    --BENCHMARK
2012    --check whether item is unit effective controlled
2013    /* Check item cache instead of PJM function
2014     l_unit_effective := pjm_unit_eff.unit_effective_item(
2015          x_item_id => p_inventory_item_id
2016         ,x_organization_id => p_organization_id);
2017    */
2018    l_return_value := INV_CACHE.set_item_rec(p_organization_id, p_inventory_item_id);
2019    IF NOT l_return_value THEN
2020       RAISE fnd_api.g_exc_unexpected_error;
2021    END IF;
2022    l_unit_effective := INV_CACHE.item_rec.effectivity_control;
2023 
2024    /*Bug#5352407. All EAM asset group items are unit effective. Though they are unit
2025      effective, unit number is not required to perform transactions. So,
2026      they should be treated as non-unit effective otherwise the quantity
2027      tree would return the available qty as 0 even though there is qty
2028      available (Since it calls PJM API for getting onhand qty for
2029      unit effective items and the PJM API returns 0 if the item is of EAM asset group
2030      type).*/
2031    IF  l_unit_effective = 2 THEN
2032       IF INV_CACHE.item_rec.eam_item_type = 1 THEN
2033          l_unit_effective := 1;
2034       END IF;
2035    END IF;
2036 
2037 
2038    --2 is model/unit effective, which is what we care about
2039    IF l_unit_effective = 2 THEN
2040       g_rootinfos(l_tree_index).unit_effective := 1;
2041    ELSE
2042       g_rootinfos(l_tree_index).unit_effective := 2;
2043    END IF;
2044 
2045    --Bug 1384720 -performance
2046    -- Populate the demand table.  The index of this record is what
2047    --  is returned to the user as the tree_id.
2048    g_demand_counter := g_demand_counter + 1;
2049    g_demand_info(g_demand_counter).root_id                  := l_tree_index;
2050    g_demand_info(g_demand_counter).tree_mode                := p_tree_mode;
2051    g_demand_info(g_demand_counter).pick_release             := p_pick_release;
2052    g_demand_info(g_demand_counter).demand_source_type_id    := p_demand_source_type_id;
2053    g_demand_info(g_demand_counter).demand_source_header_id  := p_demand_source_header_id;
2054    g_demand_info(g_demand_counter).demand_source_line_id    := p_demand_source_line_id;
2055    g_demand_info(g_demand_counter).demand_source_name       := p_demand_source_name;
2056    g_demand_info(g_demand_counter).demand_source_delivery   := p_demand_source_delivery;
2057    -- return the tree id
2058    x_tree_id         := g_demand_counter;
2059    x_return_status   := l_return_status;
2060 
2061    -- invConv change (for display)
2062    print_debug('in new_tree org_id ='||g_rootinfos(l_tree_index).organization_id);
2063 
2064 EXCEPTION
2065 
2066    WHEN fnd_api.g_exc_error THEN
2067       x_return_status := fnd_api.g_ret_sts_error;
2068 
2069    WHEN fnd_api.g_exc_unexpected_error THEN
2070       x_return_status := fnd_api.g_ret_sts_unexp_error ;
2071 
2072    WHEN OTHERS THEN
2073       x_return_status := fnd_api.g_ret_sts_unexp_error ;
2074 
2075       IF fnd_msg_pub.check_msg_level(fnd_msg_pub.g_msg_lvl_unexp_error)
2076         THEN
2077          fnd_msg_pub.add_exc_msg
2078            (  g_pkg_name
2079               , 'New_Tree'
2080               );
2081       END IF;
2082 
2083 END new_tree;
2084 
2085 
2086 -- Procedure
2087 --   get_lock_handle
2088 -- Description
2089 --   Helper function which gets the lock handle for a given item/org.
2090 --   Allocate_unique executes a commit, so this function is
2091 --   autonomous to prevent commit of the session's other data.
2092 FUNCTION get_lock_handle (
2093     p_organization_id   IN NUMBER
2094       ,p_inventory_item_id IN NUMBER) RETURN VARCHAR2 IS
2095 
2096    PRAGMA AUTONOMOUS_TRANSACTION;
2097    l_lock_handle VARCHAR2(128);
2098    l_lock_name   VARCHAR2(30);
2099 BEGIN
2100 
2101    l_lock_name := 'INV_QT_' || p_organization_id || '_' || p_inventory_item_id;
2102    dbms_lock.allocate_unique(
2103     lockname   => l_lock_name
2104    ,lockhandle => l_lock_handle);
2105    return l_lock_handle;
2106 END get_lock_handle;
2107 
2108 
2109 -- Procedure
2110 --   lock_tree
2111 -- Description
2112 --   this function places a user lock on an item/organization
2113 --   combination.  Once this lock is placed, no other sessions
2114 --   can lock the same item/org combo.  Users who call lock_tree
2115 --   do not always have to call release_lock explicitly.  The lock is
2116 --   released automatically at commit, rollback, or session loss.
2117 
2118 PROCEDURE lock_tree(
2119      p_api_version_number   IN  NUMBER
2120    , p_init_msg_lst         IN  VARCHAR2
2121    , x_return_status        OUT NOCOPY VARCHAR2
2122    , x_msg_count            OUT NOCOPY NUMBER
2123    , x_msg_data             OUT NOCOPY VARCHAR2
2124    , p_organization_id      IN  NUMBER
2125    , p_inventory_item_id    IN  NUMBER)
2126 
2127 IS
2128    l_api_version_number    CONSTANT NUMBER       := 1.0;
2129    l_api_name              CONSTANT VARCHAR2(30) := 'Lock_Tree';
2130    l_return_status         VARCHAR2(1) := fnd_api.g_ret_sts_success;
2131    l_lock_handle           VARCHAR2(128);
2132    l_status                INTEGER;
2133 
2134 BEGIN
2135    print_debug('... in lock_tree... will create a dbms_lock...');
2136    --  Standard call to check for call compatibility
2137    IF NOT fnd_api.compatible_api_call(  l_api_version_number
2138                                       , p_api_version_number
2139                                       , l_api_name
2140                                       , G_PKG_NAME
2141                                       ) THEN
2142       RAISE fnd_api.g_exc_unexpected_error;
2143    END IF;
2144 
2145    --  Initialize message list.
2146    IF fnd_api.to_boolean(p_init_msg_lst) THEN
2147       fnd_msg_pub.initialize;
2148    END IF;
2149 
2150    --validate organization and inventory item
2151    IF (p_organization_id IS NULL OR p_inventory_item_id IS NULL) THEN
2152       --raise error condition
2153       fnd_message.set_name('INV','INV_LOCK_MISSING_ARGS');
2154       fnd_msg_pub.ADD;
2155       RAISE fnd_api.g_exc_error;
2156    END IF;
2157 
2158    IF g_lock_timeout IS NULL THEN
2159       g_lock_timeout := nvl(to_number(fnd_profile.value('INV_QTY_TREE_TIMEOUT')),dbms_lock.maxwait);
2160    END IF;
2161    --get lock handle by calling helper function
2162    l_lock_handle := get_lock_handle(
2163         p_organization_id   => p_organization_id
2164       , p_inventory_item_id => p_inventory_item_id);
2165 
2166    --request lock
2167    l_status := dbms_lock.request(
2168         lockhandle        => l_lock_handle
2169       , lockmode          => dbms_lock.x_mode
2170       , timeout           => nvl(g_lock_timeout,dbms_lock.maxwait)
2171       , release_on_commit => TRUE);
2172 
2173    --check for error cases
2174    IF (l_status NOT IN (0,4)) THEN
2175       if (l_status = 1) then -- timeout
2176          fnd_message.set_name('INV','INV_LOCK_TREE_TIMEOUT');
2177          fnd_msg_pub.ADD;
2178          RAISE fnd_api.g_exc_error;
2179       elsif (l_status = 2) then -- deadlock
2180          fnd_message.set_name('INV','INV_LOCK_TREE_DEADLOCK');
2181          fnd_msg_pub.ADD;
2182          RAISE fnd_api.g_exc_error;
2183       else -- internal error - not fault of user
2184          fnd_message.set_name('INV','INV_LOCK_TREE_ERROR');
2185          fnd_msg_pub.ADD;
2186          RAISE fnd_api.g_exc_error;
2187       end if;
2188    END IF;
2189 
2190    print_debug('QTY TREE LOCK ACQUIRED '||l_lock_handle, 9);
2191 
2192    x_return_status := l_return_status;
2193 
2194 EXCEPTION
2195 
2196    WHEN fnd_api.g_exc_error THEN
2197         x_return_status := fnd_api.g_ret_sts_error;
2198 
2199    WHEN fnd_api.g_exc_unexpected_error THEN
2200         x_return_status := fnd_api.g_ret_sts_unexp_error ;
2201 
2202     WHEN OTHERS THEN
2203         x_return_status := fnd_api.g_ret_sts_unexp_error ;
2204 
2205         IF fnd_msg_pub.check_msg_level(fnd_msg_pub.g_msg_lvl_unexp_error)
2206           THEN
2207            fnd_msg_pub.add_exc_msg
2208              (  g_pkg_name
2209               , 'Lock_Tree'
2210               );
2211         END IF;
2212 
2213 END lock_tree;
2214 
2215 -- Procedure
2216 --   release_lock
2217 -- Description
2218 --   this function releases the user lock on an item/organization
2219 --   combination created by this session.  Users who call lock_tree
2220 --   do not always have to call release_lock explicitly.  The lock is
2221 --   released automatically at commit, rollback, or session loss.
2222 
2223 PROCEDURE release_lock(
2224      p_api_version_number   IN  NUMBER
2225    , p_init_msg_lst         IN  VARCHAR2
2226    , x_return_status        OUT NOCOPY VARCHAR2
2227    , x_msg_count            OUT NOCOPY NUMBER
2228    , x_msg_data             OUT NOCOPY VARCHAR2
2229    , p_organization_id      IN  NUMBER
2230    , p_inventory_item_id    IN  NUMBER)
2231 
2232 IS
2233    l_api_version_number   CONSTANT NUMBER       := 1.0;
2234    l_api_name             CONSTANT VARCHAR2(30) := 'Release_Lock';
2235    l_return_status    VARCHAR2(1) := fnd_api.g_ret_sts_success;
2236    l_lock_handle VARCHAR2(128);
2237    l_status INTEGER;
2238 BEGIN
2239    print_debug('... in release_lock ...');
2240    --  Standard call to check for call compatibility
2241    IF NOT fnd_api.compatible_api_call(l_api_version_number
2242                                       , p_api_version_number
2243                                       , l_api_name
2244                                       , G_PKG_NAME
2245                                       ) THEN
2246       RAISE fnd_api.g_exc_unexpected_error;
2247    END IF;
2248 
2249    --  Initialize message list.
2250    IF fnd_api.to_boolean(p_init_msg_lst) THEN
2251       fnd_msg_pub.initialize;
2252    END IF;
2253 
2254    --validate organization and inventory item
2255    IF (p_organization_id IS NULL OR
2256        p_inventory_item_id IS NULL) THEN
2257    --raise error condition
2258          fnd_message.set_name('INV','INV_LOCK_RELEASE_MISSING_ARGS');
2259          fnd_msg_pub.ADD;
2260          RAISE fnd_api.g_exc_error;
2261    END IF;
2262 
2263 
2264    --get lock handle by calling helper function
2265    l_lock_handle := get_lock_handle(
2266          p_organization_id   => p_organization_id
2267        , p_inventory_item_id => p_inventory_item_id);
2268 
2269 
2270    l_status := dbms_lock.release(l_lock_handle);
2271 
2272    --if success (status = 0) or session does not own lock (status=4), do nothing
2273    --if parameter error or illegal lock handle (internal error)
2274    if l_status IN (3,5) THEN
2275       fnd_message.set_name('INV','INV_LOCK_RELEASE_ERROR');
2276       fnd_msg_pub.ADD;
2277       RAISE fnd_api.g_exc_error;
2278    end if;
2279 
2280    print_debug('... Normal end of release_lock ...');
2281    x_return_status := l_return_status;
2282 
2283 EXCEPTION
2284 
2285    WHEN fnd_api.g_exc_error THEN
2286       print_debug('... release_lock EXP_ERROR='||SQLERRM, 9);
2287       x_return_status := fnd_api.g_ret_sts_error;
2288 
2289    WHEN fnd_api.g_exc_unexpected_error THEN
2290       print_debug('... release_lock UNEXP_ERROR='||SQLERRM, 9);
2291       x_return_status := fnd_api.g_ret_sts_unexp_error ;
2292 
2293    WHEN OTHERS THEN
2294       print_debug('... release_lock others='||SQLERRM, 9);
2295       x_return_status := fnd_api.g_ret_sts_unexp_error ;
2296 
2297      IF fnd_msg_pub.check_msg_level(fnd_msg_pub.g_msg_lvl_unexp_error)
2298      THEN
2299         fnd_msg_pub.add_exc_msg
2300           (  g_pkg_name
2301            , 'Release_Lock'
2302            );
2303      END IF;
2304 
2305 END release_lock;
2306 
2307 
2308 
2309 
2310 -- Function
2311 --  get_ancestor_sub
2312 -- Description
2313 --  Finds the ancestor sub node for the node passed in to the function
2314 -- Returns
2315 --  node_index of ancestor sub
2316 FUNCTION get_ancestor_sub
2317    (p_node_index IN NUMBER) RETURN NUMBER IS
2318 
2319    l_cur_node NUMBER;
2320 BEGIN
2321    l_cur_node := p_node_index;
2322    LOOP
2323       print_debug('in get_ancestor_sub, new loop... cur_node='||l_cur_node||', level='||g_nodes(l_cur_node).node_level);
2324       if l_cur_node IS NULL THEN
2325          print_debug('in get_ancestor_sub, cur_node=NULL');
2326          l_cur_node := -1;
2327          EXIT;
2328       elsif (g_nodes(l_cur_node).node_level = g_sub_level) THEN
2329          print_debug('in get_ancestor_sub, node_level='||g_nodes(l_cur_node).node_level||' = sub_level, parent_index='||g_nodes(l_cur_node).parent_index);
2330          EXIT;
2331       elsif (g_nodes(l_cur_node).node_level = g_item_level) THEN
2332          print_debug('in get_ancestor_sub, node_level='||g_nodes(l_cur_node).node_level||' = item_level, parent_index='||g_nodes(l_cur_node).parent_index);
2333          l_cur_node := -1;
2334          EXIT;
2335       elsif (g_nodes.exists(l_cur_node) = FALSE) THEN
2336          print_debug('in get_ancestor_sub, g_nodes.exists= FALSE, node_level='||g_nodes(l_cur_node).node_level);
2337          l_cur_node := -1;
2338          EXIT;
2339       end if;
2340       l_cur_node := g_nodes(l_cur_node).parent_index;
2341    END LOOP;
2342 
2343    print_debug('in get_ancestor_sub, returning='||l_cur_node);
2344    RETURN l_cur_node;
2345 END get_ancestor_sub;
2346 
2347 -- Procedure
2348 --  check_is_reservable_sub
2349 -- Description
2350 --  check from db tables whether the sub specified in
2351 --  the input is a reservable sub or not.
2352 -- invConv comment : this procedure check_is_reservable_sub is included in check_is_reservable
2353 --                   and used when g_is_mat_status_used =  NO ( == 2)
2354 -- end of invConv comment.
2355 PROCEDURE check_is_reservable_sub
2356   (   x_return_status       OUT NOCOPY VARCHAR2
2357     , p_organization_id     IN  VARCHAR2
2358     , p_subinventory_code   IN  VARCHAR2
2359     , x_is_reservable_sub   OUT NOCOPY BOOLEAN
2360       ) IS
2361          l_return_status    VARCHAR2(1) := fnd_api.g_ret_sts_success;
2362          l_reservable_type  NUMBER := 2;
2363          l_hash_value       NUMBER;
2364 BEGIN
2365    --Bug 4699159. The query is throwing a no data found exception when
2366    --p_subinventory_code is being passed as null.
2367    IF(p_subinventory_code IS NOT NULL) THEN
2368       l_hash_value := DBMS_UTILITY.get_hash_value
2369                       ( NAME      => p_organization_id ||'-'|| p_subinventory_code
2370                       , base      => 1
2371                       , hash_size => POWER(2, 25)
2372                       );
2373       IF g_is_sub_reservable.EXISTS(l_hash_value) AND
2374          g_is_sub_reservable(l_hash_value).org_id = p_organization_id AND
2375          g_is_sub_reservable(l_hash_value).subinventory_code = p_subinventory_code
2376       THEN
2377          l_reservable_type := g_is_sub_reservable(l_hash_value).reservable_type;
2378       ELSE
2379          SELECT reservable_type INTO l_reservable_type
2380            FROM mtl_secondary_inventories
2381           WHERE organization_id = p_organization_id
2382             AND secondary_inventory_name = p_subinventory_code;
2383          g_is_sub_reservable(l_hash_value).reservable_type := l_reservable_type;
2384          g_is_sub_reservable(l_hash_value).org_id := p_organization_id;
2385          g_is_sub_reservable(l_hash_value).subinventory_code := p_subinventory_code;
2386       END IF;
2387    END IF;
2388    IF (l_reservable_type = 1) THEN
2389       x_is_reservable_sub := TRUE;
2390    ELSE
2391       x_is_reservable_sub := FALSE;
2392    END IF;
2393 
2394    x_return_status := l_return_status;
2395 
2396 EXCEPTION
2397 
2398    WHEN OTHERS THEN
2399       x_return_status := fnd_api.g_ret_sts_unexp_error ;
2400 
2401       IF fnd_msg_pub.check_msg_level(fnd_msg_pub.g_msg_lvl_unexp_error)
2402       THEN
2403          fnd_msg_pub.add_exc_msg
2404             (  g_pkg_name
2405              , 'Check_Is_Reservable_SUB'
2406             );
2407       END IF;
2408 
2409 END check_is_reservable_sub;
2410 
2411 --Bug 3424532 fix
2412 -- Procedure
2413 --  check_is_reservable_item
2414 -- Description
2415 --  check from db tables whether the item specified in
2416 --  the input is a reservable or not.
2417 PROCEDURE check_is_reservable_item
2418   (   x_return_status       OUT NOCOPY VARCHAR2
2419     , p_organization_id     IN  NUMBER
2420     , p_inventory_item_id   IN  NUMBER
2421     , x_is_reservable_item  OUT NOCOPY BOOLEAN
2422       ) IS
2423          l_return_status    VARCHAR2(1) := fnd_api.g_ret_sts_success;
2424          l_reservable_type  NUMBER;
2425          l_no_info          BOOLEAN := FALSE;
2426 BEGIN
2427    IF NOT g_is_item_reservable.exists(p_inventory_item_id) THEN
2428       l_no_info := TRUE;
2429    ELSE
2430       IF g_is_item_reservable(p_inventory_item_id).org_id <> p_organization_id THEN
2431         l_no_info := TRUE;
2432       END IF;
2433    END IF;
2434 
2435    IF l_no_info THEN
2436       SELECT Nvl(reservable_type,2) INTO l_reservable_type
2437         FROM mtl_system_items
2438         WHERE organization_id = p_organization_id
2439         AND inventory_item_id = p_inventory_item_id;
2440       g_is_item_reservable(p_inventory_item_id).org_id := p_organization_id;
2441       IF (l_reservable_type = 1) THEN
2442          g_is_item_reservable(p_inventory_item_id).value := TRUE;
2443        ELSE
2444          g_is_item_reservable(p_inventory_item_id).value := FALSE;
2445       END IF;
2446    END IF;
2447 
2448    x_is_reservable_item := g_is_item_reservable(p_inventory_item_id).value;
2449 
2450    x_return_status := l_return_status;
2451 
2452 EXCEPTION
2453 
2454      WHEN OTHERS THEN
2455         x_return_status := fnd_api.g_ret_sts_unexp_error ;
2456 
2457         IF fnd_msg_pub.check_msg_level(fnd_msg_pub.g_msg_lvl_unexp_error)
2458           THEN
2459            fnd_msg_pub.add_exc_msg
2460              (  g_pkg_name
2461               , 'Check_Is_Reservable_item'
2462               );
2463         END IF;
2464 
2465 END check_is_reservable_item;
2466 
2467 -- invConv changes begin : new procedure that complete the use of check_is_reservable_sub
2468 -- Procedure
2469 --  check_is_reservable
2470 -- Description
2471 --  check from db tables whether the sub specified in
2472 --  the input is a reservable sub or not.
2473 PROCEDURE check_is_reservable
2474   (   x_return_status        OUT NOCOPY VARCHAR2
2475     , p_node_level           IN  INTEGER    DEFAULT NULL
2476     , p_inventory_item_id    IN  NUMBER
2477     , p_organization_id      IN  NUMBER
2478     , p_subinventory_code    IN  VARCHAR2
2479     , p_locator_id           IN  NUMBER
2480     , p_lot_number           IN  VARCHAR2
2481     , p_root_id              IN  NUMBER
2482     , x_is_reservable        OUT NOCOPY BOOLEAN
2483     , p_lpn_id               IN  NUMBER     DEFAULT NULL -- Onhand Material Status Support
2484       ) IS
2485 
2486 l_return_status    VARCHAR2(1) := fnd_api.g_ret_sts_success;
2487 l_reservable_type  NUMBER;
2488 l_default_onhand_status_id   NUMBER; -- Onhand Material Status Support
2489 
2490 /* Bug 6719389 */
2491 l_reservable_type_sub  NUMBER := 1;
2492 l_reservable_type_loc  NUMBER := 1;
2493 l_reservable_type_lot  NUMBER := 1;
2494 
2495 /* DE-NORMALIZED MATERIAL STATUS */
2496 CURSOR is_RSV_subInv( org_id IN NUMBER
2497                     , subinv IN VARCHAR2) IS
2498    SELECT NVL(msinv.reservable_type, 1)
2499    FROM mtl_secondary_inventories msinv
2500    WHERE msinv.organization_id = org_id
2501    AND msinv.secondary_inventory_name = subinv;
2502 
2503 
2504 /* NORMALIZED MATERIAL STATUS
2505 CURSOR is_RSV_subInv( org_id IN NUMBER
2506                     , subinv IN VARCHAR2) IS
2507 SELECT '1'
2508 FROM mtl_secondary_inventories msinv
2509 WHERE msinv.status_id IN
2510   (SELECT mms.status_id
2511    FROM mtl_material_statuses mms
2512    WHERE NVL(mms.reservable_type, 1) = 1
2513    AND mms.zone_control = 1)
2514 AND msinv.organization_id = org_id
2515 AND msinv.secondary_inventory_name = subinv;
2516 */
2517 
2518 /* DE-NORMALIZED MATERIAL STATUS */
2519 CURSOR is_RSV_loct( org_id IN NUMBER
2520                   , loct_id IN NUMBER) IS
2521    SELECT NVL(mil.reservable_type, 1)
2522    FROM mtl_item_locations mil
2523    WHERE mil.organization_id = org_id
2524    AND mil.inventory_location_id = loct_id;
2525 
2526 
2527 /* NORMALIZED MATERIAL STATUS
2528 CURSOR is_RSV_loct( org_id IN NUMBER
2529                   , loct_id IN NUMBER) IS
2530 SELECT '1'
2531 FROM mtl_item_locations mil
2532 WHERE mil.status_id IN
2533   (SELECT mms.status_id
2534    FROM mtl_material_statuses mms
2535    WHERE NVL(mms.reservable_type, 1) = 1
2536    AND mms.locator_control = 1)
2537 AND mil.organization_id = org_id
2538 AND mil.inventory_location_id = loct_id;
2539 */
2540 
2541 /* DE-NORMALIZED MATERIAL STATUS */
2542 CURSOR is_RSV_lot( org_id IN NUMBER
2543                  , item_id IN NUMBER
2544                  , lot IN VARCHAR2) IS
2545    SELECT NVL(mln.reservable_type, 1)
2546    FROM mtl_lot_numbers mln
2547    WHERE mln.inventory_item_id = item_id
2548    AND mln.organization_id = org_id
2549    AND mln.lot_number = lot;
2550 
2551 
2552 /* NORMALIZED MATERIAL STATUS
2553 CURSOR is_RSV_lot( org_id IN NUMBER
2554                  , item_id IN NUMBER
2555                  , lot IN VARCHAR2) IS
2556 SELECT '1'
2557 FROM mtl_lot_numbers mln
2558 WHERE mln.status_id IN
2559   (SELECT mms.status_id
2560    FROM mtl_material_statuses mms
2561    WHERE NVL(mms.reservable_type, 1) = 1
2562 AND mms.lot_control = 1)
2563 AND mln.inventory_item_id = item_id
2564 AND mln.organization_id = org_id
2565 AND mln.lot_number = lot;
2566 */
2567 
2568 /* ONHAND MATERIAL STATUS SUPPORT */
2569 CURSOR is_RSV_onhand( org_id IN NUMBER
2570                    , item_id IN NUMBER
2571                    , subinv  IN VARCHAR2
2572                    , loct_id IN NUMBER
2573                    , lot     IN VARCHAR2
2574                    , lpn_id  IN NUMBER) IS
2575    SELECT NVL(mms.reservable_type, 1)
2576    FROM mtl_onhand_quantities_detail moqd, mtl_material_statuses mms
2577    WHERE moqd.status_id = mms.status_id
2578    and moqd.status_id is not null
2579    AND moqd.inventory_item_id = item_id
2580    AND moqd.organization_id = org_id
2581    AND moqd.subinventory_code = subinv
2582    and nvl(moqd.locator_id, -9999) = nvl(loct_id, -9999)
2583    AND nvl(moqd.lot_number, '@@@@') = nvl(lot, '@@@@')
2584    AND nvl(moqd.lpn_id, -9999) = nvl(lpn_id, -9999)
2585    AND rownum = 1;
2586 
2587 BEGIN
2588    print_debug('in check_is_reservable. node_level='||p_node_level||', subinv='
2589       ||p_subinventory_code||', loct='||p_locator_id||', lot='||p_lot_number);
2590 
2591    IF (inv_quantity_tree_pvt.g_is_mat_status_used = 2) THEN
2592       --Bug 4587505. The value returned from here is used to set the is_reservable_sub property of the node
2593       --and for any node that is higher than subinventory(for example LOT node), the is_reservable_sub should
2594       --be set to TRUE, when INV_MATERIAL_STATUS profile is set to 2
2595       IF(p_subinventory_code IS NULL) THEN
2596          print_debug('....p_subinventory_code is null.setting x_is_reservable to TRUE...');
2597          x_is_reservable := TRUE;
2598       ELSE
2599          print_debug('.... check_is_reservable is calling check_is_reservable_sub...');
2600          check_is_reservable_sub( x_return_status       => x_return_status
2601                                 , p_organization_id     => p_organization_id
2602                                 , p_subinventory_code   => p_subinventory_code
2603                                 , x_is_reservable_sub   => x_is_reservable);
2604       END IF;
2605 
2606    ELSE
2607 
2608       -- Onhand Material Status Support
2609       IF inv_cache.set_org_rec(p_organization_id) THEN
2610          l_default_onhand_status_id := inv_cache.org_rec.default_status_id;
2611       END IF;
2612 
2613       print_debug('in check_is_rsv, default org status id='||l_default_onhand_status_id||', for org id='||p_organization_id);
2614 
2615       IF l_default_onhand_status_id is NULL THEN -- Onhand Material Status Support
2616          /*Bug #6719389 Changes done for honouring material status */
2617          /*IF (g_rootinfos(p_root_id).is_lot_status_enabled = FALSE)
2618          THEN
2619             -- Always reservable...
2620             l_reservable_type := 1;
2621          */
2622 
2623          IF (NVL(p_node_level,0) = g_revision_level)THEN
2624             l_reservable_type := 1;
2625             print_debug('in RSV reservable='||l_reservable_type||', for lot='||p_lot_number);
2626          ELSE
2627             IF (p_lot_number IS NOT NULL) THEN
2628                IF (g_rootinfos(p_root_id).is_lot_status_enabled = FALSE) THEN
2629                   l_reservable_type_lot := 1;
2630                ELSE
2631                   OPEN is_RSV_lot( p_organization_id, p_inventory_item_id, p_lot_number);
2632                   FETCH is_RSV_lot
2633                   INTO l_reservable_type_lot;
2634                   IF (is_RSV_lot%NOTFOUND) THEN
2635                      -- bug 3977807 : By default, the reservable flag is set to 1= reservable.
2636                      l_reservable_type_lot := 1;
2637                   END IF;
2638                   CLOSE is_RSV_lot;
2639                   print_debug('New in RSV reservable='||l_reservable_type_lot||', for lot='||p_lot_number);
2640                END IF;
2641             END IF;
2642 
2643             IF (p_subinventory_code IS NOT NULL) THEN
2644                OPEN is_RSV_subInv( p_organization_id, p_subinventory_code);
2645                FETCH is_RSV_subInv
2646                INTO l_reservable_type_sub;
2647                IF (is_RSV_subInv%NOTFOUND) THEN
2648                   -- bug 3977807 : By default, the reservable flag is set to 1= reservable.
2649                   l_reservable_type_sub := 1;
2650                END IF;
2651                CLOSE is_RSV_subInv;
2652                print_debug('New in RSV reservable='||l_reservable_type_sub||', for subInv='||p_subinventory_code);
2653             END IF;
2654 
2655             IF (p_locator_id IS NOT NULL) THEN
2656                OPEN is_RSV_loct( p_organization_id, p_locator_id);
2657                FETCH is_RSV_loct
2658                INTO l_reservable_type_loc;
2659                IF (is_RSV_loct%NOTFOUND) THEN
2660                   -- bug 3977807 : By default, the reservable flag is set to 1= reservable.
2661                   l_reservable_type_loc := 1;
2662                END IF;
2663                CLOSE is_RSV_loct;
2664                print_debug('New in RSV reservable='||l_reservable_type_loc||', for locator='||p_locator_id);
2665             END IF;
2666 
2667             IF (l_reservable_type_sub = 1 and l_reservable_type_loc = 1 and l_reservable_type_lot = 1) THEN
2668                l_reservable_type := 1;
2669                print_debug('New in RSV reservable=TRUE');
2670             ELSE
2671                l_reservable_type := 2;
2672                print_debug('New in RSV reservable=FALSE');
2673             END IF;
2674          END IF;   -- is_lot_status_enabled...
2675       /* Bug #6719389 Commented the code below as the code above handles the same */
2676 
2677       /*-- invConv comment : UTtest, dec04, removed "AND p_locator_id IS NULL" in test.
2678         --          and changed "subinventory IS NULL" as at lot level, subInv is always known
2679         ELSIF  (NVL(p_node_level,0) = g_lot_level) OR
2680                 (p_lot_number IS NOT NULL AND p_subinventory_code IS NOT NULL)
2681         THEN
2682          OPEN is_RSV_lot( p_organization_id, p_inventory_item_id, p_lot_number);
2683          FETCH is_RSV_lot
2684           INTO l_reservable_type;
2685          IF (is_RSV_lot%NOTFOUND)
2686          THEN
2687             -- bug 3977807 : By default, the reservable flag is set to 1= reservable.
2688             l_reservable_type := 1;
2689          END IF;
2690          CLOSE is_RSV_lot;
2691           print_debug('in RSV reservable='||l_reservable_type||', for lot='||p_lot_number);
2692 
2693         ELSIF  (NVL(p_node_level, 0) = g_locator_level)
2694           OR  (p_locator_id IS NOT NULL)
2695         THEN
2696          OPEN is_RSV_loct( p_organization_id, p_locator_id);
2697          FETCH is_RSV_loct
2698           INTO l_reservable_type;
2699          IF (is_RSV_loct%NOTFOUND)
2700          THEN
2701             -- bug 3977807 : By default, the reservable flag is set to 1= reservable.
2702             l_reservable_type := 1;
2703          END IF;
2704          CLOSE is_RSV_loct;
2705           print_debug('in RSV reservable='||l_reservable_type||', for locator='||p_locator_id);
2706 
2707          -- in that case... need to check at lot level if lot really reservable:
2708          -- bug 3941293 : added lot NOT NULL in the test.
2709          IF (l_reservable_type = 1
2710            AND p_lot_number IS NOT NULL) THEN
2711            OPEN is_RSV_lot( p_organization_id, p_inventory_item_id, p_lot_number);
2712            FETCH is_RSV_lot
2713             INTO l_reservable_type;
2714            IF (is_RSV_lot%NOTFOUND)
2715            THEN
2716               -- bug 3977807 : By default, the reservable flag is set to 1= reservable.
2717               l_reservable_type := 1;
2718            END IF;
2719            CLOSE is_RSV_lot;
2720           print_debug('in RSV reservable='||l_reservable_type||', for locator+++='||p_locator_id);
2721          ELSE
2722           print_debug('in RSV reservable='||l_reservable_type||', for locator='||p_locator_id);
2723          END IF;
2724 
2725         ELSIF  (NVL(p_node_level, 0) = g_sub_level)
2726           OR  (p_subinventory_code IS NOT NULL AND p_locator_id IS NULL)
2727         THEN
2728           print_debug('in RSV reservable='||l_reservable_type||', for subInv='||p_subinventory_code);
2729          OPEN is_RSV_subInv( p_organization_id, p_subinventory_code);
2730          FETCH is_RSV_subInv
2731           INTO l_reservable_type;
2732          IF (is_RSV_subInv%NOTFOUND)
2733          THEN
2734               -- bug 3977807 : By default, the reservable flag is set to 1= reservable.
2735               l_reservable_type := 1;
2736          END IF;
2737          CLOSE is_RSV_subInv;
2738          print_debug('in RSV reservable='||l_reservable_type||', for subInv='||p_subinventory_code);
2739 
2740          -- in that case... need to check at lot level if lot is really reservable:
2741          -- bug 3980387 : added the check reservable for the lot :
2742          IF (l_reservable_type = 1
2743            AND p_lot_number IS NOT NULL) THEN
2744            OPEN is_RSV_lot( p_organization_id, p_inventory_item_id, p_lot_number);
2745            FETCH is_RSV_lot
2746             INTO l_reservable_type;
2747            IF (is_RSV_lot%NOTFOUND)
2748            THEN
2749               -- bug 3977807 : By default, the reservable flag is set to 1= reservable.
2750               l_reservable_type := 1;
2751            END IF;
2752            CLOSE is_RSV_lot;
2753           print_debug('in RSV reservable='||l_reservable_type||', for lot under subInv+++='||p_subinventory_code);
2754          ELSE
2755           print_debug('in RSV reservable='||l_reservable_type||', for SubInv='||p_subinventory_code);
2756          END IF;
2757         END IF;
2758        END IF;  */ -- is_lot_status_enabled...
2759       ELSE
2760           OPEN is_RSV_onhand( p_organization_id, p_inventory_item_id, p_subinventory_code, p_locator_id, p_lot_number, p_lpn_id);
2761           FETCH is_RSV_onhand
2762           INTO l_reservable_type;
2763           IF (is_RSV_onhand%NOTFOUND) THEN
2764              -- bug 3977807 : By default, the reservable flag is set to 1= reservable.
2765              l_reservable_type := 1;
2766              print_debug('in RSV reservable, onhand record not found');
2767           END IF;
2768           CLOSE is_RSV_onhand;
2769           print_debug('in RSV reservable='||l_reservable_type||', for onhand record');
2770       END IF; -- Onhand Material Status Support End
2771 
2772       /* Bug 6719389 */
2773       IF l_reservable_type = 1 THEN
2774          x_is_reservable := TRUE;
2775          print_debug('in RSV reservable=TRUE');
2776       ELSE
2777          x_is_reservable := FALSE;
2778          print_debug('in RSV reservable=FALSE');
2779       END IF;
2780 
2781       x_return_status := l_return_status;
2782    END IF; --- g_is_mat_status_used.
2783 
2784 EXCEPTION
2785 
2786    WHEN OTHERS THEN
2787       print_debug('in check_is_reservable, OTHERS Error='||SQLERRM, 9);
2788       x_return_status := fnd_api.g_ret_sts_unexp_error ;
2789 
2790       IF fnd_msg_pub.check_msg_level(fnd_msg_pub.g_msg_lvl_unexp_error)
2791       THEN
2792          fnd_msg_pub.add_exc_msg
2793              (  g_pkg_name
2794               , 'Check_Is_Reservable'
2795               );
2796       END IF;
2797 
2798 END check_is_reservable;
2799 
2800 -- invConv changes end
2801 
2802 
2803 FUNCTION is_tree_valid
2804   (
2805    p_tree_id IN INTEGER
2806    ) RETURN BOOLEAN IS
2807 BEGIN
2808    IF p_tree_id IS NULL THEN
2809       RETURN FALSE;
2810    END IF;
2811 
2812    IF p_tree_id <= 0
2813 --   OR p_tree_id > g_rootinfo_counter
2814    THEN
2815       RETURN FALSE;
2816    END IF;
2817 
2818    IF g_rootinfos.exists(p_tree_id) = FALSE THEN
2819       RETURN FALSE;
2820    END IF;
2821 
2822    IF g_rootinfos(p_tree_id).inventory_item_id IS NULL THEN
2823       RETURN FALSE;
2824    END IF;
2825 
2826    RETURN TRUE;
2827 END is_tree_valid;
2828 
2829 FUNCTION is_saved_tree_valid
2830   (
2831    p_tree_id IN INTEGER
2832    ) RETURN BOOLEAN IS
2833 BEGIN
2834    IF p_tree_id IS NULL THEN
2835       RETURN FALSE;
2836    END IF;
2837 
2838    IF g_saveroots.exists(p_tree_id) = FALSE THEN
2839       RETURN FALSE;
2840    END IF;
2841 
2842    IF g_saveroots(p_tree_id).inventory_item_id IS NULL THEN
2843       RETURN FALSE;
2844    END IF;
2845 
2846    RETURN TRUE;
2847 END is_saved_tree_valid;
2848 
2849 PROCEDURE invalidate_tree
2850   (
2851    p_tree_id IN INTEGER
2852    ) IS
2853 BEGIN
2854    IF is_tree_valid(p_tree_id) THEN
2855       g_rootinfos(p_tree_id).inventory_item_id := NULL;
2856       g_rootinfos(p_tree_id).organization_id := NULL;
2857       g_rootinfos(p_tree_id).need_refresh := TRUE;
2858    END IF;
2859 
2860    IF is_saved_tree_valid(p_tree_id) THEN
2861       g_saveroots(p_tree_id).inventory_item_id := NULL;
2862       g_saveroots(p_tree_id).organization_id := NULL;
2863    END IF;
2864 
2865 
2866 END invalidate_tree;
2867 
2868 
2869 -- Function
2870 --    find_rootinfo
2871 -- Description
2872 --    find a rootinfo record based on input parameters
2873 --  Return
2874 --    0                          if rootinfo not found
2875 --    >0                         index for the rootinfo in the rootinfo array
2876 FUNCTION find_rootinfo
2877   (   x_return_status            OUT NOCOPY VARCHAR2
2878    ,  p_organization_id          IN  NUMBER
2879    ,  p_inventory_item_id        IN  NUMBER
2880    ,  p_tree_mode                IN  INTEGER
2881    ,  p_is_revision_control      IN  BOOLEAN
2882    ,  p_is_lot_control           IN  BOOLEAN
2883    ,  p_is_serial_control        IN  BOOLEAN
2884    ,  p_asset_sub_only           IN  BOOLEAN
2885    ,  p_include_suggestion       IN  BOOLEAN
2886    ,  p_demand_source_type_id    IN  NUMBER
2887    ,  p_demand_source_header_id  IN  NUMBER
2888    ,  p_demand_source_line_id    IN  NUMBER
2889    ,  p_demand_source_name       IN  VARCHAR2
2890    ,  p_demand_source_delivery   IN  NUMBER
2891    ,  p_lot_expiration_date      IN  DATE
2892    ,  p_onhand_source            IN  NUMBER
2893    ,  p_pick_release             IN  NUMBER
2894    ) RETURN INTEGER
2895   IS
2896 
2897      l_return_status            VARCHAR2(1) := fnd_api.g_ret_sts_success;
2898      l_rootinfo_index           INTEGER;
2899      l_hash_base                NUMBER;
2900      l_hash_size                NUMBER;
2901      l_hash_string              VARCHAR2(1000);
2902      l_tree_index               NUMBER;
2903      l_original_tree_index      NUMBER;
2904 
2905 BEGIN
2906    l_rootinfo_index := 1;
2907 
2908    print_debug('odab enterin find_rootinfo for :');
2909    print_debug('org ' || p_organization_id);
2910    print_debug('item ' || p_inventory_item_id);
2911    print_debug('tree ' || p_tree_mode);
2912    print_debug('dsrc ' || p_demand_source_type_id);
2913    print_debug('dhdr ' || p_demand_source_header_id);
2914    print_debug('dlin ' || p_demand_source_line_id);
2915    print_debug('dnme ' || p_demand_source_name);
2916    print_debug('ddel ' || p_demand_source_delivery);
2917    print_debug('exp ' || p_lot_expiration_date);
2918    print_debug('onh ' || p_onhand_source);
2919    print_debug('rel ' || p_pick_release);
2920    IF   p_is_lot_control THEN
2921       print_debug('lot_control=TRUE');
2922    ELSE
2923       print_debug('lot_control=FALSE');
2924    END IF;
2925 
2926 
2927    l_hash_base := 1;
2928    l_hash_size := power(2, 20);
2929    l_hash_string := build_hash_string (
2930         l_return_status
2931       , p_organization_id
2932       , p_inventory_item_id
2933       , p_tree_mode
2934       , p_is_revision_control
2935       , p_is_lot_control
2936       , p_asset_sub_only
2937       , p_demand_source_type_id
2938       , p_demand_source_header_id
2939       , p_demand_source_line_id
2940       , p_demand_source_name
2941       , p_lot_expiration_date
2942       , p_onhand_source);
2943 
2944    print_debug('in find_rootinfo: hashString_1='||l_hash_string);
2945    g_hash_string := l_hash_string;
2946    -- Bug 2092207 - hash procedure returning duplicate indices;
2947    --   doubling length of name to try to decrease probability of
2948    --   getting duplicate values
2949    l_tree_index := dbms_utility.get_hash_value(
2950                name       => l_hash_string || l_hash_string
2951              , base       => l_hash_base
2952              , hash_size  => l_hash_size);
2953 
2954    --Bug 5241485 fix
2955    l_original_tree_index := l_tree_index;
2956 
2957    print_debug('in find_rootinfo: tree_index='||l_tree_index);
2958 
2959    -- Bug 2092207 - catch duplicate tree indices. If hash string
2960    -- does not match the hash string of the found tree index,
2961    -- the get_hash_value procedure is returning duplicate tree indices
2962    -- for different hash strings.  In that case, increment the index and
2963    -- check to see if the tree with the matching hash string is at that value.
2964    -- Exit loop when correct root is found, or when empty root is found
2965 
2966    IF g_rootinfos.exists(l_tree_index) THEN
2967       WHILE g_rootinfos(l_tree_index).hash_string <> l_hash_string LOOP
2968          print_debug('in find_rootinfo: saved_HashString='||g_rootinfos(l_tree_index).hash_string);
2969 
2970          l_tree_index := l_tree_index + 1;
2971          -- if empty root is found, then the tree does not exist yet
2972          If NOT g_rootinfos.exists(l_tree_index) THEN
2973             g_empty_root_index := l_tree_index;
2974             EXIT;
2975          End If;
2976          -- if we reach the end of the possible index values, loop back to 1.
2977          If l_tree_index >= power(2,20) Then
2978             l_tree_index := 1;
2979          End If;
2980          -- if this ever true, we've used all the possible indices. Raise
2981          -- an exception.
2982          If l_tree_index = l_original_tree_index Then
2983             RAISE fnd_api.g_exc_unexpected_error;
2984          End If;
2985       END LOOP;
2986       --Bug 5241485 fix. This one causing no data found exception
2987       print_debug('in find_rootinfo: AFTER LOOP l_tree_index:'||l_tree_index);
2988    END IF;
2989 
2990    /*
2991    WHILE (l_rootinfo_index <= g_rootinfo_counter) LOOP
2992       IF (p_organization_id =
2993               g_rootinfos(l_rootinfo_index).organization_id
2994         AND p_inventory_item_id =
2995               g_rootinfos(l_rootinfo_index).inventory_item_id
2996    --Bug 1384720 - no diff. between rsv and txn mode
2997         AND ((p_tree_mode IN (g_reservation_mode, g_transaction_mode)
2998               AND g_rootinfos(l_rootinfo_index).tree_mode IN
2999         (g_reservation_mode, g_transaction_mode))
3000        OR (p_tree_mode = g_loose_only_mode
3001          AND p_tree_mode = g_rootinfos(l_rootinfo_index).tree_mode))
3002         AND p_is_revision_control =
3003               g_rootinfos(l_rootinfo_index).is_revision_control
3004         AND p_is_lot_control =
3005               g_rootinfos(l_rootinfo_index).is_lot_control
3006      --     AND p_is_serial_control =
3007      --         g_rootinfos(l_rootinfo_index).is_serial_control
3008         AND p_asset_sub_only =
3009               g_rootinfos(l_rootinfo_index).asset_sub_only
3010       --    AND p_include_suggestion =
3011       --        g_rootinfos(l_rootinfo_index).include_suggestion
3012       --demand source info only matters in loose only mode
3013        AND (p_tree_mode IN (g_reservation_mode, g_transaction_mode)
3014           OR(
3015               (p_demand_source_type_id IS NULL
3016               AND g_rootinfos(l_rootinfo_index).demand_source_type_id IS NULL
3017               OR  p_demand_source_type_id =
3018               g_rootinfos(l_rootinfo_index).demand_source_type_id
3019               )
3020           AND (p_demand_source_header_id IS NULL
3021               AND g_rootinfos(l_rootinfo_index).demand_source_header_id IS NULL
3022               OR  p_demand_source_header_id =
3023               g_rootinfos(l_rootinfo_index).demand_source_header_id
3024               )
3025           AND (p_demand_source_line_id IS NULL
3026               AND g_rootinfos(l_rootinfo_index).demand_source_line_id IS NULL
3027               OR  p_demand_source_line_id =
3028               g_rootinfos(l_rootinfo_index).demand_source_line_id
3029               )
3030           AND (p_demand_source_name IS NULL
3031               AND g_rootinfos(l_rootinfo_index).demand_source_name IS NULL
3032               OR  p_demand_source_name =
3033               g_rootinfos(l_rootinfo_index).demand_source_name
3034               )
3035           AND (p_demand_source_delivery IS NULL
3036               AND g_rootinfos(l_rootinfo_index).demand_source_delivery IS NULL
3037               OR  p_demand_source_delivery =
3038               g_rootinfos(l_rootinfo_index).demand_source_delivery
3039               )))
3040        AND (p_lot_expiration_date IS NULL
3041               AND g_rootinfos(l_rootinfo_index).lot_expiration_date IS NULL
3042               OR  p_lot_expiration_date =
3043               g_rootinfos(l_rootinfo_index).lot_expiration_date
3044               )
3045        AND ((p_onhand_source IS NULL
3046        AND g_rootinfos(l_rootinfo_index).onhand_source IS NULL)
3047        OR p_onhand_source =
3048               g_rootinfos(l_rootinfo_index).onhand_source)
3049        --now stored in demand_info
3050        --AND ((p_pick_release IS NULL
3051 --      AND g_rootinfos(l_rootinfo_index).pick_release IS NULL)
3052  --            OR p_pick_release =
3053   --            g_rootinfos(l_rootinfo_index).pick_release)
3054        ) THEN
3055         EXIT;
3056       END IF;
3057       l_rootinfo_index := l_rootinfo_index +1;
3058    END LOOP;
3059 
3060    */
3061 
3062    x_return_status := l_return_status;
3063 /*
3064    IF (l_rootinfo_index > g_rootinfo_counter) THEN
3065       --dbms_output.put_line('root not found');
3066       RETURN 0;                -- rootinfo node not found
3067     ELSE
3068 */
3069    IF g_rootinfos.exists(l_tree_index) THEN
3070       --Bug 1384720 - performance improvements
3071       -- Every time this procedure is called, insert a new record
3072       --  in demand_info table.  Return the index for that record as the tree_id
3073       g_demand_counter := g_demand_counter + 1;
3074       g_demand_info(g_demand_counter).root_id                  := l_tree_index;
3075       g_demand_info(g_demand_counter).tree_mode                := p_tree_mode;
3076       g_demand_info(g_demand_counter).pick_release             := p_pick_release;
3077       g_demand_info(g_demand_counter).demand_source_type_id    := p_demand_source_type_id;
3078       g_demand_info(g_demand_counter).demand_source_header_id  := p_demand_source_header_id;
3079       g_demand_info(g_demand_counter).demand_source_line_id    := p_demand_source_line_id;
3080       g_demand_info(g_demand_counter).demand_source_name       := p_demand_source_name;
3081       g_demand_info(g_demand_counter).demand_source_delivery   := p_demand_source_delivery;
3082       l_rootinfo_index := g_demand_counter;
3083       print_debug('odab in find_rootinfo Normal End with index='||l_rootinfo_index||', return='||x_return_status);
3084       RETURN l_rootinfo_index; -- rootinfo node found
3085    ELSE
3086       print_debug('odab in find_rootinfo Normal End With index=0, NOT FOUND, return='||x_return_status);
3087       RETURN 0;                -- rootinfo node not found
3088    END IF;
3089 
3090 EXCEPTION
3091    WHEN OTHERS THEN
3092       x_return_status := fnd_api.g_ret_sts_unexp_error ;
3093       print_debug('odab in find_rootinfo OTHERS='||SQLERRM, 9);
3094       IF fnd_msg_pub.check_msg_level(fnd_msg_pub.g_msg_lvl_unexp_error)
3095         THEN
3096          fnd_msg_pub.add_exc_msg
3097            (  g_pkg_name
3098               , 'Find_Rootinfo'
3099               );
3100       END IF;
3101       RETURN 0;
3102 
3103 END find_rootinfo;
3104 
3105 -- Function
3106 --   find_child_node
3107 -- Description
3108 --   search the child linked list of a parent node
3109 --   for a child node that has the value specified in the input
3110 --   and if no such child node, create it. So it should always
3111 --   return true, unlese there is exception occurred
3112 FUNCTION find_child_node
3113   (  x_return_status        OUT NOCOPY VARCHAR2
3114    , p_node_level           IN  INTEGER
3115    , p_tree_id        IN  INTEGER
3116    , p_revision             IN  VARCHAR2  DEFAULT NULL
3117    , p_lot_number           IN  VARCHAR2  DEFAULT NULL
3118    , p_subinventory_code    IN  VARCHAR2  DEFAULT NULL
3119    , p_is_reservable_sub    IN  BOOLEAN   DEFAULT NULL
3120    , p_locator_id           IN  NUMBER    DEFAULT NULL
3121    , p_lpn_id               IN  NUMBER    DEFAULT NULL
3122    , p_cost_group_id        IN  NUMBER    DEFAULT NULL
3123    , x_child_index          OUT NOCOPY INTEGER
3124    ) RETURN BOOLEAN IS
3125       l_return_status       VARCHAR2(1) := fnd_api.g_ret_sts_success;
3126       l_node_index          INTEGER;
3127       l_hash_string      VARCHAR2(300);
3128       l_hash_size     NUMBER;
3129       l_hash_base     NUMBER := 1;
3130       l_prev_node_index     NUMBER;
3131 
3132 BEGIN
3133    IF p_revision IS NULL
3134       AND p_lot_number IS NULL
3135       AND p_subinventory_code IS NULL
3136       AND p_locator_id IS NULL
3137       AND p_lpn_id IS NULL
3138       AND p_cost_group_id IS NULL
3139         THEN
3140       fnd_message.set_name('INV','INV-Cannot find node');
3141       fnd_message.set_token('ROUTINE', 'Find_Child_Node');
3142       fnd_msg_pub.ADD;
3143       RAISE fnd_api.g_exc_error;
3144    END IF;
3145 
3146 
3147    print_debug('... in find_child_node, building the hash string...');
3148    --build hash string
3149    l_hash_size := power(2,29);
3150    IF g_max_hash_rec = 0 then
3151       g_max_hash_rec := l_hash_size + 1;
3152    END IF;
3153       l_hash_string := p_tree_id || ':' || p_revision || ':' ||
3154           p_lot_number || ':' || p_subinventory_code || ':' ||
3155           p_locator_id || ':' || p_lpn_id || ':' ||
3156           p_cost_group_id;
3157 
3158       --get hash value using dbms_utility package
3159       l_node_index := dbms_utility.get_hash_value(
3160                         name       => l_hash_string
3161                        ,base       => l_hash_base
3162                        ,hash_size  => l_hash_size);
3163 
3164       print_debug('... in find_child_node,  after dbms_utility.get_hash_value');
3165 
3166       IF g_nodes.exists(l_node_index) THEN
3167          WHILE g_nodes(l_node_index).hash_string <> l_hash_string LOOP
3168          l_prev_node_index := l_node_index;
3169          l_node_index := g_nodes(l_node_index).next_hash_record;
3170          IF l_node_index = 0 THEN
3171             g_max_hash_rec := g_max_hash_rec + 1;
3172             l_node_index := g_max_hash_rec;
3173             g_nodes(l_prev_node_index).next_hash_record := l_node_index;
3174             EXIT; --exit loop
3175          End IF;
3176       END LOOP;
3177    END IF;
3178 
3179    IF not g_nodes.exists(l_node_index) THEN
3180       print_debug('... in find_child_node,  calling new_tree_node');
3181       new_tree_node(
3182            x_return_status       => l_return_status
3183          , p_node_level          => p_node_level
3184          , p_revision            => p_revision
3185          , p_lot_number          => p_lot_number
3186          , p_subinventory_code   => p_subinventory_code
3187          , p_is_reservable_sub   => p_is_reservable_sub
3188          , p_locator_id          => p_locator_id
3189          , p_lpn_id              => p_lpn_id
3190          , p_cost_group_id       => p_cost_group_id
3191          , p_node_index          => l_node_index
3192          , p_hash_string         => l_hash_string);
3193 
3194    END IF;
3195 
3196    x_child_index := l_node_index;
3197    x_return_status := l_return_status;
3198 
3199    RETURN TRUE;
3200 
3201 EXCEPTION
3202 
3203    WHEN fnd_api.g_exc_error THEN
3204         x_return_status := fnd_api.g_ret_sts_error;
3205 
3206    WHEN fnd_api.g_exc_unexpected_error THEN
3207         x_return_status := fnd_api.g_ret_sts_unexp_error ;
3208 
3209     WHEN OTHERS THEN
3210         x_return_status := fnd_api.g_ret_sts_unexp_error ;
3211 
3212         -- For performance reasons during pick release only do this ifdebug is on
3213         IF ((NOT g_is_pickrelease) OR nvl(g_debug,2) = 1) THEN
3214           IF fnd_msg_pub.check_msg_level(fnd_msg_pub.g_msg_lvl_unexp_error)
3215             THEN
3216              fnd_msg_pub.add_exc_msg
3217                (  g_pkg_name
3218                 , 'Find_Child_Node'
3219                 );
3220           END IF;
3221         END IF;
3222 
3223 END find_child_node;
3224 
3225 -- Function
3226 --   find_tree_node
3227 -- Description
3228 --   find the tree node based on values of the input. If
3229 --   the node and its ancestors do not exist in the tree
3230 --   , create them
3231 FUNCTION find_tree_node
3232   (   x_return_status        OUT NOCOPY VARCHAR2
3233    ,  p_tree_id              IN  INTEGER
3234    ,  p_revision             IN  VARCHAR2
3235    ,  p_lot_number           IN  VARCHAR2
3236    ,  p_subinventory_code    IN  VARCHAR2
3237    ,  p_is_reservable_sub    IN  BOOLEAN
3238    ,  p_locator_id           IN  NUMBER
3239    ,  x_node_index           OUT NOCOPY INTEGER
3240    ,  p_lpn_id               IN  NUMBER
3241    ,  p_cost_group_id        IN  NUMBER
3242    ) RETURN BOOLEAN IS
3243       l_return_status        VARCHAR2(1) := fnd_api.g_ret_sts_success;
3244       l_current_node_index   INTEGER;
3245       l_child_node_index     INTEGER;
3246       l_found                BOOLEAN;
3247       l_last_child        INTEGER;
3248       l_item_node      INTEGER;
3249 
3250 BEGIN
3251    x_node_index := 0;
3252    l_child_node_index := 0;
3253    l_current_node_index := 0;
3254   /*
3255    * Remove CG node from quantity tree.  With the advent of
3256    * measures to prevent cost group commingling, cost group availability
3257    * becomes unimportant
3258    * IF p_cost_group_id IS NOT NULL THEN
3259    *   -- search for the cost group node
3260    *   l_found :=
3261    *     find_child_node(
3262    *                       x_return_status      => l_return_status
3263    *                     , p_node_level        => g_cost_group_level
3264    *                     , p_tree_id          => p_tree_id
3265    *                     , p_revision           => p_revision
3266    *                     , p_lot_number         => p_lot_number
3267    *                     , p_subinventory_code  => p_subinventory_code
3268    *                     , p_is_reservable_sub  => p_is_reservable_sub
3269    *                     , p_locator_id         => p_locator_id
3270    *                     , p_lpn_id             => p_lpn_id
3271    *                     , p_cost_group_id      => p_cost_group_id
3272    *                     , x_child_index        => l_current_node_index
3273    *                     );
3274    *
3275    *   IF l_return_status = fnd_api.g_ret_sts_error THEN
3276    *      RAISE fnd_api.g_exc_error;
3277    *   End IF ;
3278    *
3279    *   IF l_return_status = fnd_api.g_ret_sts_unexp_error THEN
3280    *      RAISE fnd_api.g_exc_unexpected_error;
3281    *   End IF;
3282    *
3283    *   IF l_found = FALSE THEN
3284    *      fnd_message.set_name('INV','INV-Cannot find node');
3285    *      fnd_message.set_token('ROUTINE', 'Find_Tree_Node');
3286    *      fnd_msg_pub.ADD;
3287    *      RAISE fnd_api.g_exc_unexpected_error;
3288    *   End IF;
3289    *
3290    *   l_child_node_index := l_current_node_index;
3291    *   x_node_index := l_current_node_index;
3292    *   IF g_nodes(l_current_node_index).parent_index <> 0 THEN
3293    *      x_return_status := l_return_status;
3294    *   RETURN TRUE;
3295    *  END IF;
3296    *END IF;
3297    */
3298 
3299    IF p_lpn_id IS NOT NULL THEN
3300       -- search for the cost group node
3301       l_found := find_child_node(
3302                           x_return_status      => l_return_status
3303                         , p_node_level         => g_lpn_level
3304                         , p_tree_id            => p_tree_id
3305                         , p_revision           => p_revision
3306                         , p_lot_number         => p_lot_number
3307                         , p_subinventory_code  => p_subinventory_code
3308                         , p_is_reservable_sub  => p_is_reservable_sub
3309                         , p_locator_id         => p_locator_id
3310                         , p_lpn_id             => p_lpn_id
3311                         , p_cost_group_id      => NULL
3312                         , x_child_index        => l_current_node_index
3313                         );
3314 
3315       IF l_return_status = fnd_api.g_ret_sts_error THEN
3316          RAISE fnd_api.g_exc_error;
3317       End IF ;
3318 
3319       IF l_return_status = fnd_api.g_ret_sts_unexp_error THEN
3320          RAISE fnd_api.g_exc_unexpected_error;
3321       End IF;
3322 
3323       IF l_found = FALSE THEN
3324          fnd_message.set_name('INV','INV-Cannot find node');
3325          fnd_message.set_token('ROUTINE', 'Find_Tree_Node');
3326          fnd_msg_pub.ADD;
3327          RAISE fnd_api.g_exc_unexpected_error;
3328       End IF;
3329 
3330       IF l_child_node_index <> 0 THEN
3331          IF g_nodes(l_current_node_index).first_child_index = 0 THEN
3332            g_nodes(l_current_node_index).first_child_index := l_child_node_index;
3333            g_nodes(l_current_node_index).last_child_index := l_child_node_index;
3334          ELSE
3335            l_last_child := g_nodes(l_current_node_index).last_child_index;
3336            g_nodes(l_last_child).next_sibling_Index := l_child_node_index;
3337            g_nodes(l_current_node_index).last_child_index := l_child_node_index;
3338          END IF;
3339          g_nodes(l_child_node_index).parent_index := l_current_node_index;
3340       END IF;
3341       l_child_node_index := l_current_node_index;
3342       IF x_node_index = 0 THEN
3343         x_node_index := l_current_node_index;
3344       End IF;
3345       IF g_nodes(l_current_node_index).parent_index <> 0 THEN
3346           x_return_status := l_return_status;
3347           print_debug('---End of find_tree_node... x_node_index='||x_node_index||', current_node_index='||l_current_node_index||'.');
3348           RETURN TRUE;
3349       END IF;
3350    END IF;
3351 
3352    IF p_locator_id IS NOT NULL THEN
3353       -- search for the cost group node
3354       print_debug('... entering find_child_node for loct='||p_locator_id||', lot='||substr(p_lot_number, 1,10) );
3355       l_found := find_child_node(
3356                           x_return_status      => l_return_status
3357                         , p_node_level         => g_locator_level
3358                         , p_tree_id            => p_tree_id
3359                         , p_revision           => p_revision
3360                         , p_lot_number         => p_lot_number
3361                         , p_subinventory_code  => p_subinventory_code
3362                         , p_is_reservable_sub  => p_is_reservable_sub
3363                         , p_locator_id         => p_locator_id
3364                         , p_lpn_id             => NULL
3365                         , p_cost_group_id      => NULL
3366                         , x_child_index        => l_current_node_index
3367                         );
3368 
3369       IF l_return_status = fnd_api.g_ret_sts_error THEN
3370          RAISE fnd_api.g_exc_error;
3371       End IF ;
3372 
3373       IF l_return_status = fnd_api.g_ret_sts_unexp_error THEN
3374          RAISE fnd_api.g_exc_unexpected_error;
3375       End IF;
3376 
3377       IF l_found = FALSE THEN
3378          fnd_message.set_name('INV','INV-Cannot find node');
3379          fnd_message.set_token('ROUTINE', 'Find_Tree_Node');
3380          fnd_msg_pub.ADD;
3381          RAISE fnd_api.g_exc_unexpected_error;
3382       End IF;
3383 
3384       If l_child_node_index <> 0 Then
3385          if g_nodes(l_current_node_index).first_child_index = 0 then
3386            g_nodes(l_current_node_index).first_child_index := l_child_node_index;
3387            g_nodes(l_current_node_index).last_child_index := l_child_node_index;
3388          else
3389            l_last_child := g_nodes(l_current_node_index).last_child_index;
3390            g_nodes(l_last_child).next_sibling_Index := l_child_node_index;
3391            g_nodes(l_current_node_index).last_child_index := l_child_node_index;
3392          end if;
3393          g_nodes(l_child_node_index).parent_index := l_current_node_index;
3394       End If;
3395       l_child_node_index := l_current_node_index;
3396       If x_node_index = 0 Then
3397         x_node_index := l_current_node_index;
3398       End If;
3399       IF g_nodes(l_current_node_index).parent_index <> 0 THEN
3400          x_return_status := l_return_status;
3401          print_debug('--End of find_tree_node... x_node_index='||x_node_index||', current_node_index='||l_current_node_index||'.');
3402          RETURN TRUE;
3403       END IF;
3404    END IF;
3405 
3406    IF p_subinventory_code IS NOT NULL THEN
3407       -- search for the cost group node
3408       l_found := find_child_node(
3409                           x_return_status      => l_return_status
3410                         , p_node_level         => g_sub_level
3411                         , p_tree_id            => p_tree_id
3412                         , p_revision           => p_revision
3413                         , p_lot_number         => p_lot_number
3414                         , p_subinventory_code  => p_subinventory_code
3415                         , p_is_reservable_sub  => p_is_reservable_sub
3416                         , p_locator_id         => NULL
3417                         , p_lpn_id             => NULL
3418                         , p_cost_group_id      => NULL
3419                         , x_child_index        => l_current_node_index
3420                         );
3421 
3422       IF l_return_status = fnd_api.g_ret_sts_error THEN
3423          RAISE fnd_api.g_exc_error;
3424       End IF ;
3425 
3426       IF l_return_status = fnd_api.g_ret_sts_unexp_error THEN
3427          RAISE fnd_api.g_exc_unexpected_error;
3428       End IF;
3429 
3430       IF l_found = FALSE THEN
3431          fnd_message.set_name('INV','INV-Cannot find node');
3432          fnd_message.set_token('ROUTINE', 'Find_Tree_Node');
3433          fnd_msg_pub.ADD;
3434          RAISE fnd_api.g_exc_unexpected_error;
3435       End IF;
3436 
3437       If l_child_node_index <> 0 Then
3438          if g_nodes(l_current_node_index).first_child_index = 0 then
3439            g_nodes(l_current_node_index).first_child_index := l_child_node_index;
3440            g_nodes(l_current_node_index).last_child_index := l_child_node_index;
3441          else
3442            l_last_child := g_nodes(l_current_node_index).last_child_index;
3443            g_nodes(l_last_child).next_sibling_Index := l_child_node_index;
3444            g_nodes(l_current_node_index).last_child_index := l_child_node_index;
3445          end if;
3446          g_nodes(l_child_node_index).parent_index := l_current_node_index;
3447       End If;
3448       l_child_node_index := l_current_node_index;
3449       If x_node_index = 0 Then
3450         x_node_index := l_current_node_index;
3451       End If;
3452       IF g_nodes(l_current_node_index).parent_index <> 0 THEN
3453          x_return_status := l_return_status;
3454          print_debug('-End of find_tree_node... x_node_index='||x_node_index||', current_node_index='||l_current_node_index||'.');
3455          RETURN TRUE;
3456       END IF;
3457    END IF;
3458 
3459    IF p_lot_number IS NOT NULL THEN
3460       -- search for the cost group node
3461       l_found := find_child_node(
3462                           x_return_status      => l_return_status
3463                         , p_node_level         => g_lot_level
3464                         , p_tree_id            => p_tree_id
3465                         , p_revision           => p_revision
3466                         , p_lot_number         => p_lot_number
3467                         , p_subinventory_code  => NULL
3468                         , p_is_reservable_sub  => NULL
3469                         , p_locator_id         => NULL
3470                         , p_lpn_id             => NULL
3471                         , p_cost_group_id      => NULL
3472                         , x_child_index        => l_current_node_index
3473                         );
3474 
3475       IF l_return_status = fnd_api.g_ret_sts_error THEN
3476          RAISE fnd_api.g_exc_error;
3477       End IF ;
3478 
3479       IF l_return_status = fnd_api.g_ret_sts_unexp_error THEN
3480          RAISE fnd_api.g_exc_unexpected_error;
3481       End IF;
3482 
3483       IF l_found = FALSE THEN
3484          fnd_message.set_name('INV','INV-Cannot find node');
3485          fnd_message.set_token('ROUTINE', 'Find_Tree_Node');
3486          fnd_msg_pub.ADD;
3487          RAISE fnd_api.g_exc_unexpected_error;
3488       End IF;
3489 
3490       If l_child_node_index <> 0 Then
3491          if g_nodes(l_current_node_index).first_child_index = 0 then
3492            g_nodes(l_current_node_index).first_child_index := l_child_node_index;
3493            g_nodes(l_current_node_index).last_child_index := l_child_node_index;
3494          else
3495            l_last_child := g_nodes(l_current_node_index).last_child_index;
3496            g_nodes(l_last_child).next_sibling_Index := l_child_node_index;
3497            g_nodes(l_current_node_index).last_child_index := l_child_node_index;
3498          end if;
3499          g_nodes(l_child_node_index).parent_index := l_current_node_index;
3500       End If;
3501       l_child_node_index := l_current_node_index;
3502       If x_node_index = 0 Then
3503         x_node_index := l_current_node_index;
3504       End If;
3505       IF g_nodes(l_current_node_index).parent_index <> 0 THEN
3506          x_return_status := l_return_status;
3507          print_debug('+++End of find_tree_node... x_node_index='||x_node_index||', current_node_index='||l_current_node_index||'.');
3508          RETURN TRUE;
3509       END IF;
3510    END IF;
3511 
3512    IF p_revision IS NOT NULL THEN
3513       -- search for the cost group node
3514       l_found := find_child_node(
3515                           x_return_status      => l_return_status
3516                         , p_node_level         => g_revision_level
3517                         , p_tree_id            => p_tree_id
3518                         , p_revision           => p_revision
3519                         , p_lot_number         => NULL
3520                         , p_subinventory_code  => NULL
3521                         , p_is_reservable_sub  => NULL
3522                         , p_locator_id         => NULL
3523                         , p_lpn_id             => NULL
3524                         , p_cost_group_id      => NULL
3525                         , x_child_index        => l_current_node_index
3526                         );
3527 
3528       IF l_return_status = fnd_api.g_ret_sts_error THEN
3529          RAISE fnd_api.g_exc_error;
3530       End IF ;
3531 
3532       IF l_return_status = fnd_api.g_ret_sts_unexp_error THEN
3533          RAISE fnd_api.g_exc_unexpected_error;
3534       End IF;
3535 
3536       IF l_found = FALSE THEN
3537          fnd_message.set_name('INV','INV-Cannot find node');
3538          fnd_message.set_token('ROUTINE', 'Find_Tree_Node');
3539          fnd_msg_pub.ADD;
3540          RAISE fnd_api.g_exc_unexpected_error;
3541       End IF;
3542 
3543       If l_child_node_index <> 0 Then
3544          if g_nodes(l_current_node_index).first_child_index = 0 then
3545            g_nodes(l_current_node_index).first_child_index := l_child_node_index;
3546            g_nodes(l_current_node_index).last_child_index := l_child_node_index;
3547          else
3548            l_last_child := g_nodes(l_current_node_index).last_child_index;
3549            g_nodes(l_last_child).next_sibling_Index := l_child_node_index;
3550            g_nodes(l_current_node_index).last_child_index := l_child_node_index;
3551          end if;
3552          g_nodes(l_child_node_index).parent_index := l_current_node_index;
3553       End If;
3554       l_child_node_index := l_current_node_index;
3555       If x_node_index = 0 Then
3556         x_node_index := l_current_node_index;
3557       End If;
3558       IF g_nodes(l_current_node_index).parent_index <> 0 THEN
3559          x_return_status := l_return_status;
3560          print_debug('++End of find_tree_node... x_node_index='||x_node_index||', current_node_index='||l_current_node_index||'.');
3561          RETURN TRUE;
3562       END IF;
3563    END IF;
3564 
3565    l_item_node := g_rootinfos(p_tree_id).item_node_index;
3566    IF l_current_node_index = 0 THEN
3567       x_node_index := l_item_node;
3568       x_return_status := l_return_status;
3569       print_debug('+End of find_tree_node... x_node_index='||x_node_index||', l_item_node='||l_item_node||', current_node_index='||l_current_node_index||'.');
3570       RETURN TRUE;
3571    END IF;
3572    IF g_nodes(l_item_node).first_child_index = 0 THEN
3573      g_nodes(l_item_node).first_child_index := l_current_node_index;
3574      g_nodes(l_item_node).last_child_index := l_current_node_index;
3575    ELSE
3576      l_last_child := g_nodes(l_item_node).last_child_index;
3577      g_nodes(l_last_child).next_sibling_index := l_current_node_index;
3578      g_nodes(l_item_node).last_child_index := l_current_node_index;
3579    END IF;
3580 
3581    g_nodes(l_current_node_index).parent_index := l_item_node;
3582 
3583    print_debug('End of  find_tree_node... x_node_index='||x_node_index||', l_item_node='
3584       ||l_item_node||', current_node_index='||l_current_node_index||'.');
3585    print_debug('... parent_node='||l_item_node||', next_sibling='||g_nodes(l_current_node_index).next_sibling_index
3586       ||', last_child='||g_nodes(l_current_node_index).last_child_index||'.');
3587 
3588    x_return_status := l_return_status;
3589    RETURN TRUE;
3590 
3591 EXCEPTION
3592 
3593    WHEN fnd_api.g_exc_error THEN
3594         x_return_status := fnd_api.g_ret_sts_error;
3595    RETURN FALSE;
3596    WHEN fnd_api.g_exc_unexpected_error THEN
3597         x_return_status := fnd_api.g_ret_sts_unexp_error ;
3598    RETURN FALSE;
3599 
3600     WHEN OTHERS THEN
3601         x_return_status := fnd_api.g_ret_sts_unexp_error ;
3602 
3603         IF ((NOT g_is_pickrelease) OR nvl(g_debug,2) = 1) THEN
3604           IF fnd_msg_pub.check_msg_level(fnd_msg_pub.g_msg_lvl_unexp_error)
3605             THEN
3606              fnd_msg_pub.add_exc_msg
3607                (  g_pkg_name
3608                 , 'Find_Tree_Node'
3609                 );
3610           END IF;
3611         END IF;
3612         RETURN FALSE;
3613 END find_tree_node;
3614 
3615 -- invConv changes begin :
3616 -- Procedure
3617 --   check_tree_node
3618 -- Description
3619 --   check the data in a tree node specified by the input
3620 --      and set the is_reservable
3621 PROCEDURE check_tree_node
3622   ( p_tree_id              IN INTEGER
3623   , p_node_index           IN INTEGER
3624   , p_organization_id      IN NUMBER
3625   , p_inventory_item_id    IN NUMBER
3626   ) IS
3627 
3628    l_found              BOOLEAN;
3629    l_root_id            NUMBER;
3630    l_return_status      VARCHAR2(1) := fnd_api.g_ret_sts_success;
3631    l_reservable         VARCHAR2(10);
3632    b_reservable         BOOLEAN;
3633    l_status_id          NUMBER;
3634    l_zone_control       NUMBER;
3635    l_location_control   NUMBER;
3636 
3637    l_node_level         INTEGER;
3638    l_node_index         INTEGER;
3639 
3640    z_node               VARCHAR2(200);
3641    zz_node              VARCHAR2(200);
3642    z_reservable         VARCHAR2(200);
3643    z_check              VARCHAR2(200);
3644    z_lot                VARCHAR2(200);
3645    z_sub                VARCHAR2(200);
3646    z_loc                varchar2(200);
3647    z_rev                VARCHAR2(200);
3648    z_qoh                VARCHAR2(200);
3649    z_rqoh               VARCHAR2(200);
3650    z_qr                 VARCHAR2(200);
3651    z_qs                 VARCHAR2(200);
3652    z_att                VARCHAR2(200);
3653    z_atr                VARCHAR2(200);
3654    z_sqr                VARCHAR2(200);
3655    z_sqs                VARCHAR2(200);
3656    z_satt               VARCHAR2(200);
3657    z_satr               VARCHAR2(200);
3658 
3659    ll_node_level        VARCHAR2(50);
3660 
3661 BEGIN
3662     l_root_id := g_demand_info(p_tree_id).root_id;
3663     print_debug(' root_id='||l_root_id||', tree_id='||p_tree_id);
3664     l_reservable  := 'Y';
3665     IF p_node_index <> 0 THEN
3666        l_node_level := g_nodes(p_node_index).node_level;
3667 
3668        IF ( g_debug = 1 ) THEN  -- Added for bug 6332112 to avoid the excessive rpads
3669            IF l_node_level = g_item_level THEN
3670              z_node := rpad('node level: item', 25);
3671              zz_node := 'Item';
3672 
3673            ELSIF l_node_level = g_sub_level THEN
3674              z_node := rpad('node level: subinventory', 25);
3675              zz_node := 'SubInventory';
3676 
3677            ELSIF l_node_level = g_locator_level THEN
3678              z_node := rpad('node level: locator', 25);
3679              zz_node := 'Locator';
3680 
3681            ELSIF l_node_level = g_lot_level THEN
3682              z_node := rpad('node level: lot', 25);
3683              zz_node := 'Lot';
3684 
3685            ELSIF l_node_level = g_revision_level THEN
3686              z_node := rpad('node level: revision', 25);
3687              zz_node := 'Revision';
3688 
3689            END IF;   -- l_node_level
3690        END IF ; -- if g_Debug
3691 
3692        -- Special Reservation check.
3693        check_is_reservable
3694               ( x_return_status       => l_return_status
3695               , p_node_level          => l_node_level
3696               , p_inventory_item_id   => p_inventory_item_id
3697               , p_organization_id     => p_organization_id
3698               , p_subinventory_code   => g_nodes(p_node_index).subinventory_code
3699               , p_locator_id          => g_nodes(p_node_index).locator_id
3700               , p_lot_number          => g_nodes(p_node_index).lot_number
3701               , p_root_id             => l_root_id
3702               , x_is_reservable       => b_reservable
3703               , p_lpn_id              => g_nodes(p_node_index).lpn_id); -- Onhand Material Status Support
3704 
3705       IF b_reservable THEN
3706          print_debug('in check_tree for node='||p_node_index||', node_level='||l_node_level||', is_rsv=TRUE, ATR='||g_nodes(p_node_index).atr);
3707          l_reservable := 'Y';
3708       ELSE
3709          print_debug('in check_tree for node='||p_node_index||', node_level='||l_node_level||', is_rsv=FALSE, ATR='||g_nodes(p_node_index).atr);
3710          l_reservable := 'N';
3711       END IF;
3712 
3713       -- Populate the relevant node
3714       g_nodes(p_node_index).is_reservable_sub := b_reservable;
3715 
3716       -- setting the secondary qties to NULL if non-DUOM control :
3717       IF (g_rootinfos(l_root_id).is_DUOM_control = FALSE)
3718       THEN
3719           print_debug(' the item is DUOM_control=FALSE');
3720           g_nodes(p_node_index).sqoh  := NULL;
3721           g_nodes(p_node_index).srqoh := NULL;
3722           g_nodes(p_node_index).sqr   := NULL;
3723           g_nodes(p_node_index).sqs   := NULL;
3724           g_nodes(p_node_index).satt  := NULL;
3725           g_nodes(p_node_index).satr  := NULL;
3726       ELSE
3727           print_debug(' the item is DUOM_control=TRUE');
3728       END IF;
3729 
3730       -- Inserting data into the temp table.
3731       IF g_debug = 1 THEN  -- Added for bug 6332112 to avoid the excessive rpads  if debug is not on
3732          print_debug(rpad('Node',25)||rpad('lot_number',10)||rpad('SubInv',10)||rpad('loct',10)||rpad('rev',10)||
3733             rpad('qoh',10)||rpad('rqoh',10)||rpad('qr',10)||rpad('qs',10)||rpad('att',10)||rpad('atr',10)||
3734             rpad('Rsvb',10)||rpad('CheckM',10)||rpad('TRX',10) );
3735 
3736          z_lot := rpad(NVL(g_nodes(p_node_index).lot_number, '...'), 10);
3737          z_sub := rpad(NVL(g_nodes(p_node_index).subinventory_code, '...'), 10);
3738          z_loc := rpad(NVL(to_char(g_nodes(p_node_index).locator_id), '...'), 10);
3739          z_rev := rpad(NVL(g_nodes(p_node_index).revision, '...'), 10);
3740          z_qoh := rpad(to_char(g_nodes(p_node_index).qoh), 10);
3741          z_rqoh := rpad(to_char(g_nodes(p_node_index).rqoh), 10);
3742          z_qr  := rpad(to_char(g_nodes(p_node_index).qr), 10);
3743          z_qs  := rpad(to_char(g_nodes(p_node_index).qs), 10);
3744          z_att := rpad(to_char(g_nodes(p_node_index).att), 10);
3745          z_atr := rpad(to_char(g_nodes(p_node_index).atr), 10);
3746          z_reservable := rpad( l_reservable, 10);
3747 
3748          IF g_nodes(p_node_index).check_mark THEN
3749             z_check := rpad('TRUE', 10);
3750           ELSE
3751             z_check := rpad('FALSE', 10);
3752          END IF;
3753       END IF ;
3754 
3755       print_debug(z_node||z_lot||z_sub||z_loc||z_rev||z_qoh||z_rqoh||z_qr||z_qs||z_att||z_atr||l_reservable||z_check);
3756 
3757       l_node_index := g_nodes(p_node_index).first_child_index;
3758 
3759       WHILE l_node_index <> 0
3760       LOOP
3761           check_tree_node
3762                       ( p_tree_id           => p_tree_id
3763                       , p_node_index        => l_node_index
3764                       , p_organization_id   => p_organization_id
3765                       , p_inventory_item_id => p_inventory_item_id);
3766 
3767           l_node_index := g_nodes(l_node_index).next_sibling_index;
3768       END LOOP;
3769    END IF;
3770 EXCEPTION
3771    WHEN OTHERS THEN
3772       print_debug('check_tree_node, OTHERS='||SQLERRM, 9);
3773 END check_tree_node;
3774 
3775 PROCEDURE check_tree
3776 ( p_tree_id   IN INTEGER
3777 ) IS
3778 
3779 BEGIN
3780     IF g_rootinfos(g_demand_info(p_tree_id).root_id).organization_id IS NOT NULL
3781     THEN
3782        print_debug('In check_tree, calling check_tree_node. id='||p_tree_id||', node='
3783           ||g_rootinfos(g_demand_info(p_tree_id).root_id).item_node_index||', item='||g_rootinfos(g_demand_info(p_tree_id).root_id).inventory_item_id);
3784 
3785        check_tree_node( p_tree_id           => p_tree_id
3786                       , p_node_index        => g_rootinfos(g_demand_info(p_tree_id).root_id).item_node_index
3787                       , p_organization_id   => g_rootinfos(g_demand_info(p_tree_id).root_id).organization_id
3788                       , p_inventory_item_id => g_rootinfos(g_demand_info(p_tree_id).root_id).inventory_item_id);
3789     ELSE
3790        print_debug('Error: tree '||To_char(p_tree_id) || ' does not exist');
3791     END IF;
3792 EXCEPTION
3793    WHEN OTHERS THEN
3794       print_debug('check_tree ending with OTHERS.'|| SQLERRM, 9);
3795 END check_tree;
3796 -- invConv changes end
3797 
3798 
3799 -- Procedure
3800 --   add_quantities
3801 -- Description
3802 --   add quantities to the tree based on the input
3803 -- Input Parameters
3804 --   p_tree_id               tree id
3805 --   p_revision              item revision
3806 --   p_lot_number            lot number
3807 --   p_subinventory_code     subinventory code
3808 --   p_is_reservable_sub     whether the sub is a reservable.
3809 --                           this is needed to create the corresponding
3810 --                           sub node
3811 --                           if it has not been created
3812 --   p_locator_id            locator id
3813 --   p_primary_quantity      quantity to add in primary uom
3814 --   p_secondary_quantity    quantity to add in secondary uom                       -- invConv change
3815 --   p_quantity_type
3816 --   p_set_check_mark        whether to set do_check mark to the appropriate
3817 --                           nodes
3818 -- Output Parameters
3819 --   x_return_status         Standard Output Parameters
3820 
3821 -- Bug 2486318. The do check does not work. Trasactions get committed
3822 -- even if there is a node violation. Added p_check_mark_node_only to mark
3823 -- the nodes.
3824 
3825 PROCEDURE add_quantities
3826   (  x_return_status              OUT NOCOPY VARCHAR2
3827    , p_tree_id                    IN  INTEGER
3828    , p_revision                   IN  VARCHAR2
3829    , p_lot_number                 IN  VARCHAR2
3830    , p_subinventory_code          IN  VARCHAR2
3831    , p_is_reservable_sub          IN  BOOLEAN
3832    , p_locator_id                 IN  NUMBER
3833    , p_primary_quantity           IN  NUMBER
3834    , p_secondary_quantity         IN  NUMBER  DEFAULT NULL   -- invConv change
3835    , p_quantity_type              IN  INTEGER
3836    , p_set_check_mark             IN  BOOLEAN
3837    , p_cost_group_id              IN  NUMBER
3838    , p_lpn_id                     IN  NUMBER
3839    , p_check_mark_node_only       IN  VARCHAR2 DEFAULT fnd_api.g_false
3840      --Bug 4294336 --Additional Parameters
3841    , p_transaction_action_id      IN  NUMBER   DEFAULT NULL
3842    , p_transfer_subinventory_code IN  VARCHAR2 DEFAULT NULL
3843    , p_transfer_locator_id        IN  NUMBER   DEFAULT NULL
3844    ) IS
3845       l_return_status            VARCHAR2(1) := fnd_api.g_ret_sts_success;
3846       l_node_index               INTEGER;
3847       l_found                    BOOLEAN;
3848       l_is_reservable_sub        BOOLEAN;
3849       ll_is_reservable_sub       BOOLEAN;      -- invConv change
3850       l_loop_index               INTEGER;
3851       l_sub_index                NUMBER;
3852       l_tree_mode                NUMBER;
3853       l_old_factor               NUMBER;
3854       l_old_factor2              NUMBER;       -- invConv change
3855       l_new_factor               NUMBER;
3856       l_new_factor2              NUMBER;       -- invConv change
3857       l_update_quantity          NUMBER;
3858       l_update_quantity2         NUMBER;       -- invConv change
3859       l_root_id                  INTEGER;
3860       l_org_item_index           NUMBER;
3861       l_tree_index               NUMBER;
3862       l_hash_string              VARCHAR2(1000);
3863       l_hash_base                NUMBER;
3864       l_hash_size                NUMBER;
3865       l_lpn_id                   NUMBER;
3866       l_is_reservable_xfer_sub   BOOLEAN := FALSE;
3867       l_debug_line               VARCHAR2(300);
3868       l_api_name                 VARCHAR2(30) := 'ADD_QUANTITIES';
3869 BEGIN
3870    IF g_debug = 1 THEN
3871       print_debug('    '||l_api_name || ' Entered',9);
3872    END IF;
3873 
3874    print_debug('Entering add_quantities for g_qoh='||g_qoh||', qty_type='||p_quantity_type||', qty1='||p_primary_quantity||'.');
3875    print_debug(' ... lot='||substr(p_lot_number,1,10)||', subInv='||p_subinventory_code||', loct='||p_locator_id||'.');
3876    IF p_is_reservable_sub THEN
3877       print_debug('... with p_is_reservable=TRUE');
3878    ELSIF p_is_reservable_sub = FALSE THEN
3879       print_debug('... with p_is_reservable=FALSE');
3880    ELSE
3881       print_debug('... with p_is_reservable=other');
3882    END IF;
3883 
3884    -- validate quantity type
3885    IF p_quantity_type <> g_qoh
3886      AND p_quantity_type <> g_qr_same_demand
3887      AND p_quantity_type <> g_qr_other_demand
3888      AND p_quantity_type <> g_qs_txn THEN
3889       -- invalid p_quantity_type. the caller's fault
3890       print_debug('... error=INVALID_QUANTITY_TYPE');
3891       fnd_message.set_name('INV', 'INV-INVALID_QUANTITY_TYPE');
3892       fnd_msg_pub.ADD;
3893       RAISE fnd_api.g_exc_error;
3894    END IF;
3895 
3896    l_hash_base := 1;
3897    l_hash_size := power(2, 20);
3898 
3899    -- For unpacked quantities, cost group will be specified while
3900    -- LPN is NULL.  To handle this, we have a dummy LPN of lpn_Id
3901    -- -99999 to hold loose quantity. We only need to use this
3902    -- when the cost group is specified, but the LPN is Null.
3903    --
3904    --Removing cost group from the quantity tree, so this is no longer necessary
3905    /*
3906     *IF p_lpn_Id IS NULL AND p_cost_group_id IS NOT NULL THEN
3907     *   l_lpn_id := g_loose_lpn_id;
3908     *ELSE
3909     *   l_lpn_id := p_lpn_id;
3910     *END IF;
3911     */
3912 
3913    print_debug('in add_qty, calling find_tree_node... for rev='||p_revision||', lot='||p_lot_number
3914       ||', sub='||p_subinventory_code||', loct='||p_locator_id);
3915    l_found := find_tree_node(
3916                       x_return_status      => l_return_status
3917                     , p_tree_id            => p_tree_id
3918                     , p_revision           => p_revision
3919                     , p_lot_number         => p_lot_number
3920                     , p_subinventory_code  => p_subinventory_code
3921                     , p_is_reservable_sub  => p_is_reservable_sub
3922                     , p_locator_id         => p_locator_id
3923                     , x_node_index         => l_node_index
3924                     , p_cost_group_id      => p_cost_group_id
3925                     , p_lpn_id             => p_lpn_id
3926                     );
3927 
3928    IF l_return_status = fnd_api.g_ret_sts_error THEN
3929       RAISE fnd_api.g_exc_error;
3930    End IF ;
3931 
3932    IF  l_return_status = fnd_api.g_ret_sts_unexp_error THEN
3933       RAISE fnd_api.g_exc_unexpected_error;
3934    END IF;
3935 
3936    IF l_found = FALSE THEN
3937       fnd_message.set_name('INV','INV-Cannot find node');
3938          fnd_message.set_token('ROUTINE', 'Add_Quantities');
3939       fnd_msg_pub.ADD;
3940       RAISE fnd_api.g_exc_unexpected_error;
3941    End IF;
3942 
3943    -- get tree mode
3944    -- only use this value to see if mode is loose or not
3945    --  rsv and txn mode are processed the same in this procedure
3946    l_tree_mode := g_rootinfos(p_tree_id).tree_mode;
3947 
3948    IF g_debug = 1 THEN
3949       l_debug_line := '      '||'for node: rev='||p_revision||' lot='||RPAD(p_lot_number,10)||' sub='||RPAD(p_subinventory_code,10)
3950          ||' loc='||RPAD(p_locator_id,6)||' lpn='||RPAD(p_lpn_id,6)||'..with qty type='||p_quantity_type||' qty='||RPAD(p_primary_quantity,6);
3951       print_debug(l_debug_line||' action='||p_transaction_action_id||' xfrsub='||p_transfer_subinventory_code||' xfrloc='||p_transfer_locator_id,9);
3952    END IF;
3953 
3954    -- process qoh
3955    print_debug('in add_qty, node_index='||l_node_index||', qtyType='||p_quantity_type||', g_qoh='||g_qoh
3956       ||', node_level='||g_nodes(l_node_index).node_level||'...');
3957    IF p_quantity_type = g_qoh THEN
3958       IF g_nodes(l_node_index).node_level <> g_locator_level
3959         AND g_nodes(l_node_index).node_level <> g_cost_group_level
3960         AND g_nodes(l_node_index).node_level <> g_sub_level
3961         AND g_nodes(l_node_index).node_level <> g_lpn_level
3962         THEN
3963          print_debug('... error=INV-WRONG_LEVEL');
3964          fnd_message.set_name('INV', 'INV-WRONG_LEVEL');
3965          fnd_msg_pub.ADD;
3966          RAISE fnd_api.g_exc_error;
3967       End IF;
3968 
3969       -- need to find out whether the sub is reservable or not
3970       -- in order to compute rqoh
3971       -- we need to look at is_reservable_sub from the sub node
3972       -- since it is possible that p_is_reservable_sub is null
3973       -- and is_reservable_sub at the sub node is not null
3974       l_sub_index := get_ancestor_sub(l_node_index);
3975       print_debug('after get_ancestor_sub... node_index='||l_node_index||', l_sub_index='||l_sub_index||', level='||g_nodes(l_sub_index).node_level);
3976       l_is_reservable_sub := g_nodes(l_sub_index).is_reservable_sub;
3977 
3978       IF l_is_reservable_sub
3979       THEN
3980          print_debug('in add_qty, from ancestor(sub_index='||l_sub_index||'), reservable_sub=TRUE reset reservable to NULL');
3981       ELSE
3982          print_debug('in add_qty, from ancestor(sub_index='||l_sub_index||'), reservable_sub=FALSE reset reservable to NULL');
3983       END IF;
3984       -- invConv change begin : Will take the reservable flag passed as parameter
3985       l_is_reservable_sub := NULL;
3986 
3987 
3988       /** Replaced below code with two lines above
3989        *     IF (g_nodes(l_node_index).node_level = g_locator_level) THEN
3990        *     IF (g_nodes(l_node_index).node_level = g_locator_level) THEN
3991        *        l_is_reservable_sub :=
3992        *          g_nodes(g_nodes(l_node_index).parent_index).is_reservable_sub;
3993        *      ELSIF (g_nodes(l_node_index).node_level = g_cost_group_level) THEN
3994        *        l_is_reservable_sub :=
3995        *          g_nodes(g_nodes(g_nodes(l_node_index).parent_index).parent_index).is_reservable_sub;
3996        *      ELSIF (g_nodes(l_node_index).node_level = g_sub_level) THEN
3997        *        l_is_reservable_sub :=
3998        *          g_nodes(l_node_index).is_reservable_sub;
3999        *      ELSE
4000        *        l_is_reservable_sub := NULL;
4001        *     END IF;
4002       */
4003 
4004       IF l_is_reservable_sub IS NULL THEN
4005          print_debug('in add_qty, l_is_reservable_sub=NULL');
4006          -- invConv changes begin : DEC-2004 : modification in the computation, ONLY if MAT_STAT=YES
4007          --   Now, making a distinction in the MATERIAL_STATUS mode values
4008          --    for compututing the reservable flag :
4009          IF (INV_QUANTITY_TREE_PVT.g_is_mat_status_used = 2)
4010          THEN
4011             IF p_is_reservable_sub IS NOT NULL THEN
4012                print_debug('in add_qty, p_is_reservable_sub=NOT NULL');
4013                -- we did not know whether the sub is reservable
4014                -- when we created the node last time
4015                -- but we know now from p_is_reservable_sub
4016                l_is_reservable_sub := p_is_reservable_sub;
4017             ELSE
4018                print_debug('in add_qty, p_is_reservable_sub=NULL');
4019 
4020                -- has to find out reservable type of the sub
4021                -- from the tables
4022                -- invConv changes begin (replaced call)
4023                --check_is_reservable_sub
4024                --  (
4025                --     x_return_status     => l_return_status
4026                --   , p_organization_id   => g_rootinfos(p_tree_id).organization_id
4027                --   , p_subinventory_code => p_subinventory_code
4028                --   , x_is_reservable_sub => l_is_reservable_sub
4029                --   );
4030                print_debug('in add_qty, tree_id='||p_tree_id);
4031                print_debug('in add_qty, Calling check_is_reservable. item_id='||g_rootinfos(p_tree_id).inventory_item_id||', org='||g_rootinfos(p_tree_id).organization_id||', sub='||p_subinventory_code);
4032                check_is_reservable
4033                  ( x_return_status       => l_return_status
4034                  , p_inventory_item_id   => g_rootinfos(p_tree_id).inventory_item_id
4035                  , p_organization_id     => g_rootinfos(p_tree_id).organization_id
4036                  , p_subinventory_code   => p_subinventory_code
4037                  , p_locator_id          => p_locator_id
4038                  , p_lot_number          => p_lot_number
4039                  , p_root_id             => p_tree_id
4040                  , x_is_reservable       => l_is_reservable_sub
4041                  , p_lpn_id              => p_lpn_id); -- Onhand Material Status Support
4042                print_debug('in add_qty, after check_is_reservable. return_status='||l_return_status);
4043                -- invConv changes end
4044 
4045                IF l_return_status = fnd_api.g_ret_sts_error THEN
4046                   RAISE fnd_api.g_exc_error;
4047                End IF ;
4048 
4049                IF l_return_status = fnd_api.g_ret_sts_unexp_error THEN
4050                   RAISE fnd_api.g_exc_unexpected_error;
4051                End IF;
4052             END IF;  -- p_is_reservable_sub = NULL
4053 
4054           -- invConv changes begin : Added the ELSE cndition.
4055         ELSE
4056             print_debug('in add_qty, MATERIAL_STATUS=TRUE tree_id='||p_tree_id);
4057             print_debug('in add_qty, Calling check_is_reservable. item_id='||g_rootinfos(p_tree_id).inventory_item_id||', org='||g_rootinfos(p_tree_id).organization_id||', sub='||p_subinventory_code);
4058             check_is_reservable
4059               ( x_return_status       => l_return_status
4060               , p_inventory_item_id   => g_rootinfos(p_tree_id).inventory_item_id
4061               , p_organization_id     => g_rootinfos(p_tree_id).organization_id
4062               , p_subinventory_code   => p_subinventory_code
4063               , p_locator_id          => p_locator_id
4064               , p_lot_number          => p_lot_number
4065               , p_root_id             => p_tree_id
4066               , x_is_reservable       => l_is_reservable_sub
4067               , p_lpn_id              => p_lpn_id); -- Onhand Material Status Support
4068             print_debug('in add_qty, after check_is_reservable. return_status='||l_return_status);
4069             -- invConv changes end
4070 
4071             IF l_return_status = fnd_api.g_ret_sts_error THEN
4072                RAISE fnd_api.g_exc_error;
4073             End IF ;
4074 
4075             IF l_return_status = fnd_api.g_ret_sts_unexp_error THEN
4076                RAISE fnd_api.g_exc_unexpected_error;
4077             End IF;
4078          END IF;  -- (INV_QUANTITY_TREE_PVT.g_is_mat_status_used = 2)
4079          -- invConv changes end.
4080 
4081          g_nodes(l_sub_index).is_reservable_sub := l_is_reservable_sub;
4082 
4083          /** replaced below code with single line above
4084            * -- save reservable_type into the node
4085            * IF (g_nodes(l_node_index).node_level = g_locator_level) THEN
4086            *    g_nodes(g_nodes(l_node_index).parent_index).is_reservable_sub
4087            *      := l_is_reservable_sub;
4088            *  ELSIF (g_nodes(l_node_index).node_level = g_cost_group_level) THEN
4089            *    g_nodes(g_nodes(g_nodes(l_node_index).parent_index).parent_index).is_reservable_sub
4090            *      := l_is_reservable_sub;
4091            *  ELSIF (g_nodes(l_node_index).node_level = g_sub_level) THEN
4092            *    g_nodes(l_node_index).is_reservable_sub := l_is_reservable_sub;
4093            * END IF;
4094            */
4095       END IF;
4096 
4097       l_loop_index := l_node_index;
4098       LOOP
4099          IF g_debug = 1 THEN
4100             l_debug_line := '      '||'Old: Node: '||g_nodes(l_loop_index).node_level||' :'||lpad(l_loop_index,10)||':'||lpad(g_nodes(l_loop_index).qoh,8)||':'||lpad(g_nodes(l_loop_index).rqoh,8);
4101             print_debug(l_debug_line||':'||lpad(g_nodes(l_loop_index).qr,8)||':'||lpad(g_nodes(l_loop_index).qs,8)||':'||lpad(g_nodes(l_loop_index).att,8)||':'||lpad(g_nodes(l_loop_index).atr,8),12);
4102          END IF;
4103 
4104          print_debug('loop1, node_level='||g_nodes(l_loop_index).node_level);
4105          print_debug('loop1, node_index='||l_loop_index||' qoh='||g_nodes(l_loop_index).qoh||' rqoh='||g_nodes(l_loop_index).rqoh
4106            ||' qr='||g_nodes(l_loop_index).qr||' qs='||g_nodes(l_loop_index).qs);
4107          print_debug(' ... att='||g_nodes(l_loop_index).att||' atr='||g_nodes(l_loop_index).atr);
4108          print_debug('.. sqoh='||g_nodes(l_loop_index).sqoh||' srqoh='||g_nodes(l_loop_index).srqoh||' sqr='||g_nodes(l_loop_index).sqr
4109            ||' sqs='||g_nodes(l_loop_index).sqs);
4110          print_debug(' .... satt='||g_nodes(l_loop_index).satt||' satr='||g_nodes(l_loop_index).satr);
4111 
4112          -- update qoh
4113          g_nodes(l_loop_index).qoh := g_nodes(l_loop_index).qoh + p_primary_quantity;
4114          -- invConv Changes begin
4115          g_nodes(l_loop_index).sqoh := NVL(g_nodes(l_loop_index).sqoh, 0) + p_secondary_quantity;    -- invConv change
4116          -- invConv Changes end
4117 
4118          -- Bug 7211383, we should use the condition only on l_is_reservable_sub.
4119          --    Material status is already taken care while setting value of l_is_reservable_sub.
4120          --    From update_quantities_for_form we always pass p_is_reservable sub as NULL.
4121          --    So with existing condition, when material status is used,
4122          --    code always used to compute incorrect rqoh, atr and thus att.
4123 
4124          -- invConv changes begin : DEC-2004 : modification in the computation, ONLY if MAT_STAT=YES
4125          --IF (l_is_reservable_sub AND INV_QUANTITY_TREE_PVT.g_is_mat_status_used = 2)
4126          --   OR ( l_is_reservable_sub AND p_is_reservable_sub AND INV_QUANTITY_TREE_PVT.g_is_mat_status_used = 1)
4127          IF l_is_reservable_sub = TRUE
4128          THEN
4129             print_debug('in add_qty,0 reservable_flag=TRUE');
4130             -- update rqoh
4131             g_nodes(l_loop_index).rqoh :=
4132               g_nodes(l_loop_index).rqoh + p_primary_quantity;
4133             -- invConv Changes begin
4134             g_nodes(l_loop_index).srqoh :=
4135                 NVL(g_nodes(l_loop_index).srqoh, 0) + p_secondary_quantity;    -- invConv change
4136             -- invConv Changes end
4137          ELSE
4138             print_debug('in add_qty,0 reservable_flag=FALSE');
4139          END IF;
4140 
4141          --update att/atr for containerized items;
4142          --track packed quantity on hand only in loose only mode;
4143          --see design document for detailed info on how att/atr is
4144          -- calculated in loose only mode;
4145          IF l_tree_mode = g_loose_only_mode AND p_lpn_id IS NOT NULL  THEN
4146 
4147             --l_old factor = QS+QR-PQOH
4148             l_old_factor := g_nodes(l_loop_index).qs + g_nodes(l_loop_index).qr - g_nodes(l_loop_index).pqoh;
4149             -- invConv Changes begin
4150             l_old_factor2 := g_nodes(l_loop_index).sqs + g_nodes(l_loop_index).sqr - g_nodes(l_loop_index).spqoh;    -- invConv change
4151             -- invConv Changes end
4152 
4153             --l_new factor = QS+QR-(PQOH+(change in PQOH))
4154             l_new_factor := l_old_factor - p_primary_quantity;
4155             -- invConv Changes begin
4156             l_new_factor2 := NVL(l_old_factor2, 0) - p_secondary_quantity;    -- invConv change
4157             -- invConv Changes end
4158 
4159 
4160             -- update_quantity is amount to update att/atr by
4161             -- Base calculation is update_quantity =
4162             --    max(old_factor, 0) - max(new_factor, 0)
4163             -- We have to deal with four possible cases:
4164             --  1. old_factor and new_factor >0
4165             --  2. old_factor >0 and new_factor <0
4166             --  3. old_factor <0 and new_factor >0
4167             --  4. old_factor and new_factor <0
4168             -- for these four cases, the att and atr are updated differently
4169             IF l_old_factor > 0 THEN
4170                IF l_new_factor > 0 THEN
4171                   --old_factor - new_factor
4172                   l_update_quantity:= p_primary_quantity;
4173                   -- invConv Changes begin
4174                   l_update_quantity2 := p_secondary_quantity;    -- invConv change
4175                   -- invConv Changes end
4176 
4177                ELSE  -- old factor > 0, new factor <= 0
4178                   --old_factor - 0  (max(new_factor, 0) = 0)
4179                   l_update_quantity := l_old_factor;
4180                   -- invConv Changes begin
4181                   l_update_quantity2 := l_old_factor2;
4182                   -- invConv Changes end
4183                END IF;
4184             ELSE -- l_old_factor <=0
4185                IF l_new_factor > 0 THEN
4186                   -- -new_factor  (max(old_factor, 0) = 0)
4187                   l_update_quantity:= 0.0 - l_new_factor;
4188                   -- invConv Changes begin
4189                   l_update_quantity2 := 0.0 - l_new_factor2;    -- invConv change
4190                   -- invConv Changes end
4191                ELSE  -- old factor < 0, new factor <= 0
4192                   -- 0-0
4193                   l_update_quantity:= 0;
4194                   -- invConv Changes begin
4195                   l_update_quantity2 := 0;    -- invConv change
4196                   -- invConv Changes end
4197                END IF;
4198             END IF;
4199 
4200             --update pqoh
4201             g_nodes(l_loop_index).pqoh := g_nodes(l_loop_index).pqoh + p_primary_quantity;
4202             -- invConv Changes begin
4203             g_nodes(l_loop_index).spqoh := NVL(g_nodes(l_loop_index).spqoh, 0) + p_secondary_quantity;    -- invConv change
4204             -- invConv Changes end
4205 
4206             --update att
4207             g_nodes(l_loop_index).att := g_nodes(l_loop_index).att + l_update_quantity;
4208             -- invConv Changes begin
4209             g_nodes(l_loop_index).satt := NVL(g_nodes(l_loop_index).satt, 0) + l_update_quantity2;    -- invConv change
4210             -- invConv Changes end
4211 
4212             -- Bug 7211383, we should use the condition only on l_is_reservable_sub.
4213             --    Material status is already taken care while setting value of l_is_reservable_sub.
4214             --    From update_quantities_for_form we always pass p_is_reservable sub as NULL.
4215             --    So with existing condition, when material status is used,
4216             --    code always used to compute incorrect rqoh, atr and thus att.
4217 
4218             -- invConv changes begin : DEC-2004 : modification in the computation, ONLY if MAT_STAT=YES
4219             --IF (l_is_reservable_sub AND INV_QUANTITY_TREE_PVT.g_is_mat_status_used = 2)
4220             --  OR ( l_is_reservable_sub AND p_is_reservable_sub AND INV_QUANTITY_TREE_PVT.g_is_mat_status_used = 1)
4221             IF l_is_reservable_sub = TRUE
4222             THEN
4223                print_debug('in add_qty,1 rsv=TRUE, newATR='||g_nodes(l_loop_index).atr||' + '||l_update_quantity);
4224                --update atr
4225                g_nodes(l_loop_index).atr := g_nodes(l_loop_index).atr + l_update_quantity;
4226                -- invConv Changes begin
4227                g_nodes(l_loop_index).satr := NVL(g_nodes(l_loop_index).satr, 0) + l_update_quantity2;    -- invConv change
4228                -- invConv Changes end
4229             ELSE
4230                print_debug('in add_qty,1 rsv=FALSE, newATR='||g_nodes(l_loop_index).atr||' + 0');
4231             END IF;
4232          ELSE -- not in loose items only mode, or quantity not containerized
4233             --update att
4234             g_nodes(l_loop_index).att := g_nodes(l_loop_index).att + p_primary_quantity;
4235             -- invConv Changes begin
4236             g_nodes(l_loop_index).satt := NVL(g_nodes(l_loop_index).satt, 0) + p_secondary_quantity;    -- invConv change
4237             -- invConv Changes end
4238 
4239             -- Bug 7211383, we should use the condition only on l_is_reservable_sub.
4240             --    Material status is already taken care while setting value of l_is_reservable_sub.
4241             --    From update_quantities_for_form we always pass p_is_reservable sub as NULL.
4242             --    So with existing condition, when material status is used,
4243             --    code always used to compute incorrect rqoh, atr and thus att.
4244 
4245             -- invConv changes begin : DEC-2004 : modification in the computation, ONLY if MAT_STAT=YES
4246             --IF (l_is_reservable_sub AND INV_QUANTITY_TREE_PVT.g_is_mat_status_used = 2)
4247             -- OR ( l_is_reservable_sub AND p_is_reservable_sub AND INV_QUANTITY_TREE_PVT.g_is_mat_status_used = 1)
4248             IF l_is_reservable_sub
4249             THEN
4250                print_debug('in add_qty,2 rsv=TRUE, newATR='||g_nodes(l_loop_index).atr||' + '||p_primary_quantity);
4251                --update atr
4252                g_nodes(l_loop_index).atr := g_nodes(l_loop_index).atr + p_primary_quantity;
4253                -- invConv Changes begin
4254                g_nodes(l_loop_index).satr := NVL(g_nodes(l_loop_index).satr, 0) + p_secondary_quantity;    -- invConv change
4255                -- invConv Changes end
4256             ELSE
4257                print_debug('in add_qty,2 rsv=FALSE, newATR='||g_nodes(l_loop_index).atr||' + 0');
4258             END IF;
4259          END IF;
4260          -- set check mark
4261 
4262          -- Bug 2486318. The do check does not work. Trasactions get committed
4263          -- even if there is a node violation. Added p_check_mark_node_only to mark the nodes.
4264 
4265          IF (p_set_check_mark = TRUE or
4266              p_check_mark_node_only = fnd_api.g_true AND
4267              p_primary_quantity < 0 )THEN
4268             g_nodes(l_loop_index).check_mark := TRUE;
4269          END IF;
4270 
4271          IF g_debug = 1 THEN
4272             l_debug_line := '      '||'New: Node: '||g_nodes(l_loop_index).node_level||' :'||lpad(l_loop_index,10)||':'||lpad(g_nodes(l_loop_index).qoh,8)||':'||lpad(g_nodes(l_loop_index).rqoh,8);
4273             print_debug(l_debug_line||':'||lpad(g_nodes(l_loop_index).qr,8)||':'||lpad(g_nodes(l_loop_index).qs,8)||':'||lpad(g_nodes(l_loop_index).att,8)||':'||lpad(g_nodes(l_loop_index).atr,8),12);
4274          END IF;
4275 
4276          IF (g_nodes(l_loop_index).node_level = g_item_level) THEN
4277             EXIT;
4278          END IF;
4279 
4280          l_loop_index := g_nodes(l_loop_index).parent_index;
4281       END LOOP;
4282 
4283 
4284     --process reservations
4285     ELSIF p_quantity_type = g_qr_same_demand
4286       OR p_quantity_type = g_qr_other_demand THEN
4287       print_debug('in add_qty, process reservation');
4288 
4289       l_loop_index := l_node_index;
4290       LOOP
4291          IF g_debug = 1 THEN
4292             l_debug_line := '      '||'Old: Node: '||g_nodes(l_loop_index).node_level||' :'||lpad(l_loop_index,10)||':'||lpad(g_nodes(l_loop_index).qoh,8)||':'||lpad(g_nodes(l_loop_index).rqoh,8);
4293             print_debug(l_debug_line||':'||lpad(g_nodes(l_loop_index).qr,8)||':'||lpad(g_nodes(l_loop_index).qs,8)||':'||lpad(g_nodes(l_loop_index).att,8)||':'||lpad(g_nodes(l_loop_index).atr,8),12);
4294          END IF;
4295 
4296          print_debug('loop2, node_index='||l_loop_index||' qoh='||g_nodes(l_loop_index).qoh||' rqoh='||g_nodes(l_loop_index).rqoh||' qr='||g_nodes(l_loop_index).qr||' qs='||g_nodes(l_loop_index).qs);
4297          print_debug(' ... att='||g_nodes(l_loop_index).att||' atr='||g_nodes(l_loop_index).atr);
4298          print_debug('.. sqoh='||g_nodes(l_loop_index).sqoh||' srqoh='||g_nodes(l_loop_index).srqoh||' sqr='||g_nodes(l_loop_index).sqr||' sqs='||g_nodes(l_loop_index).sqs);
4299          print_debug(' .... satt='||g_nodes(l_loop_index).satt||' satr='||g_nodes(l_loop_index).satr);
4300          print_debug(' .... pqoh='||g_nodes(l_loop_index).pqoh);
4301 
4302          --update att/atr for containerized items
4303          IF l_tree_mode = g_loose_only_mode THEN
4304             --old factor = QS+QR-PQOH
4305             l_old_factor := g_nodes(l_loop_index).qs + g_nodes(l_loop_index).qr - g_nodes(l_loop_index).pqoh;
4306             -- invConv Changes begin
4307             l_old_factor2 := g_nodes(l_loop_index).sqs + g_nodes(l_loop_index).sqr - g_nodes(l_loop_index).spqoh;    -- invConv change
4308             -- invConv Changes end
4309 
4310             --new factor = QS+QR+(change to QR)-PQOH
4311             l_new_factor := l_old_factor + p_primary_quantity;
4312             -- invConv Changes begin
4313             l_new_factor2 := NVL(l_old_factor2, 0) + p_secondary_quantity;    -- invConv change
4314             -- invConv Changes end
4315 
4316             if l_old_factor > 0 then
4317                IF l_new_factor > 0 THEN
4318                   l_update_quantity:= 0.0 - p_primary_quantity;
4319                   -- invConv Changes begin
4320                   l_update_quantity2:= 0.0 - p_secondary_quantity;    -- invConv change
4321                   -- invConv Changes end
4322 
4323                ELSE  -- old factor > 0, new factor <= 0
4324                   l_update_quantity := l_old_factor;
4325                   -- invConv Changes begin
4326                   l_update_quantity2 := l_old_factor2;    -- invConv change
4327                   -- invConv Changes end
4328                END IF;
4329             else -- l_old_factor <=0
4330                IF l_new_factor > 0 THEN
4331                   l_update_quantity:= 0.0 - l_new_factor;
4332                   -- invConv Changes begin
4333                   l_update_quantity2:= 0.0 - l_new_factor2;    -- invConv change
4334                   -- invConv Changes end
4335                ELSE  -- old factor < 0, new factor <= 0
4336                   l_update_quantity:= 0;
4337                   -- invConv Changes begin
4338                   l_update_quantity2:= 0;    -- invConv change
4339                   -- invConv Changes end
4340                END IF;
4341             end if;
4342 
4343             -- update qr
4344             g_nodes(l_loop_index).qr := g_nodes(l_loop_index).qr + p_primary_quantity;
4345             -- invConv Changes begin
4346             g_nodes(l_loop_index).sqr := NVL(g_nodes(l_loop_index).sqr, 0) + p_secondary_quantity;    -- invConv change
4347             -- invConv Changes end
4348 
4349             --update atr
4350             if g_nodes(l_loop_index).is_reservable_sub then
4351                print_debug('in add_qty,X rsv=TRUE, newATR='||g_nodes(l_loop_index).atr||' + '||l_update_quantity);
4352             else
4353                print_debug('in add_qty,X rsv=FALSE, newATR='||g_nodes(l_loop_index).atr||' + '||l_update_quantity);
4354             end if;
4355 
4356             g_nodes(l_loop_index).atr := g_nodes(l_loop_index).atr + l_update_quantity;
4357             -- invConv Changes begin
4358             g_nodes(l_loop_index).satr := NVL(g_nodes(l_loop_index).satr, 0) + l_update_quantity2;    -- invConv change
4359             -- invConv Changes end
4360 
4361             IF p_quantity_type = g_qr_other_demand
4362                -- we should also update att if the reservation qty is negative
4363                -- bitang, 1/20/2000
4364                OR p_primary_quantity < 0 THEN
4365                -- update att
4366                g_nodes(l_loop_index).att := g_nodes(l_loop_index).att + l_update_quantity;
4367                -- invConv Changes begin
4368                g_nodes(l_loop_index).satt := NVL(g_nodes(l_loop_index).satt, 0) + l_update_quantity2;    -- invConv change
4369                -- invConv Changes end
4370             END IF;
4371          ELSE -- not in loose items only mode
4372             -- update qr
4373             g_nodes(l_loop_index).qr := g_nodes(l_loop_index).qr + p_primary_quantity;
4374             -- invConv Changes begin
4375             g_nodes(l_loop_index).sqr := NVL(g_nodes(l_loop_index).sqr, 0) + p_secondary_quantity;    -- invConv change
4376             -- invConv Changes end
4377 
4378             --update atr
4379             if g_nodes(l_loop_index).is_reservable_sub then
4380                print_debug('in add_qty,Y rsv=TRUE, newATR='||g_nodes(l_loop_index).atr||' + '||p_primary_quantity);
4381             else
4382                print_debug('in add_qty,Y rsv=FALSE, newATR='||g_nodes(l_loop_index).atr||' + '||p_primary_quantity);
4383             end if;
4384             g_nodes(l_loop_index).atr := g_nodes(l_loop_index).atr - p_primary_quantity;
4385             -- invConv Changes begin
4386             g_nodes(l_loop_index).satr := NVL(g_nodes(l_loop_index).satr, 0) - p_secondary_quantity;    -- invConv change
4387             -- invConv Changes end
4388 
4389             IF p_quantity_type = g_qr_other_demand
4390             -- we should also update att if the reservation qty is negative
4391             -- bitang, 1/20/2000
4392                OR p_primary_quantity < 0 THEN
4393                -- update att
4394                g_nodes(l_loop_index).att := g_nodes(l_loop_index).att - p_primary_quantity;
4395                -- invConv Changes begin
4396                g_nodes(l_loop_index).satt := NVL(g_nodes(l_loop_index).satt, 0) - p_secondary_quantity;    -- invConv change
4397                -- invConv Changes end
4398             END IF;
4399          END IF;
4400 
4401          -- only set do check mark if we are reserving materials
4402 
4403          -- Bug 2486318. The do check does not work. Trasactions get committed
4404          -- even if there is a node violation. Added p_check_mark_node_only to mark the nodes.
4405 
4406          IF (p_set_check_mark = TRUE or
4407              p_check_mark_node_only = fnd_api.g_true AND p_primary_quantity >0) THEN
4408             g_nodes(l_loop_index).check_mark := TRUE;
4409          END IF;
4410 
4411          IF g_debug = 1 THEN
4412             l_debug_line := '      '||'New: Node: '||g_nodes(l_loop_index).node_level||' :'||lpad(l_loop_index,10)||':'||lpad(g_nodes(l_loop_index).qoh,8)||':'||lpad(g_nodes(l_loop_index).rqoh,8);
4413             print_debug(l_debug_line||':'||lpad(g_nodes(l_loop_index).qr,8)||':'||lpad(g_nodes(l_loop_index).qs,8)||':'||lpad(g_nodes(l_loop_index).att,8)||':'||lpad(g_nodes(l_loop_index).atr,8),12);
4414          END IF;
4415 
4416          EXIT WHEN g_nodes(l_loop_index).node_level = g_item_level;
4417 
4418          l_loop_index := g_nodes(l_loop_index).parent_index;
4419       END LOOP;
4420 
4421 
4422    --process suggestions
4423    ELSIF p_quantity_type = g_qs_txn THEN
4424       IF g_nodes(l_node_index).node_level <> g_locator_level
4425         AND g_nodes(l_node_index).node_level <> g_cost_group_level
4426         AND g_nodes(l_node_index).node_level <> g_sub_level
4427         AND g_nodes(l_node_index).node_level <> g_lpn_level
4428         THEN
4429          fnd_message.set_name('INV', 'INV-WRONG_LEVEL');
4430          fnd_msg_pub.ADD;
4431          RAISE fnd_api.g_exc_error;
4432       End IF;
4433 
4434       -- need to find out whether the sub is reservable or not
4435       -- in order to compute atr
4436       -- we need to look at is_reservable_sub from the sub node
4437       -- since it is possible that p_is_reservable_sub is null
4438       -- and is_reservable_sub at the sub node is not null
4439 
4440       print_debug('in add_qty, process suggestion');
4441       l_sub_index := get_ancestor_sub(l_node_index);
4442       print_debug('..after get_ancestor_sub... node_index='||l_node_index||', l_sub_index='||l_sub_index||', level='||g_nodes(l_sub_index).node_level);
4443       l_is_reservable_sub := g_nodes(l_sub_index).is_reservable_sub;
4444 
4445       /*
4446        *     IF (g_nodes(l_node_index).node_level = g_locator_level) THEN
4447        *        l_is_reservable_sub :=
4448        *          g_nodes(g_nodes(l_node_index).parent_index).is_reservable_sub;
4449        *      ELSIF (g_nodes(l_node_index).node_level = g_cost_group_level) THEN
4450        *        l_is_reservable_sub :=
4451        *          g_nodes(g_nodes(g_nodes(l_node_index).parent_index).parent_index).is_reservable_sub;
4452        *      ELSIF (g_nodes(l_node_index).node_level = g_sub_level) THEN
4453        *        l_is_reservable_sub :=
4454        *          g_nodes(l_node_index).is_reservable_sub;
4455        *      ELSE
4456        *        l_is_reservable_sub := NULL;
4457        *     END IF;
4458       */
4459 
4460       IF l_is_reservable_sub IS NULL THEN
4461          IF p_is_reservable_sub IS NOT NULL THEN
4462             -- we did not know whether the sub is reservable
4463             -- when we created the node last time
4464             -- but we know now from p_is_reservable_sub
4465             l_is_reservable_sub := p_is_reservable_sub;
4466          ELSE
4467             -- has to find out reservable type of the sub
4468             -- from the tables
4469             -- invConv changes begin (replaced call)
4470             --check_is_reservable_sub
4471             --  (
4472             --     x_return_status     => l_return_status
4473             --   , p_organization_id   => g_rootinfos(p_tree_id).organization_id
4474             --   , p_subinventory_code => p_subinventory_code
4475             --   , x_is_reservable_sub => l_is_reservable_sub
4476             --   );
4477             check_is_reservable
4478               ( x_return_status       => l_return_status
4479               , p_inventory_item_id   => g_rootinfos(p_tree_id).inventory_item_id
4480               , p_organization_id     => g_rootinfos(p_tree_id).organization_id
4481               , p_subinventory_code   => p_subinventory_code
4482               , p_locator_id          => p_locator_id
4483               , p_lot_number          => p_lot_number
4484               , p_root_id             => p_tree_id
4485               , x_is_reservable       => l_is_reservable_sub
4486               , p_lpn_id              => p_lpn_id); -- Onhand Material Status Support
4487 
4488             -- invConv changes end
4489 
4490             IF l_return_status = fnd_api.g_ret_sts_error THEN
4491                RAISE fnd_api.g_exc_error;
4492             End IF ;
4493 
4494             IF l_return_status = fnd_api.g_ret_sts_unexp_error THEN
4495                RAISE fnd_api.g_exc_unexpected_error;
4496             End IF;
4497          END IF;
4498 
4499          g_nodes(l_sub_index).is_reservable_sub := l_is_reservable_sub;
4500          /*
4501           *        -- save reservable_type into the node
4502           *        IF (g_nodes(l_node_index).node_level = g_locator_level) THEN
4503           *           g_nodes(g_nodes(l_node_index).parent_index).is_reservable_sub
4504           *             := l_is_reservable_sub;
4505           *         ELSIF (g_nodes(l_node_index).node_level = g_cost_group_level) THEN
4506           *           g_nodes(g_nodes(g_nodes(l_node_index).parent_index).parent_index).is_reservable_sub
4507           *             := l_is_reservable_sub;
4508           *         ELSIF (g_nodes(l_node_index).node_level = g_sub_level) THEN
4509           *           g_nodes(l_node_index).is_reservable_sub := l_is_reservable_sub;
4510           *        END IF;
4511          */
4512 
4513       END IF;
4514 
4515       --Bug 4294336
4516       IF NVL(p_transaction_action_id,-1 ) = 2  THEN
4517         l_is_reservable_xfer_sub := FALSE;
4518         IF p_transfer_subinventory_code IS NOT NULL THEN
4519             check_is_reservable_sub
4520               (
4521                  x_return_status     => l_return_status
4522                , p_organization_id   => g_rootinfos(p_tree_id).organization_id
4523                , p_subinventory_code => p_transfer_subinventory_code
4524                , x_is_reservable_sub => l_is_reservable_xfer_sub
4525                );
4526 
4527             IF l_return_status = fnd_api.g_ret_sts_error THEN
4528                RAISE fnd_api.g_exc_error;
4529             End IF ;
4530 
4531             IF l_return_status = fnd_api.g_ret_sts_unexp_error THEN
4532                RAISE fnd_api.g_exc_unexpected_error;
4533             End IF;
4534          END IF;
4535       END IF;
4536       --Bug 4294336
4537 
4538       l_loop_index := l_node_index;
4539       LOOP
4540          if g_debug = 1 then
4541             l_debug_line := '      '||'Old: Node: '||g_nodes(l_loop_index).node_level||' :'||lpad(l_loop_index,10)||':'||lpad(g_nodes(l_loop_index).qoh,8)||':'||lpad(g_nodes(l_loop_index).rqoh,8);
4542             print_debug(l_debug_line||':'||lpad(g_nodes(l_loop_index).qr,8)||':'||lpad(g_nodes(l_loop_index).qs,8)||':'||lpad(g_nodes(l_loop_index).att,8)||':'||lpad(g_nodes(l_loop_index).atr,8),12);
4543          end if;
4544 
4545          print_debug('loop3, node_index='||l_loop_index||' qoh='||g_nodes(l_loop_index).qoh||' rqoh='||g_nodes(l_loop_index).rqoh||' qr='||g_nodes(l_loop_index).qr||' qs='||g_nodes(l_loop_index).qs);
4546          print_debug(' ... att='||g_nodes(l_loop_index).att||' atr='||g_nodes(l_loop_index).atr);
4547          print_debug('.. sqoh='||g_nodes(l_loop_index).sqoh||' srqoh='||g_nodes(l_loop_index).srqoh||' sqr='||g_nodes(l_loop_index).sqr||' sqs='||g_nodes(l_loop_index).sqs);
4548          print_debug(' .... satt='||g_nodes(l_loop_index).satt||' satr='||g_nodes(l_loop_index).satr);
4549 
4550          --update att/atr for loose only mode
4551          IF l_tree_mode = g_loose_only_mode THEN
4552             print_debug('... in add_qty,3... mode=loose_only');
4553             --old factor = QS+QR-PQOH
4554             l_old_factor := g_nodes(l_loop_index).qs + g_nodes(l_loop_index).qr - g_nodes(l_loop_index).pqoh;
4555             -- invConv Changes begin
4556             l_old_factor2 := g_nodes(l_loop_index).sqs + g_nodes(l_loop_index).sqr - g_nodes(l_loop_index).spqoh;    -- invConv change
4557             -- invConv Changes end
4558 
4559             --new factor = QS+ (change to QS) +QR-PQOH
4560             l_new_factor := l_old_factor + p_primary_quantity;
4561             l_new_factor2 := NVL(l_old_factor2, 0) + p_secondary_quantity;       -- invConv change
4562 
4563 
4564             if l_old_factor > 0 then
4565                IF l_new_factor > 0 THEN
4566                   l_update_quantity:= 0.0 - p_primary_quantity;
4567                   l_update_quantity2:= 0.0 - p_secondary_quantity;        -- invConv change
4568                ELSE  -- old factor > 0, new factor <= 0
4569                   l_update_quantity := l_old_factor;
4570                   l_update_quantity2 := l_old_factor2;                    -- invConv change
4571                END IF;
4572             else -- l_old_factor <=0
4573                IF l_new_factor > 0 THEN
4574                   l_update_quantity:= 0.0 - l_new_factor;
4575                   l_update_quantity2:= 0.0 - l_new_factor2;                -- invConv change
4576 
4577                ELSE  -- old factor < 0, new factor <= 0
4578                   l_update_quantity:= 0;
4579                   l_update_quantity2:= 0;                                 -- invConv change
4580                END IF;
4581             end if;
4582 
4583             -- Start of fix for the Bug 4294336
4584             IF NVL(p_transaction_action_id,-1 ) = 2  THEN
4585                IF  g_nodes(l_loop_index).node_level = g_locator_level THEN
4586                   IF  NVL(g_nodes(l_loop_index).locator_id,-99) <> NVL(p_transfer_locator_id,-999) THEN
4587                        -- update qs
4588                        print_debug('... in add_qty,3... updating qs with trx_qty...qs='||g_nodes(l_loop_index).qs||', trx_qty='||p_primary_quantity);
4589                        g_nodes(l_loop_index).qs := g_nodes(l_loop_index).qs + p_primary_quantity;
4590                        -- invConv Changes begin
4591                        g_nodes(l_loop_index).sqs := NVL(g_nodes(l_loop_index).sqs, 0) + p_secondary_quantity;    -- invConv change
4592                        -- invConv Changes end
4593 
4594                        --update att
4595                        g_nodes(l_loop_index).att := g_nodes(l_loop_index).att + l_update_quantity;
4596                        -- invConv Changes begin
4597                        g_nodes(l_loop_index).satt := NVL(g_nodes(l_loop_index).satt, 0) + l_update_quantity2;    -- invConv change
4598                        -- invConv Changes end
4599 
4600                        if l_is_reservable_sub then
4601                           print_debug('in add_qty,3 rsv=TRUE, newATR='||g_nodes(l_loop_index).atr||' + '||l_update_quantity);
4602                           --update atr
4603                           g_nodes(l_loop_index).atr := g_nodes(l_loop_index).atr + l_update_quantity;
4604                           -- invConv Changes begin
4605                           g_nodes(l_loop_index).satr := NVL(g_nodes(l_loop_index).satr, 0) + l_update_quantity2;    -- invConv change
4606                           -- invConv Changes end
4607                        else
4608                           print_debug('in add_qty,3 rsv=FALSE, newATR='||g_nodes(l_loop_index).atr||' + 0');
4609                        end if;
4610 
4611                   END IF;
4612                ELSIF g_nodes(l_loop_index).node_level = g_sub_level  THEN
4613                   IF g_nodes(l_loop_index).subinventory_code <> p_transfer_subinventory_code THEN
4614                        -- update qs
4615                        print_debug('... in add_qty,3... updating qs with trx_qty...qs='||g_nodes(l_loop_index).qs||', trx_qty='||p_primary_quantity);
4616                        g_nodes(l_loop_index).qs := g_nodes(l_loop_index).qs + p_primary_quantity;
4617                        -- invConv Changes begin
4618                        g_nodes(l_loop_index).sqs := NVL(g_nodes(l_loop_index).sqs, 0) + p_secondary_quantity;    -- invConv change
4619                        -- invConv Changes end
4620 
4621                        --update att
4622                        g_nodes(l_loop_index).att := g_nodes(l_loop_index).att + l_update_quantity;
4623                        -- invConv Changes begin
4624                        g_nodes(l_loop_index).satt := NVL(g_nodes(l_loop_index).satt, 0) + l_update_quantity2;    -- invConv change
4625                        -- invConv Changes end
4626 
4627                        if l_is_reservable_sub then
4628                           print_debug('in add_qty,3 rsv=TRUE, newATR='||g_nodes(l_loop_index).atr||' + '||l_update_quantity);
4629                           --update atr
4630                           g_nodes(l_loop_index).atr := g_nodes(l_loop_index).atr + l_update_quantity;
4631                           -- invConv Changes begin
4632                           g_nodes(l_loop_index).satr := NVL(g_nodes(l_loop_index).satr, 0) + l_update_quantity2;    -- invConv change
4633                           -- invConv Changes end
4634                        else
4635                           print_debug('in add_qty,3 rsv=FALSE, newATR='||g_nodes(l_loop_index).atr||' + 0');
4636                        end if;
4637                   END IF;
4638                ELSIF g_nodes(l_loop_index).node_level = g_lot_level THEN
4639                   IF NVL(g_nodes(l_loop_index).lot_number,'@#$') =  NVL(p_lot_number,'$#@') THEN
4640                        -- update qs
4641                        print_debug('... in add_qty,3... updating qs with trx_qty...qs='||g_nodes(l_loop_index).qs||', trx_qty='||p_primary_quantity);
4642                        g_nodes(l_loop_index).qs := g_nodes(l_loop_index).qs + p_primary_quantity;
4643                        -- invConv Changes begin
4644                        g_nodes(l_loop_index).sqs := NVL(g_nodes(l_loop_index).sqs, 0) + p_secondary_quantity;    -- invConv change
4645                        -- invConv Changes end
4646 
4647                        --update att
4648                        g_nodes(l_loop_index).att := g_nodes(l_loop_index).att + l_update_quantity;
4649                        -- invConv Changes begin
4650                        g_nodes(l_loop_index).satt := NVL(g_nodes(l_loop_index).satt, 0) + l_update_quantity2;    -- invConv change
4651                        -- invConv Changes end
4652 
4653                        if l_is_reservable_sub then
4654                           print_debug('in add_qty,3 rsv=TRUE, newATR='||g_nodes(l_loop_index).atr||' + '||l_update_quantity);
4655                           --update atr
4656                           g_nodes(l_loop_index).atr := g_nodes(l_loop_index).atr + l_update_quantity;
4657                           -- invConv Changes begin
4658                           g_nodes(l_loop_index).satr := NVL(g_nodes(l_loop_index).satr, 0) + l_update_quantity2;    -- invConv change
4659                           -- invConv Changes end
4660                        else
4661                           print_debug('in add_qty,3 rsv=FALSE, newATR='||g_nodes(l_loop_index).atr||' + 0');
4662                        end if;
4663                   END IF;
4664                ELSIF  g_nodes(l_loop_index).node_level = g_revision_level THEN
4665                   IF NVL(g_nodes(l_loop_index).revision,'@#$') =  NVL(p_revision,'$#@') THEN
4666                        -- update qs
4667                        print_debug('... in add_qty,3... updating qs with trx_qty...qs='||g_nodes(l_loop_index).qs||', trx_qty='||p_primary_quantity);
4668                        g_nodes(l_loop_index).qs := g_nodes(l_loop_index).qs + p_primary_quantity;
4669                        -- invConv Changes begin
4670                        g_nodes(l_loop_index).sqs := NVL(g_nodes(l_loop_index).sqs, 0) + p_secondary_quantity;    -- invConv change
4671                        -- invConv Changes end
4672 
4673                        --update att
4674                        g_nodes(l_loop_index).att := g_nodes(l_loop_index).att + l_update_quantity;
4675                        -- invConv Changes begin
4676                        g_nodes(l_loop_index).satt := NVL(g_nodes(l_loop_index).satt, 0) + l_update_quantity2;    -- invConv change
4677                        -- invConv Changes end
4678 
4679                        if l_is_reservable_sub then
4680                           print_debug('in add_qty,3 rsv=TRUE, newATR='||g_nodes(l_loop_index).atr||' + '||l_update_quantity);
4681                           --update atr
4682                           g_nodes(l_loop_index).atr := g_nodes(l_loop_index).atr + l_update_quantity;
4683                           -- invConv Changes begin
4684                           g_nodes(l_loop_index).satr := NVL(g_nodes(l_loop_index).satr, 0) + l_update_quantity2;    -- invConv change
4685                           -- invConv Changes end
4686                        else
4687                           print_debug('in add_qty,3 rsv=FALSE, newATR='||g_nodes(l_loop_index).atr||' + 0');
4688                        end if;
4689                   END IF;
4690                ELSIF g_nodes(l_loop_index).node_level = g_item_level THEN
4691                   NULL;
4692                ELSE
4693                   -- update qs
4694                   print_debug('... in add_qty,3... updating qs with trx_qty...qs='||g_nodes(l_loop_index).qs||', trx_qty='||p_primary_quantity);
4695                   g_nodes(l_loop_index).qs := g_nodes(l_loop_index).qs + p_primary_quantity;
4696                   -- invConv Changes begin
4697                   g_nodes(l_loop_index).sqs := NVL(g_nodes(l_loop_index).sqs, 0) + p_secondary_quantity;    -- invConv change
4698                   -- invConv Changes end
4699 
4700                   --update att
4701                   g_nodes(l_loop_index).att := g_nodes(l_loop_index).att + l_update_quantity;
4702                   -- invConv Changes begin
4703                   g_nodes(l_loop_index).satt := NVL(g_nodes(l_loop_index).satt, 0) + l_update_quantity2;    -- invConv change
4704                   -- invConv Changes end
4705 
4706                   if l_is_reservable_sub then
4707                      print_debug('in add_qty,3 rsv=TRUE, newATR='||g_nodes(l_loop_index).atr||' + '||l_update_quantity);
4708                      --update atr
4709                      g_nodes(l_loop_index).atr := g_nodes(l_loop_index).atr + l_update_quantity;
4710                      -- invConv Changes begin
4711                      g_nodes(l_loop_index).satr := NVL(g_nodes(l_loop_index).satr, 0) + l_update_quantity2;    -- invConv change
4712                      -- invConv Changes end
4713                   else
4714                      print_debug('in add_qty,3 rsv=FALSE, newATR='||g_nodes(l_loop_index).atr||' + 0');
4715                   end if;
4716                END IF;  --Node Level Check
4717                /*
4718                 IF g_nodes(l_loop_index).node_level = g_item_level AND l_qty_chk_flag THEN
4719                   g_nodes(l_loop_index).qs_adj := g_nodes(l_loop_index).qs_adj + p_primary_quantity;
4720                   l_qty_chk_flag := FALSE;
4721                 END IF;
4722                */
4723                IF g_nodes(l_loop_index).node_level IN ( g_lot_level , g_revision_level , g_item_level)
4724                  AND p_transfer_subinventory_code IS NOT NULL
4725                  AND NOT l_is_reservable_xfer_sub THEN
4726                   g_nodes(l_loop_index).qs_adj1 := g_nodes(l_loop_index).qs_adj1 + p_primary_quantity;
4727                   g_nodes(l_loop_index).sqs_adj1 := g_nodes(l_loop_index).sqs_adj1 + p_secondary_quantity;
4728                    /* Added for bug 7323112 */
4729                   IF p_subinventory_code IS NOT NULL AND NOT l_is_reservable_sub THEN
4730                      g_nodes(l_loop_index).qs_adj1 := g_nodes(l_loop_index).qs_adj1 - p_primary_quantity;
4731                      g_nodes(l_loop_index).sqs_adj1 := g_nodes(l_loop_index).sqs_adj1 - p_secondary_quantity;
4732                   END IF;
4733                    /* End of changes for bug 7323112 */
4734                END IF;
4735 
4736             ELSE
4737                -- update qs
4738                print_debug('... in add_qty,3... updating qs with trx_qty...qs='||g_nodes(l_loop_index).qs||', trx_qty='||p_primary_quantity);
4739                g_nodes(l_loop_index).qs := g_nodes(l_loop_index).qs + p_primary_quantity;
4740                -- invConv Changes begin
4741                g_nodes(l_loop_index).sqs := NVL(g_nodes(l_loop_index).sqs, 0) + p_secondary_quantity;    -- invConv change
4742                -- invConv Changes end
4743 
4744                --update att
4745                g_nodes(l_loop_index).att := g_nodes(l_loop_index).att + l_update_quantity;
4746                -- invConv Changes begin
4747                g_nodes(l_loop_index).satt := NVL(g_nodes(l_loop_index).satt, 0) + l_update_quantity2;    -- invConv change
4748                -- invConv Changes end
4749 
4750                if l_is_reservable_sub then
4751                  print_debug('in add_qty,3 rsv=TRUE, newATR='||g_nodes(l_loop_index).atr||' + '||l_update_quantity);
4752                  --update atr
4753                  g_nodes(l_loop_index).atr := g_nodes(l_loop_index).atr + l_update_quantity;
4754                  -- invConv Changes begin
4755                  g_nodes(l_loop_index).satr := NVL(g_nodes(l_loop_index).satr, 0) + l_update_quantity2;    -- invConv change
4756                  -- invConv Changes end
4757                else
4758                   print_debug('in add_qty,3 rsv=FALSE, newATR='||g_nodes(l_loop_index).atr||' + 0');
4759                end if;
4760 
4761             END IF;
4762 
4763             /*
4764             -- update qs
4765             print_debug('... in add_qty,3... updating qs with trx_qty...qs='||g_nodes(l_loop_index).qs||', trx_qty='||p_primary_quantity);
4766             g_nodes(l_loop_index).qs := g_nodes(l_loop_index).qs + p_primary_quantity;
4767             -- invConv Changes begin
4768             g_nodes(l_loop_index).sqs := NVL(g_nodes(l_loop_index).sqs, 0) + p_secondary_quantity;    -- invConv change
4769             -- invConv Changes end
4770 
4771             --update att
4772             g_nodes(l_loop_index).att := g_nodes(l_loop_index).att + l_update_quantity;
4773             -- invConv Changes begin
4774             g_nodes(l_loop_index).satt := NVL(g_nodes(l_loop_index).satt, 0) + l_update_quantity2;    -- invConv change
4775             -- invConv Changes end
4776 
4777             if l_is_reservable_sub then
4778                print_debug('in add_qty,3 rsv=TRUE, newATR='||g_nodes(l_loop_index).atr||' + '||l_update_quantity);
4779                --update atr
4780                g_nodes(l_loop_index).atr := g_nodes(l_loop_index).atr + l_update_quantity;
4781                -- invConv Changes begin
4782                g_nodes(l_loop_index).satr := NVL(g_nodes(l_loop_index).satr, 0) + l_update_quantity2;    -- invConv change
4783                -- invConv Changes end
4784             else
4785                print_debug('in add_qty,3 rsv=FALSE, newATR='||g_nodes(l_loop_index).atr||' + 0');
4786             end if;
4787             */
4788             --End of fix for the Bug 4294336
4789 
4790          ELSE -- not in loose items only mode
4791             -- Start of fix for the Bug 4294336
4792             IF NVL(p_transaction_action_id,-1 ) = 2  THEN
4793                IF  g_nodes(l_loop_index).node_level = g_locator_level THEN
4794                   IF  NVL(g_nodes(l_loop_index).locator_id,-99) <> NVL(p_transfer_locator_id,-999) THEN
4795                      print_debug('... in add_qty,3... NOT loose mode, updating qs with trx_qty...qs='||g_nodes(l_loop_index).qs||', trx_qty='||p_primary_quantity);
4796                      -- update qs
4797                      g_nodes(l_loop_index).qs := g_nodes(l_loop_index).qs + p_primary_quantity;
4798                      -- invConv Changes begin
4799                      g_nodes(l_loop_index).sqs := NVL(g_nodes(l_loop_index).sqs, 0) + p_secondary_quantity;    -- invConv change
4800                      -- invConv Changes end
4801 
4802                      --update att
4803                      g_nodes(l_loop_index).att := g_nodes(l_loop_index).att - p_primary_quantity;
4804                      -- invConv Changes begin
4805                      g_nodes(l_loop_index).satt := NVL(g_nodes(l_loop_index).satt, 0) - p_secondary_quantity;    -- invConv change
4806                      -- invConv Changes end
4807 
4808                      if l_is_reservable_sub then
4809                         print_debug('in add_qty,4 rsv=TRUE, newATR='||g_nodes(l_loop_index).atr||' + '||p_primary_quantity);
4810                         --update atr
4811                         g_nodes(l_loop_index).atr := g_nodes(l_loop_index).atr - p_primary_quantity;
4812                         -- invConv Changes begin
4813                         g_nodes(l_loop_index).satr := NVL(g_nodes(l_loop_index).satr, 0) - p_secondary_quantity;    -- invConv change
4814                         -- invConv Changes end
4815                      else
4816                         print_debug('in add_qty,4 rsv=FALSE, newATR='||g_nodes(l_loop_index).atr||' + 0');
4817                      end if;
4818                   END IF;
4819                ELSIF g_nodes(l_loop_index).node_level = g_sub_level  THEN
4820                   IF g_nodes(l_loop_index).subinventory_code <> p_transfer_subinventory_code THEN
4821                      print_debug('... in add_qty,3... NOT loose mode, updating qs with trx_qty...qs='||g_nodes(l_loop_index).qs||', trx_qty='||p_primary_quantity);
4822                      -- update qs
4823                      g_nodes(l_loop_index).qs := g_nodes(l_loop_index).qs + p_primary_quantity;
4824                      -- invConv Changes begin
4825                      g_nodes(l_loop_index).sqs := NVL(g_nodes(l_loop_index).sqs, 0) + p_secondary_quantity;    -- invConv change
4826                      -- invConv Changes end
4827 
4828                      --update att
4829                      g_nodes(l_loop_index).att := g_nodes(l_loop_index).att - p_primary_quantity;
4830                      -- invConv Changes begin
4831                      g_nodes(l_loop_index).satt := NVL(g_nodes(l_loop_index).satt, 0) - p_secondary_quantity;    -- invConv change
4832                      -- invConv Changes end
4833 
4834                      if l_is_reservable_sub then
4835                         print_debug('in add_qty,4 rsv=TRUE, newATR='||g_nodes(l_loop_index).atr||' + '||p_primary_quantity);
4836                         --update atr
4837                         g_nodes(l_loop_index).atr := g_nodes(l_loop_index).atr - p_primary_quantity;
4838                         -- invConv Changes begin
4839                         g_nodes(l_loop_index).satr := NVL(g_nodes(l_loop_index).satr, 0) - p_secondary_quantity;    -- invConv change
4840                         -- invConv Changes end
4841                      else
4842                         print_debug('in add_qty,4 rsv=FALSE, newATR='||g_nodes(l_loop_index).atr||' + 0');
4843                      end if;
4844                      -- l_qty_chk_flag := TRUE;
4845                   END IF;
4846                ELSIF g_nodes(l_loop_index).node_level = g_lot_level THEN
4847                   IF NVL(g_nodes(l_loop_index).lot_number,'@#$') =  NVL(p_lot_number,'$#@') THEN
4848                      print_debug('... in add_qty,3... NOT loose mode, updating qs with trx_qty...qs='||g_nodes(l_loop_index).qs||', trx_qty='||p_primary_quantity);
4849                      -- update qs
4850                      g_nodes(l_loop_index).qs := g_nodes(l_loop_index).qs + p_primary_quantity;
4851                      -- invConv Changes begin
4852                      g_nodes(l_loop_index).sqs := NVL(g_nodes(l_loop_index).sqs, 0) + p_secondary_quantity;    -- invConv change
4853                      -- invConv Changes end
4854 
4855                      --update att
4856                      g_nodes(l_loop_index).att := g_nodes(l_loop_index).att - p_primary_quantity;
4857                      -- invConv Changes begin
4858                      g_nodes(l_loop_index).satt := NVL(g_nodes(l_loop_index).satt, 0) - p_secondary_quantity;    -- invConv change
4859                      -- invConv Changes end
4860 
4861                      if l_is_reservable_sub then
4862                         print_debug('in add_qty,4 rsv=TRUE, newATR='||g_nodes(l_loop_index).atr||' + '||p_primary_quantity);
4863                         --update atr
4864                         g_nodes(l_loop_index).atr := g_nodes(l_loop_index).atr - p_primary_quantity;
4865                         -- invConv Changes begin
4866                         g_nodes(l_loop_index).satr := NVL(g_nodes(l_loop_index).satr, 0) - p_secondary_quantity;    -- invConv change
4867                         -- invConv Changes end
4868                      else
4869                         print_debug('in add_qty,4 rsv=FALSE, newATR='||g_nodes(l_loop_index).atr||' + 0');
4870                      end if;
4871                      -- l_qty_chk_flag := TRUE;
4872                   END IF;
4873                ELSIF  g_nodes(l_loop_index).node_level = g_revision_level THEN
4874                   IF NVL(g_nodes(l_loop_index).revision,'@#$') = NVL(p_revision,'$#@') THEN
4875                      print_debug('... in add_qty,3... NOT loose mode, updating qs with trx_qty...qs='||g_nodes(l_loop_index).qs||', trx_qty='||p_primary_quantity);
4876                      -- update qs
4877                      g_nodes(l_loop_index).qs := g_nodes(l_loop_index).qs + p_primary_quantity;
4878                      -- invConv Changes begin
4879                      g_nodes(l_loop_index).sqs := NVL(g_nodes(l_loop_index).sqs, 0) + p_secondary_quantity;    -- invConv change
4880                      -- invConv Changes end
4881 
4882                      --update att
4883                      g_nodes(l_loop_index).att := g_nodes(l_loop_index).att - p_primary_quantity;
4884                      -- invConv Changes begin
4885                      g_nodes(l_loop_index).satt := NVL(g_nodes(l_loop_index).satt, 0) - p_secondary_quantity;    -- invConv change
4886                      -- invConv Changes end
4887 
4888                      if l_is_reservable_sub then
4889                         print_debug('in add_qty,4 rsv=TRUE, newATR='||g_nodes(l_loop_index).atr||' + '||p_primary_quantity);
4890                         --update atr
4891                         g_nodes(l_loop_index).atr := g_nodes(l_loop_index).atr - p_primary_quantity;
4892                         -- invConv Changes begin
4893                         g_nodes(l_loop_index).satr := NVL(g_nodes(l_loop_index).satr, 0) - p_secondary_quantity;    -- invConv change
4894                         -- invConv Changes end
4895                      else
4896                         print_debug('in add_qty,4 rsv=FALSE, newATR='||g_nodes(l_loop_index).atr||' + 0');
4897                      end if;
4898                      --   l_qty_chk_flag := TRUE;
4899                   END IF;
4900                ELSIF g_nodes(l_loop_index).node_level = g_item_level THEN
4901                   NULL;
4902                ELSE
4903                   print_debug('... in add_qty,3... NOT loose mode, updating qs with trx_qty...qs='||g_nodes(l_loop_index).qs||', trx_qty='||p_primary_quantity);
4904                   -- update qs
4905                   g_nodes(l_loop_index).qs := g_nodes(l_loop_index).qs + p_primary_quantity;
4906                   -- invConv Changes begin
4907                   g_nodes(l_loop_index).sqs := NVL(g_nodes(l_loop_index).sqs, 0) + p_secondary_quantity;    -- invConv change
4908                   -- invConv Changes end
4909 
4910                   --update att
4911                   g_nodes(l_loop_index).att := g_nodes(l_loop_index).att - p_primary_quantity;
4912                   -- invConv Changes begin
4913                   g_nodes(l_loop_index).satt := NVL(g_nodes(l_loop_index).satt, 0) - p_secondary_quantity;    -- invConv change
4914                   -- invConv Changes end
4915 
4916                   if l_is_reservable_sub then
4917                      print_debug('in add_qty,4 rsv=TRUE, newATR='||g_nodes(l_loop_index).atr||' + '||p_primary_quantity);
4918                      --update atr
4919                      g_nodes(l_loop_index).atr := g_nodes(l_loop_index).atr - p_primary_quantity;
4920                      -- invConv Changes begin
4921                      g_nodes(l_loop_index).satr := NVL(g_nodes(l_loop_index).satr, 0) - p_secondary_quantity;    -- invConv change
4922                      -- invConv Changes end
4923                   else
4924                      print_debug('in add_qty,4 rsv=FALSE, newATR='||g_nodes(l_loop_index).atr||' + 0');
4925                   end if;
4926                   -- l_qty_chk_flag := TRUE;
4927                END IF;  --Node Level Check
4928                /*
4929                IF g_nodes(l_loop_index).node_level = g_item_level AND l_qty_chk_flag THEN
4930                   g_nodes(l_loop_index).qs_adj := g_nodes(l_loop_index).qs_adj + p_primary_quantity;
4931                   l_qty_chk_flag := FALSE;
4932                END IF;
4933                 */
4934                IF g_nodes(l_loop_index).node_level IN ( g_lot_level , g_revision_level , g_item_level)
4935                   AND p_transfer_subinventory_code IS NOT NULL
4936                   AND NOT l_is_reservable_xfer_sub THEN
4937                   g_nodes(l_loop_index).qs_adj1 := g_nodes(l_loop_index).qs_adj1 + p_primary_quantity;
4938                   g_nodes(l_loop_index).sqs_adj1 := g_nodes(l_loop_index).sqs_adj1 + p_secondary_quantity;
4939                    /* Added for bug 7323112 */
4940                   IF p_subinventory_code IS NOT NULL AND NOT l_is_reservable_sub THEN
4941                      g_nodes(l_loop_index).qs_adj1 := g_nodes(l_loop_index).qs_adj1 - p_primary_quantity;
4942                      g_nodes(l_loop_index).sqs_adj1 := g_nodes(l_loop_index).sqs_adj1 - p_secondary_quantity;
4943                   END IF;
4944                   /* End of changes for bug 7323112 */
4945 
4946                END IF;
4947 
4948             ELSE
4949                print_debug('... in add_qty,3... NOT loose mode, updating qs with trx_qty...qs='||g_nodes(l_loop_index).qs||', trx_qty='||p_primary_quantity);
4950                -- update qs
4951                g_nodes(l_loop_index).qs := g_nodes(l_loop_index).qs + p_primary_quantity;
4952                -- invConv Changes begin
4953                g_nodes(l_loop_index).sqs := NVL(g_nodes(l_loop_index).sqs, 0) + p_secondary_quantity;    -- invConv change
4954                -- invConv Changes end
4955 
4956                --update att
4957                g_nodes(l_loop_index).att := g_nodes(l_loop_index).att - p_primary_quantity;
4958                -- invConv Changes begin
4959                g_nodes(l_loop_index).satt := NVL(g_nodes(l_loop_index).satt, 0) - p_secondary_quantity;    -- invConv change
4960                -- invConv Changes end
4961 
4962                if l_is_reservable_sub then
4963                   print_debug('in add_qty,4 rsv=TRUE, newATR='||g_nodes(l_loop_index).atr||' + '||p_primary_quantity);
4964                   --update atr
4965                   g_nodes(l_loop_index).atr := g_nodes(l_loop_index).atr - p_primary_quantity;
4966                   -- invConv Changes begin
4967                   g_nodes(l_loop_index).satr := NVL(g_nodes(l_loop_index).satr, 0) - p_secondary_quantity;    -- invConv change
4968                   -- invConv Changes end
4969                else
4970                   print_debug('in add_qty,4 rsv=FALSE, newATR='||g_nodes(l_loop_index).atr||' + 0');
4971                end if;
4972                -- l_qty_chk_flag := TRUE;
4973             END IF; --Action Id 2 check
4974 
4975             /*
4976             print_debug('... in add_qty,3... NOT loose mode, updating qs with trx_qty...qs='||g_nodes(l_loop_index).qs||', trx_qty='||p_primary_quantity);
4977             -- update qs
4978             g_nodes(l_loop_index).qs := g_nodes(l_loop_index).qs + p_primary_quantity;
4979             -- invConv Changes begin
4980             g_nodes(l_loop_index).sqs := NVL(g_nodes(l_loop_index).sqs, 0) + p_secondary_quantity;    -- invConv change
4981             -- invConv Changes end
4982 
4983             --update att
4984             g_nodes(l_loop_index).att := g_nodes(l_loop_index).att - p_primary_quantity;
4985             -- invConv Changes begin
4986             g_nodes(l_loop_index).satt := NVL(g_nodes(l_loop_index).satt, 0) - p_secondary_quantity;    -- invConv change
4987             -- invConv Changes end
4988 
4989             if l_is_reservable_sub then
4990                print_debug('in add_qty,4 rsv=TRUE, newATR='||g_nodes(l_loop_index).atr||' + '||p_primary_quantity);
4991                --update atr
4992                g_nodes(l_loop_index).atr := g_nodes(l_loop_index).atr - p_primary_quantity;
4993                -- invConv Changes begin
4994                g_nodes(l_loop_index).satr := NVL(g_nodes(l_loop_index).satr, 0) - p_secondary_quantity;    -- invConv change
4995                -- invConv Changes end
4996             else
4997                print_debug('in add_qty,4 rsv=FALSE, newATR='||g_nodes(l_loop_index).atr||' + 0');
4998             end if;
4999             */
5000             -- End of fix for the Bug 4294336
5001 
5002          END IF;
5003 
5004          -- set check mark
5005 
5006          -- Bug 2486318. The do check does not work. Trasactions get committed
5007          -- even if there is a node violation. Added p_check_mark_node_only to mark the nodes.
5008 
5009          IF (p_set_check_mark = TRUE or
5010            p_check_mark_node_only = fnd_api.g_true AND p_primary_quantity < 0 )THEN
5011                g_nodes(l_loop_index).check_mark := TRUE;
5012          END IF;
5013 
5014          IF g_debug = 1 THEN
5015             l_debug_line := '      '||'New: Node: '||g_nodes(l_loop_index).node_level||' :'||lpad(l_loop_index,10)||':'||lpad(g_nodes(l_loop_index).qoh,8)||':'||lpad(g_nodes(l_loop_index).rqoh,8);
5016             print_debug(l_debug_line||':'||lpad(g_nodes(l_loop_index).qr,8)||':'||lpad(g_nodes(l_loop_index).qs,8)||':'||lpad(g_nodes(l_loop_index).att,8)||':'||lpad(g_nodes(l_loop_index).atr,8),12);
5017          END IF;
5018 
5019          IF (g_nodes(l_loop_index).node_level = g_item_level) THEN
5020             EXIT;
5021          END IF;
5022 
5023          l_loop_index := g_nodes(l_loop_index).parent_index;
5024       END LOOP;
5025 
5026 
5027    END IF;
5028 
5029    IF p_set_check_mark = TRUE THEN
5030       -- we will mark other trees with the same org and item id
5031       -- as need refresh since the update may render
5032       -- those trees as outdated
5033       /* Performance - don't loop through all trees
5034       FOR l_rootinfo_index IN 1..g_all_roots_counter LOOP
5035          l_root_id := g_all_roots(l_rootinfo_index);
5036          IF p_tree_id <> l_root_id
5037             AND (g_rootinfos(l_root_id).organization_id = g_rootinfos(p_tree_id).organization_id
5038              AND g_rootinfos(l_root_id).inventory_item_id = g_rootinfos(p_tree_id).inventory_item_id)
5039          THEN
5040             g_rootinfos(l_root_id).need_refresh := TRUE;
5041          END IF;
5042       END LOOP;
5043       */
5044 
5045       l_hash_string := g_rootinfos(p_tree_id).organization_id
5046         || ':' || g_rootinfos(p_tree_id).inventory_item_id;
5047       l_org_item_index := dbms_utility.get_hash_value(
5048                         name       => l_hash_string
5049                        ,base       => l_hash_base
5050                        ,hash_size  => l_hash_size);
5051       If g_org_item_trees.exists(l_org_item_index) Then
5052          l_tree_index  := g_org_item_trees(l_org_item_index);
5053          LOOP
5054             EXIT WHEN l_tree_index = 0;
5055             l_root_id := g_all_roots(l_tree_index).root_id;
5056             if l_root_id <> p_tree_id then
5057                g_rootinfos(l_root_id).need_refresh := TRUE;
5058             end if;
5059             l_tree_index := g_all_roots(l_tree_index).next_root;
5060          END LOOP;
5061       End If;
5062    END IF;
5063 
5064    print_debug('Normal end of add_quantities...');
5065    x_return_status := l_return_status;
5066 
5067 EXCEPTION
5068    WHEN fnd_api.g_exc_error THEN
5069       print_debug('in add_quantities... EXP_ERROR sql='||SQLERRM,9);
5070       x_return_status := fnd_api.g_ret_sts_error;
5071 
5072    WHEN fnd_api.g_exc_unexpected_error THEN
5073       print_debug('in add_quantities... UNEXP_ERROR sql='||SQLERRM,9);
5074       x_return_status := fnd_api.g_ret_sts_unexp_error ;
5075 
5076    WHEN OTHERS THEN
5077       print_debug('in add_quantities... OTHERS ERROR sql='||SQLERRM,9);
5078       x_return_status := fnd_api.g_ret_sts_unexp_error ;
5079 
5080       IF fnd_msg_pub.check_msg_level(fnd_msg_pub.g_msg_lvl_unexp_error)
5081       THEN
5082          fnd_msg_pub.add_exc_msg
5083              (  g_pkg_name
5084               , 'Add_Quantities'
5085               ,9);
5086       END IF;
5087 END add_quantities;
5088 
5089 -- Procedure
5090 --   build_tree
5091 -- Description
5092 --   build the tree by querying the database tables and compute quantities
5093 PROCEDURE build_tree
5094   (  x_return_status         OUT NOCOPY VARCHAR2
5095      , p_tree_id             IN  INTEGER
5096     ) IS
5097    l_api_name                    VARCHAR2(30) := 'BUILD_TREE';
5098    l_return_status               VARCHAR2(1) := fnd_api.g_ret_sts_success;
5099    l_is_reservable_sub           BOOLEAN;
5100    l_cursor                      NUMBER;
5101    l_dummy                       INTEGER;
5102    l_index_start                 NUMBER := 0;
5103    l_num_recs_fetch              NUMBER := 100;
5104    l_cur_num_rows                NUMBER := 0;
5105    l_tot_num_rows                NUMBER := 0;
5106    l_index                       NUMBER := 0;
5107 
5108    l_revision_control            NUMBER;
5109    l_no_lpn_reservations         NUMBER;
5110    l_tree_mode                   NUMBER;
5111    l_demand_source_type_id       NUMBER;
5112    l_demand_source_header_id     NUMBER;
5113    l_demand_source_line_id       NUMBER;
5114    l_demand_source_name          VARCHAR2(30);
5115    l_demand_source_delivery      NUMBER;
5116    l_organization_id             NUMBER;
5117    l_inventory_item_id           NUMBER;
5118    l_subinventory_code           VARCHAR2(30);
5119    l_locator_id                  NUMBER;
5120    l_lot_number                  VARCHAR2(80);     -- invConv change
5121    l_primary_quantity            NUMBER;
5122    l_asset_subs_only             NUMBER;
5123    l_onhand_source               NUMBER;
5124    l_lot_expiration_control      NUMBER;
5125    l_lot_expiration_date         DATE;
5126    l_grade_code                  VARCHAR2(150);
5127 
5128    v_revision                    bulk_varchar_3_tbl_type;
5129    v_lot_number                  bulk_varchar_80_tbl_type;      -- invConv change
5130    v_subinventory_code           bulk_varchar_10_tbl_type;
5131    v_lot_expiration_date         bulk_date_tbl_type;
5132    v_reservable_type             bulk_num_tbl_type;
5133    v_primary_quantity            bulk_num_tbl_type;
5134    v_secondary_quantity          bulk_num_tbl_type;         -- invConv change
5135    v_quantity_type               bulk_num_tbl_type;
5136    v_locator_id                  bulk_num_tbl_type;
5137    v_inventory_item_id           bulk_num_tbl_type;
5138    v_organization_id             bulk_num_tbl_type;
5139    v_cost_group_id               bulk_num_tbl_type;
5140    v_lpn_id                      bulk_num_tbl_type;
5141 
5142    v_transaction_action_id       bulk_num_tbl_type;
5143    v_transfer_subinventory_code  bulk_varchar_10_tbl_type;
5144    v_transfer_locator_id         bulk_num_tbl_type;
5145 
5146    v_status_id                   bulk_num_tbl_type; -- Onhand Material Status Support
5147 
5148 -- Onhand Material Status Support: Modified the queries to check for availability_type
5149 -- and atpable_type from MOQD's status if the status is tracked at the onhand level.
5150 
5151      CURSOR c_plain IS
5152      SELECT
5153           x.organization_id               organization_id
5154         , x.inventory_item_id             inventory_item_id
5155         , x.revision                      revision
5156         , NULL                            lot_number
5157         , NULL                            lot_expiration_date
5158         , x.subinventory_code             subinventory_code
5159         , sub.reservable_type             reservable_type
5160         , x.locator_id                    locator_id
5161         , SUM(x.primary_quantity)         primary_quantity          -- invConv change (added SUM)
5162         , SUM(x.secondary_quantity)       secondary_quantity        -- invConv change (+added SUM)
5163         , x.quantity_type                 quantity_type
5164         , x.cost_group_id                 cost_group_id
5165         , x.lpn_id                        lpn_id
5166         , x.transaction_action_id         transaction_action_id
5167         , x.transfer_subinventory_code    transfer_subinventory_code
5168         , x.transfer_locator_id           transfer_locator_id
5169      FROM (
5170        SELECT
5171            x.organization_id                                organization_id
5172          , x.inventory_item_id                              inventory_item_id
5173          , decode(l_revision_control, 2, NULL, x.revision)  revision
5174          , NULL                                             lot_number
5175          , x.subinventory_code                              subinventory_code
5176          , x.locator_id                                     locator_id
5177          , SUM(x.primary_quantity)                          primary_quantity
5178          , SUM(x.secondary_quantity)                        secondary_quantity    -- invConv change
5179          , x.quantity_type                                  quantity_type
5180          , x.cost_group_id                                  cost_group_id
5181          , x.lpn_id                                         lpn_id
5182          , x.transaction_action_id                          transaction_action_id
5183          , x.transfer_subinventory_code                     transfer_subinventory_code
5184          , x.transfer_locator_id                            transfer_locator_id
5185         FROM (
5186           -- reservations
5187           SELECT
5188              mr.organization_id                                                        organization_id
5189            , mr.inventory_item_id                                                      inventory_item_id
5190            , mr.revision                                                               revision
5191            , mr.lot_number                                                             lot_number
5192            , mr.subinventory_code                                                      subinventory_code
5193            , mr.locator_id                                                             locator_id
5194            , mr.primary_reservation_quantity - Nvl(mr.detailed_quantity,0)             primary_quantity
5195            , mr.secondary_reservation_quantity - Nvl(mr.secondary_detailed_quantity,0) secondary_quantity
5196            , 3                                                                         quantity_type
5197            , to_number(NULL)                                                           cost_group_id
5198            , lpn_id                                                                    lpn_id
5199            , to_number(NULL)                                                           transaction_action_id
5200            , to_char(NULL)                                                             transfer_subinventory_code
5201            , to_number(NULL)                                                           transfer_locator_id
5202         FROM mtl_reservations mr
5203         WHERE
5204              Nvl(mr.supply_source_type_id, 13) = 13
5205          AND mr.primary_reservation_quantity > Nvl(mr.detailed_quantity,0)
5206          AND ((l_no_lpn_reservations <>1) OR (l_no_lpn_reservations = 1 AND mr.lpn_id IS NULL))
5207          AND (l_tree_mode <> 3 OR
5208                 (l_tree_mode = 3
5209                  AND NOT (    l_demand_source_type_id = mr.demand_source_type_id
5210                           AND l_demand_source_header_id = mr.demand_source_header_id
5211                           AND Nvl(l_demand_source_line_id, -9999) = Nvl(mr.demand_source_line_id,-9999)
5212                           AND Nvl(l_demand_source_name, '@@@###@@#') = Nvl(mr.demand_source_name,'@@@###@@#')
5213                           AND Nvl(l_demand_source_delivery,-9999) = Nvl(mr.demand_source_delivery,-9999)
5214                          )
5215                 )
5216              )
5217         UNION ALL
5218           -- onhand quantities
5219           SELECT
5220              moq.organization_id                   organization_id
5221            , moq.inventory_item_id                 inventory_item_id
5222            , moq.revision                          revision
5223            , moq.lot_number                        lot_number
5224            , moq.subinventory_code                 subinventory_code
5225            , moq.locator_id                        locator_id
5226            , moq.primary_transaction_quantity
5227            , moq.secondary_transaction_quantity                                  -- invConv change
5228            , 1                                     quantity_type
5229            , moq.cost_group_id                     cost_group_id
5230            , moq.lpn_id                            lpn_id
5231            , to_number(NULL)                       transaction_action_id
5232            , to_char(NULL)                         transfer_subinventory_code
5233            , to_number(NULL)                       transfer_locator_id
5234           FROM
5235              mtl_onhand_quantities_detail       moq
5236 
5237         UNION ALL
5238           -- pending transactions in mmtt
5239           SELECT
5240                mmtt.organization_id                                                                organization_id
5241              , mmtt.inventory_item_id                                                              inventory_item_id
5242              , mmtt.revision                                                                       revision
5243              , NULL                                                                                lot_number
5244              , mmtt.subinventory_code                                                              subinventory_code
5245              , mmtt.locator_id                                                                     locator_id
5246              --Bug 4185621
5247              --, Decode(mmtt.transaction_status, 2, 1,
5248              , Decode(Decode(mmtt.transaction_status, 2, decode(nvl(mmtt.wms_task_status,-1),4,-1,2), mmtt.transaction_status)
5249                       , 2, 1, Decode(mmtt.transaction_action_id,1,-1,2,-1,28,-1,3,-1,Sign(mmtt.primary_quantity)))
5250                * round(Abs(mmtt.primary_quantity),5)
5251              --Bug 4185621
5252              --, Decode(mmtt.transaction_status, 2, 1,
5253              , Decode(Decode(mmtt.transaction_status, 2, decode(nvl(mmtt.wms_task_status,-1),4,-1,2), mmtt.transaction_status)
5254                       , 2, 1, Decode(mmtt.transaction_action_id,1,-1,2,-1,28,-1,3,-1,Sign(mmtt.secondary_transaction_quantity)))
5255                * round(Abs(mmtt.secondary_transaction_quantity),5)                              -- invConv change
5256              --Bug 4185621
5257              --, Decode(mmtt.transaction_status, 2, 5, 1)  quantity_type
5258              , Decode(mmtt.transaction_status, 2, decode(nvl(mmtt.wms_task_status,-1),4,1,5), 1)   quantity_type
5259              , mmtt.cost_group_id                                                                  cost_group_id
5260              , NVL(mmtt.allocated_lpn_id,NVL(mmtt.content_lpn_id, mmtt.lpn_id))                    lpn_id
5261              , Decode(mmtt.transaction_status, 2 , mmtt.transaction_action_id, to_number(NULL))    transaction_action_id
5262              , Decode(mmtt.transaction_status, 2 , mmtt.transfer_subinventory, to_char(NULL))      transfer_subinventory_code
5263              , Decode(mmtt.transaction_status, 2 , mmtt.transfer_to_location, to_number(NULL))     transfer_locator_id
5264           FROM
5265                mtl_material_transactions_temp mmtt
5266           WHERE
5267                mmtt.posting_flag = 'Y'
5268            AND mmtt.subinventory_code IS NOT NULL
5269            AND (Nvl(mmtt.transaction_status,0) <> 2 OR
5270                 Nvl(mmtt.transaction_status,0) = 2 AND mmtt.transaction_action_id IN (1,2,28,3,21,29,32,34))
5271            -- dont look at scrap and costing txns
5272            -- Bug 3396558 fix. Ignore ownership xfr,planning xfr transactions
5273            AND mmtt.transaction_action_id NOT IN (5,6,24,30)
5274 
5275         UNION ALL
5276           -- receiving side of transfers
5277           -- added 5/23/00
5278           -- if quantity is in an lpn, then it is containerized
5279           -- Bug 7658493, If wms task is in loaded status, consider allocation like pending transaction.
5280           SELECT
5281                Decode(mmtt.transaction_action_id, 3, mmtt.transfer_organization, mmtt.organization_id)   organization_id
5282              , mmtt.inventory_item_id                                                                    inventory_item_id
5283              , mmtt.revision                                                                             revision
5284              , NULL                                                                                      lot_number
5285              , mmtt.transfer_subinventory                                                                subinventory_code
5286              , mmtt.transfer_to_location                                                                 locator_id
5287              , round(Abs(mmtt.primary_quantity),5)
5288              , round(Abs(mmtt.secondary_transaction_quantity),5)             -- invConv change
5289              , 1                                                                                         quantity_type
5290              , mmtt.transfer_cost_group_id                                                               cost_group_id
5291              , NVL(mmtt.content_lpn_id,mmtt.transfer_lpn_id)                                             lpn_id
5292              , to_number(NULL)                                                                           transaction_action_id
5293              , to_char(NULL)                                                                             transfer_subinventory_code
5294              , to_number(NULL)                                                                           transfer_locator_id
5295           FROM
5296                mtl_material_transactions_temp mmtt
5297           WHERE
5298                mmtt.posting_flag = 'Y'
5299            AND Decode( Nvl(mmtt.transaction_status,0),
5300                        2, decode(nvl(mmtt.wms_task_status,-1), 4, 1, 2),
5301                        1 ) <> 2
5302            AND mmtt.transaction_action_id IN (2,28,3)
5303            --bug 3581133
5304            AND mmtt.wip_supply_type IS NULL
5305              ) x
5306       WHERE x.organization_id    = l_organization_id
5307         AND x.inventory_item_id  = l_inventory_item_id
5308       GROUP BY
5309            x.organization_id, x.inventory_item_id, x.revision
5310           , x.lot_number, x.subinventory_code, x.locator_id
5311           , x.quantity_type, x.cost_group_id, x.lpn_id
5312           , x.transaction_action_id, x.transfer_subinventory_code
5313           , x.transfer_locator_id
5314              ) x
5315              , mtl_secondary_inventories sub
5316   WHERE
5317         x.organization_id    = sub.organization_id          (+)
5318     AND x.subinventory_code  = sub.secondary_inventory_name (+)
5319     AND (l_asset_subs_only = 2 OR NVL(sub.asset_inventory,1) = 1)
5320     AND (  (l_onhand_source = 1 AND Nvl(sub.inventory_atp_code, 1) = 1)
5321         OR (l_onhand_source = 2 AND Nvl(sub.availability_type, 1) = 1 )
5322         OR l_onhand_source =3
5323         OR (l_onhand_source = 4 AND (nvl(sub.inventory_atp_code,1) = 1 AND nvl(sub.availability_type,1)=1))
5324         )
5325     GROUP BY                                   -- invConv change : GROUP BY because of SUM.
5326           x.organization_id
5327         , x.inventory_item_id
5328         , x.revision
5329         , NULL
5330         , NULL
5331         , sub.reservable_type
5332         , x.subinventory_code
5333         , NULL
5334         , x.locator_id
5335         , x.quantity_type
5336         , x.cost_group_id
5337         , x.lpn_id
5338         , x.transaction_action_id
5339         , x.transfer_subinventory_code
5340         , x.transfer_locator_id;
5341 
5342      -- invConv changes begin : c_plain with MMS about ATP/Nettable...
5343      CURSOR c_plain_MMS IS
5344      SELECT
5345           x.organization_id       organization_id
5346         , x.inventory_item_id     inventory_item_id
5347         , x.revision              revision
5348    , NULL           lot_number
5349         , NULL              lot_expiration_date
5350         , x.subinventory_code     subinventory_code
5351         , sub.reservable_type     reservable_type
5352         , x.locator_id            locator_id
5353         , SUM(x.primary_quantity)     primary_quantity          -- invConv change (added SUM)
5354         , SUM(x.secondary_quantity)   secondary_quantity        -- invConv change (+added SUM)
5355         , x.quantity_type         quantity_type
5356         , x.cost_group_id         cost_group_id
5357         , x.lpn_id        lpn_id
5358         , x.transaction_action_id       transaction_action_id
5359         , x.transfer_subinventory_code  transfer_subinventory_code
5360         , x.transfer_locator_id         transfer_locator_id
5361         , x.status_id
5362      FROM (
5363        SELECT
5364            x.organization_id                                organization_id
5365          , x.inventory_item_id                              inventory_item_id
5366          , decode(l_revision_control, 2, NULL, x.revision)  revision
5367          , NULL                                             lot_number
5368          , x.subinventory_code                              subinventory_code
5369          , x.locator_id                                     locator_id
5370          , SUM(x.primary_quantity)                          primary_quantity
5371          , SUM(x.secondary_quantity)                        secondary_quantity    -- invConv change
5372          , x.quantity_type                                  quantity_type
5373          , x.cost_group_id                                  cost_group_id
5374          , x.lpn_id                                         lpn_id
5375          , x.transaction_action_id                          transaction_action_id
5376          , x.transfer_subinventory_code                     transfer_subinventory_code
5377          , x.transfer_locator_id                            transfer_locator_id
5378          , x.status_id
5379         FROM (
5380        -- reservations
5381        SELECT
5382           mr.organization_id                                                        organization_id
5383         , mr.inventory_item_id                                                      inventory_item_id
5384         , mr.revision                                                               revision
5385         , mr.lot_number                                                             lot_number
5386         , mr.subinventory_code                                                      subinventory_code
5387         , mr.locator_id                                                             locator_id
5388         , mr.primary_reservation_quantity - Nvl(mr.detailed_quantity,0)             primary_quantity
5389         , mr.secondary_reservation_quantity - Nvl(mr.secondary_detailed_quantity,0) secondary_quantity
5390         , 3                                                                         quantity_type
5391         , to_number(NULL)                                                           cost_group_id
5392         , lpn_id                                                                    lpn_id
5393         , to_number(NULL)                                                           transaction_action_id
5394         , to_char(NULL)                                                             transfer_subinventory_code
5395         , to_number(NULL)                                                           transfer_locator_id
5396         , to_number(NULL)                                                           status_id -- Onhand Material Status Support
5397      FROM mtl_reservations mr
5398      WHERE
5399           Nvl(mr.supply_source_type_id, 13) = 13
5400       AND mr.primary_reservation_quantity >
5401       Nvl(mr.detailed_quantity,0)
5402       AND ((l_no_lpn_reservations <>1)
5403            OR (l_no_lpn_reservations = 1 AND mr.lpn_id IS NULL))
5404       AND (l_tree_mode <> 3 OR
5405           (l_tree_mode = 3
5406       AND NOT (l_demand_source_type_id = mr.demand_source_type_id
5407                 AND l_demand_source_header_id = mr.demand_source_header_id
5408             AND Nvl(l_demand_source_line_id, -9999) =
5409          Nvl(mr.demand_source_line_id,-9999)
5410             AND Nvl(l_demand_source_name, '@@@###@@#') =
5411          Nvl(mr.demand_source_name,'@@@###@@#')
5412                 AND Nvl(l_demand_source_delivery,-9999) =
5413          Nvl(mr.demand_source_delivery,-9999)
5414                    )
5415         ))
5416      UNION ALL
5417        -- onhand quantities
5418        SELECT
5419           moq.organization_id               organization_id
5420         , moq.inventory_item_id             inventory_item_id
5421         , moq.revision                      revision
5422         , moq.lot_number                    lot_number
5423         , moq.subinventory_code             subinventory_code
5424         , moq.locator_id                    locator_id
5425         , moq.primary_transaction_quantity
5426         , moq.secondary_transaction_quantity                                  -- invConv change
5427         , 1                                 quantity_type
5428         , moq.cost_group_id                 cost_group_id
5429         , moq.lpn_id             lpn_id
5430         , to_number(NULL)                      transaction_action_id
5431         , to_char(NULL)                        transfer_subinventory_code
5432         , to_number(NULL)                      transfer_locator_id
5433         , moq.status_id                        -- Onhand Material Status Support
5434        FROM
5435           mtl_onhand_quantities_detail       moq
5436      UNION ALL
5437        -- pending transactions in mmtt
5438        SELECT
5439             mmtt.organization_id    organization_id
5440           , mmtt.inventory_item_id  inventory_item_id
5441           , mmtt.revision           revision
5442           , NULL              lot_number
5443           , mmtt.subinventory_code  subinventory_code
5444           , mmtt.locator_id         locator_id
5445      --Bug 4185621
5446      --, Decode(mmtt.transaction_status, 2, 1,
5447      , Decode(Decode(mmtt.transaction_status, 2, decode(nvl(mmtt.wms_task_status,-1),4,-1,2), mmtt.transaction_status), 2, 1,
5448       Decode(mmtt.transaction_action_id,1,-1,2,-1,28,-1,3,-1,
5449             Sign(mmtt.primary_quantity)))
5450          * round(Abs(mmtt.primary_quantity),5)
5451      --Bug 4185621
5452      --, Decode(mmtt.transaction_status, 2, 1,
5453      , Decode(Decode(mmtt.transaction_status, 2, decode(nvl(mmtt.wms_task_status,-1),4,-1,2), mmtt.transaction_status), 2, 1,
5454       Decode(mmtt.transaction_action_id,1,-1,2,-1,28,-1,3,-1,
5455             Sign(mmtt.secondary_transaction_quantity)))
5456          * round(Abs(mmtt.secondary_transaction_quantity),5)                              -- invConv change
5457      --Bug 4185621
5458      --, Decode(mmtt.transaction_status, 2, 5, 1)  quantity_type
5459      , Decode(mmtt.transaction_status, 2, decode(nvl(mmtt.wms_task_status,-1),4,1,5), 1)  quantity_type
5460           , mmtt.cost_group_id       cost_group_id
5461           ,NVL(mmtt.allocated_lpn_id,
5462       NVL(mmtt.content_lpn_id, mmtt.lpn_id)) lpn_id
5463           , Decode(mmtt.transaction_status, 2 , mmtt.transaction_action_id, to_number(NULL)) transaction_action_id
5464           , Decode(mmtt.transaction_status, 2 , mmtt.transfer_subinventory, to_char(NULL)) transfer_subinventory_code
5465           , Decode(mmtt.transaction_status, 2 , mmtt.transfer_to_location, to_number(NULL))  transfer_locator_id
5466           , inv_material_status_grp.get_default_status(mmtt.organization_id
5467                                           ,mmtt.inventory_item_id
5468                                           ,mmtt.subinventory_code
5469                                           ,mmtt.locator_id
5470                                           ,null -- lot_number
5471                                           ,NVL(mmtt.allocated_lpn_id,
5472                                  NVL(mmtt.content_lpn_id, mmtt.lpn_id))
5473                                           ) status_id -- Onhand Material Status Support
5474        FROM
5475             mtl_material_transactions_temp mmtt
5476        WHERE
5477               mmtt.posting_flag = 'Y'
5478        AND mmtt.subinventory_code IS NOT NULL
5479     AND (Nvl(mmtt.transaction_status,0) <> 2 OR
5480          Nvl(mmtt.transaction_status,0) = 2 AND
5481          mmtt.transaction_action_id IN (1,2,28,3,21,29,32,34)
5482         )
5483       -- dont look at scrap and costing txns
5484       -- Bug 3396558 fix. Ignore ownership xfr,planning xfr transactions
5485          AND mmtt.transaction_action_id NOT IN (5,6,24,30)
5486        UNION ALL
5487        -- receiving side of transfers
5488        -- added 5/23/00
5489        -- if quantity is in an lpn, then it is containerized
5490        -- Bug 7658493, If wms task is in loaded status, consider allocation like pending transaction.
5491        SELECT
5492             Decode(mmtt.transaction_action_id
5493                , 3, mmtt.transfer_organization
5494                , mmtt.organization_id)   organization_id
5495           , mmtt.inventory_item_id       inventory_item_id
5496           , mmtt.revision                revision
5497           , NULL                         lot_number
5498           , mmtt.transfer_subinventory   subinventory_code
5499           , mmtt.transfer_to_location    locator_id
5500           , round(Abs(mmtt.primary_quantity),5)
5501           , round(Abs(mmtt.secondary_transaction_quantity),5)             -- invConv change
5502           , 1                            quantity_type
5503           , mmtt.transfer_cost_group_id  cost_group_id
5504           , NVL(mmtt.content_lpn_id,mmtt.transfer_lpn_id) lpn_id
5505           , to_number(NULL)                      transaction_action_id
5506           , to_char(NULL)                        transfer_subinventory_code
5507           , to_number(NULL)                      transfer_locator_id
5508           , inv_material_status_grp.get_default_status(Decode(mmtt.transaction_action_id
5509                                                , 3, mmtt.transfer_organization
5510                                                , mmtt.organization_id)
5511                                           ,mmtt.inventory_item_id
5512                                           ,mmtt.transfer_subinventory
5513                                           ,mmtt.transfer_to_location
5514                                           ,null -- lot_number
5515                                           ,NVL(mmtt.content_lpn_id,mmtt.transfer_lpn_id)
5516                                           ,mmtt.transaction_action_id
5517                                           ,inv_material_status_grp.get_default_status(mmtt.organization_id
5518                                                   ,mmtt.inventory_item_id
5519                                                   ,mmtt.subinventory_code
5520                                                   ,mmtt.locator_id
5521                                                   ,null -- lot_number
5522                                                   ,NVL(mmtt.allocated_lpn_id,
5523                                         NVL(mmtt.content_lpn_id, mmtt.lpn_id))
5524                                                   )
5525                                           ) status_id -- Onhand Material Status Support
5526        FROM
5527             mtl_material_transactions_temp mmtt
5528        WHERE
5529              mmtt.posting_flag = 'Y'
5530          AND Decode( Nvl(mmtt.transaction_status,0),
5531                        2, decode(nvl(mmtt.wms_task_status,-1), 4, 1, 2),
5532                        1 ) <> 2
5533          AND mmtt.transaction_action_id IN (2,28,3)
5534      --bug 3581133
5535        AND mmtt.wip_supply_type IS NULL
5536       ) x
5537       WHERE x.organization_id    = l_organization_id
5538         AND x.inventory_item_id  = l_inventory_item_id
5539       GROUP BY
5540            x.organization_id, x.inventory_item_id, x.revision
5541           , x.lot_number,x.subinventory_code, x.locator_id
5542           , x.quantity_type, x.cost_group_id, x.lpn_id
5543           , x.transaction_action_id, x.transfer_subinventory_code
5544           , x.transfer_locator_id, x.status_id -- Onhand Material Status Support
5545    ) x
5546     , mtl_secondary_inventories sub
5547     , mtl_item_locations loc        -- invConv change
5548     , mtl_parameters mp -- Onhand Material Status Support
5549     , mtl_material_statuses_b mms -- Onhand Material Status Support
5550   WHERE
5551         x.organization_id = loc.organization_id  (+)              -- invConv change
5552     AND x.locator_id = loc.inventory_location_id (+)              -- invConv change
5553     AND x.organization_id    = sub.organization_id         (+)
5554     AND x.subinventory_code = sub.secondary_inventory_name (+)
5555     AND x.organization_id    = mp.organization_id (+) -- Onhand Material Status Support
5556     AND x.status_id = mms.status_id (+) -- Onhand Material Status Support
5557     AND (l_asset_subs_only = 2 OR
5558          NVL(sub.asset_inventory,1) = 1)
5559     AND (
5560          (mp.default_status_id is null and
5561           ( (l_onhand_source =1 AND
5562              Nvl(sub.inventory_atp_code, 1) = 1
5563              AND Nvl(loc.inventory_atp_code, 1) = 1                  -- invConv change
5564        )
5565             OR (l_onhand_source = 2 AND
5566        Nvl(sub.availability_type, 1) = 1
5567                  AND Nvl(loc.availability_type, 1) = 1            -- invConv change
5568           )
5569        OR l_onhand_source =3
5570             OR (l_onhand_source = 4 AND
5571            (nvl(sub.inventory_atp_code,1) = 1
5572                  AND Nvl(loc.inventory_atp_code, 1) = 1                 -- invConv change
5573                  AND Nvl(loc.availability_type, 1) = 1                  -- invConv change
5574                  AND nvl(sub.availability_type,1)=1
5575                 )
5576                )
5577           )
5578          )
5579          OR
5580          (
5581           mp.default_status_id is not null and
5582            ( (l_onhand_source =1 AND
5583                Nvl(mms.inventory_atp_code, 1) = 1
5584              )
5585              OR (l_onhand_source = 2 AND
5586                  Nvl(mms.availability_type, 1) = 1
5587            )
5588         OR l_onhand_source =3
5589              OR (l_onhand_source = 4 AND
5590              (nvl(mms.inventory_atp_code,1) = 1
5591               AND nvl(mms.availability_type,1)=1
5592                   )
5593                 )
5594            )
5595          )
5596     )
5597     GROUP BY                     -- invConv change : GROUP BY because of SUM.
5598           x.organization_id
5599         , x.inventory_item_id
5600         , x.revision
5601         , NULL
5602         , NULL
5603         , x.subinventory_code
5604         , sub.reservable_type
5605         , x.locator_id
5606         , x.quantity_type
5607         , x.cost_group_id
5608         , x.lpn_id
5609         , x.transaction_action_id
5610         , x.transfer_subinventory_code
5611         , x.transfer_locator_id
5612         , x.status_id; -- Onhand Material Status Support
5613      -- invConv changes end : c_plain with MMS about ATP/Nettable...
5614 
5615 
5616           --Lot Controlled and Not Unit Effective
5617       -- invConv change : grade_code filter is in cursor c_lot_grade.
5618       -- invConv ... no chage here, go and see c_lot_grade
5619       -- invConv ... no MMS specific change here ... see c_lot_MMS and c_lot_grade_MMS
5620 
5621       CURSOR c_lot IS
5622       SELECT
5623           x.organization_id       organization_id
5624         , x.inventory_item_id     inventory_item_id
5625         , x.revision              revision
5626         , x.lot_number       lot_number
5627         , lot.expiration_date     lot_expiration_date
5628         , x.subinventory_code     subinventory_code
5629         , sub.reservable_type     reservable_type
5630         , x.locator_id            locator_id
5631         , x.primary_quantity      primary_quantity
5632         , x.secondary_quantity    secondary_quantity       -- invConv change
5633         , x.quantity_type         quantity_type
5634         , x.cost_group_id         cost_group_id
5635         , x.lpn_id        lpn_id
5636         , x.transaction_action_id       transaction_action_id
5637         , x.transfer_subinventory_code  transfer_subinventory_code
5638         , x.transfer_locator_id         transfer_locator_id
5639      FROM (
5640        SELECT
5641            x.organization_id       organization_id
5642          , x.inventory_item_id     inventory_item_id
5643          , decode(l_revision_control, 2, NULL, x.revision) revision
5644          , x.lot_number            lot_number
5645          , x.subinventory_code     subinventory_code
5646          , x.locator_id            locator_id
5647          , SUM(x.primary_quantity) primary_quantity
5648          , SUM(x.secondary_quantity) secondary_quantity     -- invConv change
5649          , x.quantity_type         quantity_type
5650          , x.cost_group_id         cost_group_id
5651          , x.lpn_id        lpn_id
5652          , x.transaction_action_id       transaction_action_id
5653          , x.transfer_subinventory_code  transfer_subinventory_code
5654          , x.transfer_locator_id         transfer_locator_id
5655         FROM (
5656        -- reservations
5657        SELECT
5658           mr.organization_id       organization_id
5659         , mr.inventory_item_id     inventory_item_id
5660         , mr.revision              revision
5661         , mr.lot_number            lot_number
5662         , mr.subinventory_code     subinventory_code
5663         , mr.locator_id            locator_id
5664         , mr.primary_reservation_quantity
5665            - Nvl(mr.detailed_quantity,0)    primary_quantity
5666         , mr.secondary_reservation_quantity
5667            - Nvl(mr.secondary_detailed_quantity,0)    secondary_quantity     -- invConv change
5668         , 3                        quantity_type
5669         , to_number(NULL)     cost_group_id
5670         , lpn_id        lpn_id
5671         , to_number(NULL)                      transaction_action_id
5672         , to_char(NULL)                        transfer_subinventory_code
5673         , to_number(NULL)                      transfer_locator_id
5674      FROM mtl_reservations mr
5675      WHERE
5676           Nvl(mr.supply_source_type_id, 13) = 13
5677       AND mr.primary_reservation_quantity >
5678        Nvl(mr.detailed_quantity,0)
5679       AND ((l_no_lpn_reservations <>1)
5680            OR (l_no_lpn_reservations = 1 AND mr.lpn_id IS NULL))
5681       AND (l_tree_mode <> 3 OR
5682           (l_tree_mode = 3
5683       AND NOT
5684              ( l_demand_source_type_id = mr.demand_source_type_id
5685             AND l_demand_source_header_id =  mr.demand_source_header_id
5686             AND Nvl(l_demand_source_line_id, -9999) =
5687       Nvl(mr.demand_source_line_id,-9999)
5688           AND Nvl(l_demand_source_name, '@@@###@@#') =
5689       Nvl(mr.demand_source_name,'@@@###@@#')
5690        AND Nvl(l_demand_source_delivery,-9999) =
5691       Nvl(mr.demand_source_delivery,-9999)
5692               )
5693    ))
5694      UNION ALL
5695        -- onhand quantities
5696        SELECT
5697           moq.organization_id               organization_id
5698         , moq.inventory_item_id             inventory_item_id
5699         , moq.revision                      revision
5700         , moq.lot_number                    lot_number
5701         , moq.subinventory_code             subinventory_code
5702         , moq.locator_id                    locator_id
5703         , moq.primary_transaction_quantity
5704         , moq.secondary_transaction_quantity                            -- invConv change
5705         , 1                                 quantity_type
5706    , moq.cost_group_id                 cost_group_id
5707    , moq.lpn_id             lpn_id
5708         , to_number(NULL)                      transaction_action_id
5709         , to_char(NULL)                        transfer_subinventory_code
5710         , to_number(NULL)                      transfer_locator_id
5711        FROM
5712           mtl_onhand_quantities_detail       moq
5713      UNION ALL
5714        -- pending transactions in mmtt, lot in MMTT
5715        SELECT
5716             mmtt.organization_id    organization_id
5717           , mmtt.inventory_item_id  inventory_item_id
5718           , mmtt.revision           revision
5719           , mmtt.lot_number         lot_number
5720           , mmtt.subinventory_code  subinventory_code
5721           , mmtt.locator_id         locator_id
5722      --Bug 4185621
5723           --, Decode(mmtt.transaction_status, 2, 1,
5724           , Decode(Decode(mmtt.transaction_status, 2, decode(nvl(mmtt.wms_task_status,-1),4,-1,2), mmtt.transaction_status), 2, 1,
5725       Decode(mmtt.transaction_action_id,1,-1,2,-1,28,-1,3,-1,
5726          Sign(mmtt.primary_quantity)))
5727          * round(Abs(mmtt.primary_quantity),5)
5728      --Bug 4185621
5729           --, Decode(mmtt.transaction_status, 2, 1,
5730           , Decode(Decode(mmtt.transaction_status, 2, decode(nvl(mmtt.wms_task_status,-1),4,-1,2), mmtt.transaction_status), 2, 1,
5731       Decode(mmtt.transaction_action_id,1,-1,2,-1,28,-1,3,-1,
5732          Sign(mmtt.secondary_transaction_quantity)))
5733          * round(Abs(mmtt.secondary_transaction_quantity),5)           -- invConv change
5734      --Bug 4185621
5735           --, Decode(mmtt.transaction_status, 2, 5, 1) quantity_type
5736           , Decode(mmtt.transaction_status, 2, decode(nvl(mmtt.wms_task_status,-1),4,1,5), 1)  quantity_type
5737           , mmtt.cost_group_id       cost_group_id
5738      ,NVL(mmtt.allocated_lpn_id,
5739       NVL(mmtt.content_lpn_id, mmtt.lpn_id)) lpn_id
5740           , Decode(mmtt.transaction_status, 2 , mmtt.transaction_action_id, to_number(NULL)) transaction_action_id
5741           , Decode(mmtt.transaction_status, 2 , mmtt.transfer_subinventory, to_char(NULL)) transfer_subinventory_code
5742           , Decode(mmtt.transaction_status, 2 , mmtt.transfer_to_location, to_number(NULL))  transfer_locator_id
5743        FROM
5744             mtl_material_transactions_temp mmtt
5745        WHERE
5746             mmtt.posting_flag = 'Y'
5747     AND mmtt.lot_number IS NOT NULL
5748     AND mmtt.subinventory_code IS NOT NULL
5749     AND (Nvl(mmtt.transaction_status,0) <> 2 OR
5750             Nvl(mmtt.transaction_status,0) = 2 AND
5751             mmtt.transaction_action_id IN (1,2,28,3,21,29,32,34)
5752         )
5753       -- dont look at scrap and costing txns
5754       -- Bug 3396558 fix. Ignore ownership xfr,planning xfr transactions
5755          AND mmtt.transaction_action_id NOT IN (5,6,24,30)
5756     UNION ALL
5757        --MMTT records, lot in MTLT
5758        SELECT
5759             mmtt.organization_id    organization_id
5760           , mmtt.inventory_item_id  inventory_item_id
5761           , mmtt.revision           revision
5762           , mtlt.lot_number         lot_number
5763           , mmtt.subinventory_code  subinventory_code
5764           , mmtt.locator_id         locator_id
5765      --Bug 4185621
5766           --, Decode(mmtt.transaction_status, 2, 1,
5767           , Decode(Decode(mmtt.transaction_status, 2, decode(nvl(mmtt.wms_task_status,-1),4,-1,2), mmtt.transaction_status), 2, 1,
5768       Decode(mmtt.transaction_action_id,1,-1,2,-1,28,-1,3,-1,
5769       Sign(mmtt.primary_quantity)))
5770        * round(Abs( mtlt.primary_quantity ),5)
5771      --Bug 4185621
5772      --, Decode(mmtt.transaction_status, 2, 1,
5773           , Decode(Decode(mmtt.transaction_status, 2, decode(nvl(mmtt.wms_task_status,-1),4,-1,2), mmtt.transaction_status), 2, 1,
5774       Decode(mmtt.transaction_action_id,1,-1,2,-1,28,-1,3,-1,
5775       Sign(mmtt.secondary_transaction_quantity)))
5776        * round(Abs( mtlt.secondary_quantity ),5)             -- invConv change
5777      --Bug 4185621
5778           --, Decode(mmtt.transaction_status, 2, 5, 1) quantity_type
5779           , Decode(mmtt.transaction_status, 2, decode(nvl(mmtt.wms_task_status,-1),4,1,5), 1)  quantity_type
5780           , mmtt.cost_group_id       cost_group_id
5781      ,NVL(mmtt.allocated_lpn_id,
5782       NVL(mmtt.content_lpn_id, mmtt.lpn_id)) lpn_id
5783           , Decode(mmtt.transaction_status, 2 , mmtt.transaction_action_id, to_number(NULL)) transaction_action_id
5784           , Decode(mmtt.transaction_status, 2 , mmtt.transfer_subinventory, to_char(NULL)) transfer_subinventory_code
5785           , Decode(mmtt.transaction_status, 2 , mmtt.transfer_to_location, to_number(NULL))  transfer_locator_id
5786        FROM
5787            mtl_material_transactions_temp mmtt,
5788       mtl_transaction_lots_temp mtlt
5789        WHERE
5790              mmtt.posting_flag = 'Y'
5791          AND mmtt.transaction_temp_id = mtlt.transaction_temp_id
5792          AND mmtt.lot_number IS NULL
5793     AND mmtt.subinventory_code IS NOT NULL
5794     AND (Nvl(mmtt.transaction_status,0) <> 2 OR
5795          Nvl(mmtt.transaction_status,0) = 2 AND
5796         mmtt.transaction_action_id IN (1,2,28,3,21,29,32,34)
5797       )
5798       -- dont look at scrap and costing txns
5799       -- Bug 3396558 fix. Ignore ownership xfr,planning xfr transactions
5800          AND mmtt.transaction_action_id NOT IN (5,6,24,30)
5801        UNION ALL
5802        -- receiving side of transfers, lot in MMTT
5803        -- Bug 7658493, If wms task is in loaded status, consider allocation like pending transaction.
5804        SELECT
5805             Decode(mmtt.transaction_action_id
5806                , 3, mmtt.transfer_organization
5807                , mmtt.organization_id)   organization_id
5808           , mmtt.inventory_item_id       inventory_item_id
5809           , mmtt.revision                revision
5810           , mmtt.lot_number              lot_number
5811           , mmtt.transfer_subinventory   subinventory_code
5812           , mmtt.transfer_to_location    locator_id
5813           , round(Abs( mmtt.primary_quantity),5)
5814           , round(Abs( mmtt.secondary_transaction_quantity),5)         -- invConv change
5815           , 1                            quantity_type
5816           , mmtt.transfer_cost_group_id  cost_group_id
5817           , NVL(mmtt.content_lpn_id,mmtt.transfer_lpn_id) lpn_id
5818           , to_number(NULL)                      transaction_action_id
5819           , to_char(NULL)                        transfer_subinventory_code
5820           , to_number(NULL)                      transfer_locator_id
5821        FROM
5822             mtl_material_transactions_temp mmtt
5823        WHERE
5824              mmtt.posting_flag = 'Y'
5825      AND mmtt.lot_number IS NOT NULL
5826      AND Decode( Nvl(mmtt.transaction_status,0),
5827                        2, decode(nvl(mmtt.wms_task_status,-1), 4, 1, 2),
5828                        1 ) <> 2
5829           AND mmtt.transaction_action_id IN (2,28,3)
5830   UNION ALL
5831        -- receiving side of transfers, lot in MTLT
5832        -- Bug 7658493, If wms task is in loaded status, consider allocation like pending transaction.
5833        SELECT
5834             Decode(mmtt.transaction_action_id
5835                , 3, mmtt.transfer_organization
5836                , mmtt.organization_id)   organization_id
5837           , mmtt.inventory_item_id       inventory_item_id
5838           , mmtt.revision                revision
5839           , mtlt.lot_number              lot_number
5840           , mmtt.transfer_subinventory   subinventory_code
5841           , mmtt.transfer_to_location    locator_id
5842           , round(Abs( mtlt.primary_quantity ),5)
5843           , round(Abs( mtlt.secondary_quantity ),5)              -- invConv change
5844           , 1                            quantity_type
5845           , mmtt.transfer_cost_group_id  cost_group_id
5846           , NVL(mmtt.content_lpn_id,mmtt.transfer_lpn_id) lpn_id
5847           , to_number(NULL)                      transaction_action_id
5848           , to_char(NULL)                        transfer_subinventory_code
5849           , to_number(NULL)                      transfer_locator_id
5850        FROM
5851             mtl_material_transactions_temp mmtt,
5852        mtl_transaction_lots_temp mtlt
5853        WHERE
5854              mmtt.posting_flag = 'Y'
5855           AND mmtt.lot_number IS NULL
5856           AND mmtt.transaction_temp_id = mtlt.transaction_temp_id
5857           AND Decode( Nvl(mmtt.transaction_status,0),
5858                        2, decode(nvl(mmtt.wms_task_status,-1), 4, 1, 2),
5859                        1 ) <> 2
5860           AND mmtt.transaction_action_id IN (2,28,3)
5861       ) x
5862       WHERE x.organization_id    = l_organization_id
5863         AND x.inventory_item_id  = l_inventory_item_id
5864       GROUP BY
5865            x.organization_id, x.inventory_item_id, x.revision
5866           , x.lot_number,x.subinventory_code, x.locator_id
5867           , x.quantity_type, x.cost_group_id, x.lpn_id
5868           , x.transaction_action_id, x.transfer_subinventory_code
5869           , x.transfer_locator_id
5870    ) x
5871     , mtl_secondary_inventories sub
5872     , mtl_lot_numbers lot
5873  WHERE
5874    x.organization_id    = sub.organization_id          (+)
5875    AND x.subinventory_code = sub.secondary_inventory_name (+)
5876    AND x.organization_id   = lot.organization_id   (+)
5877    AND x.inventory_item_id = lot.inventory_item_id (+)
5878    AND x.lot_number        = lot.lot_number        (+)
5879    AND (l_asset_subs_only = 2 OR
5880          NVL(sub.asset_inventory,1) = 1)
5881    AND ((l_onhand_source = 1 AND
5882     Nvl(sub.inventory_atp_code, 1) = 1
5883       ) OR
5884         (l_onhand_source = 2 AND
5885        Nvl(sub.availability_type, 1) = 1
5886    ) OR
5887    l_onhand_source =3
5888    OR
5889    (l_onhand_source = 4 AND
5890     Nvl(sub.inventory_atp_code, 1) = 1 AND
5891     Nvl(sub.availability_type, 1) = 1)
5892       )
5893    AND (l_lot_expiration_control = 2 OR
5894         lot.expiration_date IS NULL OR
5895         l_lot_expiration_date IS NULL OR
5896         lot.expiration_date > l_lot_expiration_date);
5897 
5898      CURSOR c_lot_MMS IS
5899       SELECT
5900           x.organization_id       organization_id
5901         , x.inventory_item_id     inventory_item_id
5902         , x.revision              revision
5903         , x.lot_number       lot_number
5904         , lot.expiration_date     lot_expiration_date
5905         , x.subinventory_code     subinventory_code
5906         , sub.reservable_type     reservable_type
5907         , x.locator_id            locator_id
5908         , x.primary_quantity      primary_quantity
5909         , x.secondary_quantity    secondary_quantity       -- invConv change
5910         , x.quantity_type         quantity_type
5911         , x.cost_group_id         cost_group_id
5912         , x.lpn_id        lpn_id
5913         , x.transaction_action_id       transaction_action_id
5914         , x.transfer_subinventory_code  transfer_subinventory_code
5915         , x.transfer_locator_id         transfer_locator_id
5916         , x.status_id -- Onhand Material Status Support
5917      FROM (
5918        SELECT
5919            x.organization_id       organization_id
5920          , x.inventory_item_id     inventory_item_id
5921          , decode(l_revision_control, 2, NULL, x.revision) revision
5922          , x.lot_number            lot_number
5923          , x.subinventory_code     subinventory_code
5924          , x.locator_id            locator_id
5925          , SUM(x.primary_quantity) primary_quantity
5926          , SUM(x.secondary_quantity) secondary_quantity     -- invConv change
5927          , x.quantity_type         quantity_type
5928          , x.cost_group_id         cost_group_id
5929          , x.lpn_id        lpn_id
5930          , x.transaction_action_id       transaction_action_id
5931          , x.transfer_subinventory_code  transfer_subinventory_code
5932          , x.transfer_locator_id         transfer_locator_id
5933          , x.status_id -- Onhand Material Status Support
5934         FROM (
5935        -- reservations
5936        SELECT
5937           mr.organization_id       organization_id
5938         , mr.inventory_item_id     inventory_item_id
5939         , mr.revision              revision
5940         , mr.lot_number            lot_number
5941         , mr.subinventory_code     subinventory_code
5942         , mr.locator_id            locator_id
5943         , mr.primary_reservation_quantity
5944            - Nvl(mr.detailed_quantity,0)    primary_quantity
5945         , mr.secondary_reservation_quantity
5946            - Nvl(mr.secondary_detailed_quantity,0)    secondary_quantity     -- invConv change
5947         , 3                        quantity_type
5948         , to_number(NULL)     cost_group_id
5949         , lpn_id        lpn_id
5950         , to_number(NULL)                      transaction_action_id
5951         , to_char(NULL)                        transfer_subinventory_code
5952         , to_number(NULL)                      transfer_locator_id
5953         , to_number(NULL)                      status_id -- Onhand Material Status Support
5954      FROM mtl_reservations mr
5955      WHERE
5956           Nvl(mr.supply_source_type_id, 13) = 13
5957       AND mr.primary_reservation_quantity >
5958        Nvl(mr.detailed_quantity,0)
5959       AND ((l_no_lpn_reservations <>1)
5960            OR (l_no_lpn_reservations = 1 AND mr.lpn_id IS NULL))
5961       AND (l_tree_mode <> 3 OR
5962           (l_tree_mode = 3
5963       AND NOT
5964              ( l_demand_source_type_id = mr.demand_source_type_id
5965             AND l_demand_source_header_id =  mr.demand_source_header_id
5966             AND Nvl(l_demand_source_line_id, -9999) =
5967       Nvl(mr.demand_source_line_id,-9999)
5968           AND Nvl(l_demand_source_name, '@@@###@@#') =
5969       Nvl(mr.demand_source_name,'@@@###@@#')
5970        AND Nvl(l_demand_source_delivery,-9999) =
5971       Nvl(mr.demand_source_delivery,-9999)
5972               )
5973    ))
5974      UNION ALL
5975        -- onhand quantities
5976        SELECT
5977           moq.organization_id               organization_id
5978         , moq.inventory_item_id             inventory_item_id
5979         , moq.revision                      revision
5980         , moq.lot_number                    lot_number
5981         , moq.subinventory_code             subinventory_code
5982         , moq.locator_id                    locator_id
5983         , moq.primary_transaction_quantity
5984         , moq.secondary_transaction_quantity                            -- invConv change
5985         , 1                                 quantity_type
5986    , moq.cost_group_id                 cost_group_id
5987    , moq.lpn_id             lpn_id
5988         , to_number(NULL)                      transaction_action_id
5989         , to_char(NULL)                        transfer_subinventory_code
5990         , to_number(NULL)                      transfer_locator_id
5991         , moq.status_id                        -- Onhand Material Status Support
5992        FROM
5993           mtl_onhand_quantities_detail       moq
5994      UNION ALL
5995        -- pending transactions in mmtt, lot in MMTT
5996        SELECT
5997             mmtt.organization_id    organization_id
5998           , mmtt.inventory_item_id  inventory_item_id
5999           , mmtt.revision           revision
6000           , mmtt.lot_number         lot_number
6001           , mmtt.subinventory_code  subinventory_code
6002           , mmtt.locator_id         locator_id
6003      --Bug 4185621
6004           --, Decode(mmtt.transaction_status, 2, 1,
6005           , Decode(Decode(mmtt.transaction_status, 2, decode(nvl(mmtt.wms_task_status,-1),4,-1,2), mmtt.transaction_status), 2, 1,
6006       Decode(mmtt.transaction_action_id,1,-1,2,-1,28,-1,3,-1,
6007          Sign(mmtt.primary_quantity)))
6008          * round(Abs(mmtt.primary_quantity),5)
6009       --Bug 4185621
6010            --, Decode(mmtt.transaction_status, 2, 1,
6011            , Decode(Decode(mmtt.transaction_status, 2, decode(nvl(mmtt.wms_task_status,-1),4,-1,2), mmtt.transaction_status), 2, 1,
6012       Decode(mmtt.transaction_action_id,1,-1,2,-1,28,-1,3,-1,
6013          Sign(mmtt.secondary_transaction_quantity)))
6014          * round(Abs(mmtt.secondary_transaction_quantity),5)           -- invConv change
6015      --Bug 4185621
6016           --, Decode(mmtt.transaction_status, 2, 5, 1) quantity_type
6017           , Decode(mmtt.transaction_status, 2, decode(nvl(mmtt.wms_task_status,-1),4,1,5), 1)  quantity_type
6018           , mmtt.cost_group_id       cost_group_id
6019      ,NVL(mmtt.allocated_lpn_id,
6020       NVL(mmtt.content_lpn_id, mmtt.lpn_id)) lpn_id
6021           , Decode(mmtt.transaction_status, 2 , mmtt.transaction_action_id, to_number(NULL)) transaction_action_id
6022           , Decode(mmtt.transaction_status, 2 , mmtt.transfer_subinventory, to_char(NULL)) transfer_subinventory_code
6023           , Decode(mmtt.transaction_status, 2 , mmtt.transfer_to_location, to_number(NULL))  transfer_locator_id
6024           , inv_material_status_grp.get_default_status(mmtt.organization_id
6025                                           ,mmtt.inventory_item_id
6026                                           ,mmtt.subinventory_code
6027                                           ,mmtt.locator_id
6028                                           ,mmtt.lot_number -- lot_number
6029                                           ,NVL(mmtt.allocated_lpn_id,
6030                                  NVL(mmtt.content_lpn_id, mmtt.lpn_id))
6031                                           ) status_id -- Onhand Material Status Support
6032        FROM
6033             mtl_material_transactions_temp mmtt
6034        WHERE
6035             mmtt.posting_flag = 'Y'
6036 -- invConv bug 4074394   removed the fix in v115.141, because it only works
6037 --       when the ingredient item has no inventory.
6038          AND mmtt.lot_number IS NOT NULL
6039          AND mmtt.subinventory_code IS NOT NULL
6040          AND (Nvl(mmtt.transaction_status,0) <> 2 OR
6041               Nvl(mmtt.transaction_status,0) = 2 AND
6042               mmtt.transaction_action_id IN (1,2,28,3,21,29,32,34)
6043               )
6044       -- dont look at scrap and costing txns
6045       -- Bug 3396558 fix. Ignore ownership xfr,planning xfr transactions
6046          AND mmtt.transaction_action_id NOT IN (5,6,24,30)
6047     UNION ALL
6048        --MMTT records, lot in MTLT
6049        SELECT
6050             mmtt.organization_id    organization_id
6051           , mmtt.inventory_item_id  inventory_item_id
6052           , mmtt.revision           revision
6053           , mtlt.lot_number         lot_number
6054           , mmtt.subinventory_code  subinventory_code
6055           , mmtt.locator_id         locator_id
6056      --Bug 4185621
6057           --, Decode(mmtt.transaction_status, 2, 1,
6058           , Decode(Decode(mmtt.transaction_status, 2, decode(nvl(mmtt.wms_task_status,-1),4,-1,2), mmtt.transaction_status), 2, 1,
6059       Decode(mmtt.transaction_action_id,1,-1,2,-1,28,-1,3,-1,
6060       Sign(mmtt.primary_quantity)))
6061        * round(Abs( mtlt.primary_quantity ),5)
6062      --Bug 4185621
6063           --, Decode(mmtt.transaction_status, 2, 1,
6064           , Decode(Decode(mmtt.transaction_status, 2, decode(nvl(mmtt.wms_task_status,-1),4,-1,2), mmtt.transaction_status), 2, 1,
6065       Decode(mmtt.transaction_action_id,1,-1,2,-1,28,-1,3,-1,
6066       Sign(mmtt.secondary_transaction_quantity)))
6067        * round(Abs( mtlt.secondary_quantity ),5)             -- invConv change
6068      --Bug 4185621
6069           --, Decode(mmtt.transaction_status, 2, 5, 1) quantity_type
6070           , Decode(mmtt.transaction_status, 2, decode(nvl(mmtt.wms_task_status,-1),4,1,5), 1)  quantity_type
6071           , mmtt.cost_group_id       cost_group_id
6072      ,NVL(mmtt.allocated_lpn_id,
6073       NVL(mmtt.content_lpn_id, mmtt.lpn_id)) lpn_id
6074           , Decode(mmtt.transaction_status, 2 , mmtt.transaction_action_id, to_number(NULL)) transaction_action_id
6075           , Decode(mmtt.transaction_status, 2 , mmtt.transfer_subinventory, to_char(NULL)) transfer_subinventory_code
6076           , Decode(mmtt.transaction_status, 2 , mmtt.transfer_to_location, to_number(NULL))  transfer_locator_id
6077           , inv_material_status_grp.get_default_status(mmtt.organization_id
6078                                           ,mmtt.inventory_item_id
6079                                           ,mmtt.subinventory_code
6080                                           ,mmtt.locator_id
6081                                           ,mtlt.lot_number -- lot_number in MTLT
6082                                           ,NVL(mmtt.allocated_lpn_id,
6083                                  NVL(mmtt.content_lpn_id, mmtt.lpn_id))
6084                                           ) status_id -- Onhand Material Status Support
6085        FROM
6086            mtl_material_transactions_temp mmtt,
6087            mtl_transaction_lots_temp mtlt
6088        WHERE
6089              mmtt.posting_flag = 'Y'
6090          AND mmtt.transaction_temp_id = mtlt.transaction_temp_id
6091          AND mmtt.lot_number IS NULL
6092          AND mmtt.subinventory_code IS NOT NULL
6093          AND (Nvl(mmtt.transaction_status,0) <> 2 OR
6094               Nvl(mmtt.transaction_status,0) = 2 AND
6095               mmtt.transaction_action_id IN (1,2,28,3,21,29,32,34)
6096               )
6097           -- dont look at scrap and costing txns
6098           -- Bug 3396558 fix. Ignore ownership xfr,planning xfr transactions
6099          AND mmtt.transaction_action_id NOT IN (5,6,24,30)
6100        UNION ALL
6101        -- receiving side of transfers, lot in MMTT
6102        -- Bug 7658493, If wms task is in loaded status, consider allocation like pending transaction.
6103        SELECT
6104             Decode(mmtt.transaction_action_id
6105                , 3, mmtt.transfer_organization
6106                , mmtt.organization_id)   organization_id
6107           , mmtt.inventory_item_id       inventory_item_id
6108           , mmtt.revision                revision
6109           , mmtt.lot_number              lot_number
6110           , mmtt.transfer_subinventory   subinventory_code
6111           , mmtt.transfer_to_location    locator_id
6112           , round(Abs( mmtt.primary_quantity),5)
6113           , round(Abs( mmtt.secondary_transaction_quantity),5)         -- invConv change
6114           , 1                            quantity_type
6115           , mmtt.transfer_cost_group_id  cost_group_id
6116           , NVL(mmtt.content_lpn_id,mmtt.transfer_lpn_id) lpn_id
6117           , to_number(NULL)                      transaction_action_id
6118           , to_char(NULL)                        transfer_subinventory_code
6119           , to_number(NULL)                      transfer_locator_id
6120           , inv_material_status_grp.get_default_status(Decode(mmtt.transaction_action_id
6121                                                , 3, mmtt.transfer_organization
6122                                                , mmtt.organization_id)
6123                                           ,mmtt.inventory_item_id
6124                                           ,mmtt.transfer_subinventory
6125                                           ,mmtt.transfer_to_location
6126                                           ,mmtt.lot_number -- lot_number
6127                                           ,NVL(mmtt.content_lpn_id,mmtt.transfer_lpn_id)
6128                                           ,mmtt.transaction_action_id
6129                                           ,inv_material_status_grp.get_default_status(mmtt.organization_id
6130                                                   ,mmtt.inventory_item_id
6131                                                   ,mmtt.subinventory_code
6132                                                   ,mmtt.locator_id
6133                                                   ,mmtt.lot_number -- lot_number
6134                                                   ,NVL(mmtt.allocated_lpn_id,
6135                                         NVL(mmtt.content_lpn_id, mmtt.lpn_id))
6136                                                   )
6137                                           ) status_id -- Onhand Material Status Support
6138        FROM
6139             mtl_material_transactions_temp mmtt
6140        WHERE
6141              mmtt.posting_flag = 'Y'
6142      AND mmtt.lot_number IS NOT NULL
6143      AND Decode( Nvl(mmtt.transaction_status,0),
6144                        2, decode(nvl(mmtt.wms_task_status,-1), 4, 1, 2),
6145                        1 ) <> 2
6146           AND mmtt.transaction_action_id IN (2,28,3)
6147   UNION ALL
6148        -- receiving side of transfers, lot in MTLT
6149        -- Bug 7658493, If wms task is in loaded status, consider allocation like pending transaction.
6150        SELECT
6151             Decode(mmtt.transaction_action_id
6152                , 3, mmtt.transfer_organization
6153                , mmtt.organization_id)   organization_id
6154           , mmtt.inventory_item_id       inventory_item_id
6155           , mmtt.revision                revision
6156           , mtlt.lot_number              lot_number
6157           , mmtt.transfer_subinventory   subinventory_code
6158           , mmtt.transfer_to_location    locator_id
6159           , round(Abs( mtlt.primary_quantity ),5)
6160           , round(Abs( mtlt.secondary_quantity ),5)              -- invConv change
6161           , 1                            quantity_type
6162           , mmtt.transfer_cost_group_id  cost_group_id
6163           , NVL(mmtt.content_lpn_id,mmtt.transfer_lpn_id) lpn_id
6164           , to_number(NULL)                      transaction_action_id
6165           , to_char(NULL)                        transfer_subinventory_code
6166           , to_number(NULL)                      transfer_locator_id
6167           , inv_material_status_grp.get_default_status(Decode(mmtt.transaction_action_id
6168                                                , 3, mmtt.transfer_organization
6169                                                , mmtt.organization_id)
6170                                           ,mmtt.inventory_item_id
6171                                           ,mmtt.transfer_subinventory
6172                                           ,mmtt.transfer_to_location
6173                                           ,mtlt.lot_number -- lot_number
6174                                           ,NVL(mmtt.content_lpn_id,mmtt.transfer_lpn_id)
6175                                           ,mmtt.transaction_action_id
6176                                           ,inv_material_status_grp.get_default_status(mmtt.organization_id
6177                                                   ,mmtt.inventory_item_id
6178                                                   ,mmtt.subinventory_code
6179                                                   ,mmtt.locator_id
6180                                                   ,mtlt.lot_number -- lot_number
6181                                                   ,NVL(mmtt.allocated_lpn_id,
6182                                         NVL(mmtt.content_lpn_id, mmtt.lpn_id))
6183                                                   )
6184                                           ) status_id -- Onhand Material Status Support
6185        FROM
6186             mtl_material_transactions_temp mmtt,
6187        mtl_transaction_lots_temp mtlt
6188        WHERE
6189              mmtt.posting_flag = 'Y'
6190           AND mmtt.lot_number IS NULL
6191           AND mmtt.transaction_temp_id = mtlt.transaction_temp_id
6192           AND Decode( Nvl(mmtt.transaction_status,0),
6193                        2, decode(nvl(mmtt.wms_task_status,-1), 4, 1, 2),
6194                        1 ) <> 2
6195           AND mmtt.transaction_action_id IN (2,28,3)
6196       ) x
6197       WHERE x.organization_id    = l_organization_id
6198         AND x.inventory_item_id  = l_inventory_item_id
6199       GROUP BY
6200            x.organization_id, x.inventory_item_id, x.revision
6201           , x.lot_number,x.subinventory_code, x.locator_id
6202           , x.quantity_type, x.cost_group_id, x.lpn_id
6203           , x.transaction_action_id, x.transfer_subinventory_code
6204           , x.transfer_locator_id, x.status_id -- Onhand Material Status Support
6205    ) x
6206     , mtl_secondary_inventories sub
6207     , mtl_item_locations loc                                      -- invConv change
6208     , mtl_lot_numbers lot
6209     , mtl_parameters mp -- Onhand Material Status Support
6210     , mtl_material_statuses_b mms -- Onhand Material Status Support
6211  WHERE
6212        x.inventory_item_id = lot.inventory_item_id        (+)     -- invConv change
6213    AND x.organization_id = lot.organization_id            (+)     -- invConv change
6214    AND x.lot_number = lot.lot_number                      (+)     -- invConv change
6215    AND x.organization_id = loc.organization_id            (+)     -- invConv change
6216    AND x.locator_id = loc.inventory_location_id           (+)     -- invConv change
6217    AND x.organization_id    = sub.organization_id         (+)
6218    AND x.subinventory_code = sub.secondary_inventory_name (+)
6219    AND x.organization_id   = lot.organization_id   (+)
6220    AND x.inventory_item_id = lot.inventory_item_id (+)
6221    AND x.lot_number        = lot.lot_number        (+)
6222    AND x.organization_id    = mp.organization_id   (+) -- Onhand Material Status Support
6223    AND x.status_id = mms.status_id                 (+) -- Onhand Material Status Support
6224    AND (l_asset_subs_only = 2 OR
6225          NVL(sub.asset_inventory,1) = 1)
6226    AND (
6227         (mp.default_status_id is null and
6228         ((l_onhand_source = 1 AND
6229               Nvl(sub.inventory_atp_code, 1) = 1
6230           AND Nvl(loc.inventory_atp_code, 1) = 1                  -- invConv change
6231           AND Nvl(lot.inventory_atp_code, 1) = 1                  -- invConv change
6232       ) OR
6233         (l_onhand_source = 2 AND
6234                      Nvl(sub.availability_type, 1) = 1
6235                  AND Nvl(loc.availability_type, 1) = 1            -- invConv change
6236                  AND Nvl(lot.availability_type, 1) = 1            -- invConv change
6237    ) OR
6238    l_onhand_source =3
6239    OR
6240    (l_onhand_source = 4 AND
6241               Nvl(sub.inventory_atp_code, 1) = 1
6242           AND Nvl(loc.inventory_atp_code, 1) = 1                  -- invConv change
6243           AND Nvl(lot.inventory_atp_code, 1) = 1                  -- invConv change
6244           AND Nvl(loc.availability_type, 1) = 1                   -- invConv change
6245           AND Nvl(lot.availability_type, 1) = 1                   -- invConv change
6246      AND Nvl(sub.availability_type, 1) = 1
6247         )
6248       )
6249       )
6250       or
6251       (
6252         mp.default_status_id is not null and
6253            ((l_onhand_source =1 AND
6254                Nvl(mms.inventory_atp_code, 1) = 1
6255              )
6256           OR (l_onhand_source = 2 AND
6257          Nvl(mms.availability_type, 1) = 1
6258         )
6259      OR l_onhand_source =3
6260           OR (l_onhand_source = 4 AND
6261          (nvl(mms.inventory_atp_code,1) = 1
6262          AND nvl(mms.availability_type,1)=1
6263               )
6264              )
6265            )
6266        )
6267       )
6268    AND (l_lot_expiration_control = 2 OR
6269         lot.expiration_date IS NULL OR
6270         l_lot_expiration_date IS NULL OR
6271         lot.expiration_date > l_lot_expiration_date);
6272       -- invConv changes end : c_lot with MMS about ATP/Nettable...
6273 
6274       -- invConv change : grade_code filter is here
6275       -- invConv .... no MMS specific change, please see c_lot_grade_MMS
6276 
6277       CURSOR c_lot_grade IS
6278       SELECT
6279           x.organization_id       organization_id
6280         , x.inventory_item_id     inventory_item_id
6281         , x.revision              revision
6282         , x.lot_number       lot_number
6283         , lot.expiration_date     lot_expiration_date
6284         , x.subinventory_code     subinventory_code
6285         , sub.reservable_type     reservable_type
6286         , x.locator_id            locator_id
6287         , x.primary_quantity      primary_quantity
6288         , x.secondary_quantity    secondary_quantity       -- invConv change
6289         , x.quantity_type         quantity_type
6290         , x.cost_group_id         cost_group_id
6291         , x.lpn_id        lpn_id
6292         , x.transaction_action_id       transaction_action_id
6293         , x.transfer_subinventory_code  transfer_subinventory_code
6294         , x.transfer_locator_id         transfer_locator_id
6295      FROM (
6296        SELECT
6297            x.organization_id       organization_id
6298          , x.inventory_item_id     inventory_item_id
6299          , decode(l_revision_control, 2, NULL, x.revision) revision
6300          , x.lot_number            lot_number
6301          , x.subinventory_code     subinventory_code
6302          , x.locator_id            locator_id
6303          , SUM(x.primary_quantity) primary_quantity
6304          , SUM(x.secondary_quantity) secondary_quantity     -- invConv change
6305          , x.quantity_type         quantity_type
6306          , x.cost_group_id         cost_group_id
6307          , x.lpn_id        lpn_id
6308          , x.transaction_action_id       transaction_action_id
6309          , x.transfer_subinventory_code  transfer_subinventory_code
6310          , x.transfer_locator_id         transfer_locator_id
6311         FROM (
6312        -- reservations
6313        SELECT
6314           mr.organization_id       organization_id
6315         , mr.inventory_item_id     inventory_item_id
6316         , mr.revision              revision
6317         , mr.lot_number            lot_number
6318         , mr.subinventory_code     subinventory_code
6319         , mr.locator_id            locator_id
6320         , mr.primary_reservation_quantity
6321            - Nvl(mr.detailed_quantity,0)    primary_quantity
6322         , mr.secondary_reservation_quantity
6323            - Nvl(mr.secondary_detailed_quantity,0)    secondary_quantity     -- invConv change
6324         , 3                        quantity_type
6325         , to_number(NULL)     cost_group_id
6326         , lpn_id        lpn_id
6327         , to_number(NULL)                      transaction_action_id
6328         , to_char(NULL)                        transfer_subinventory_code
6329         , to_number(NULL)                      transfer_locator_id
6330      FROM mtl_reservations mr
6331      WHERE
6332           Nvl(mr.supply_source_type_id, 13) = 13
6333       AND mr.primary_reservation_quantity >
6334        Nvl(mr.detailed_quantity,0)
6335       AND ((l_no_lpn_reservations <>1)
6336            OR (l_no_lpn_reservations = 1 AND mr.lpn_id IS NULL))
6337       AND (l_tree_mode <> 3 OR
6338           (l_tree_mode = 3
6339       AND NOT
6340              ( l_demand_source_type_id = mr.demand_source_type_id
6341             AND l_demand_source_header_id =  mr.demand_source_header_id
6342             AND Nvl(l_demand_source_line_id, -9999) =
6343       Nvl(mr.demand_source_line_id,-9999)
6344           AND Nvl(l_demand_source_name, '@@@###@@#') =
6345       Nvl(mr.demand_source_name,'@@@###@@#')
6346        AND Nvl(l_demand_source_delivery,-9999) =
6347       Nvl(mr.demand_source_delivery,-9999)
6348               )
6349    ))
6350      UNION ALL
6351        -- onhand quantities
6352        SELECT
6353           moq.organization_id               organization_id
6354         , moq.inventory_item_id             inventory_item_id
6355         , moq.revision                      revision
6356         , moq.lot_number                    lot_number
6357         , moq.subinventory_code             subinventory_code
6358         , moq.locator_id                    locator_id
6359         , moq.primary_transaction_quantity
6360         , moq.secondary_transaction_quantity                            -- invConv change
6361         , 1                                 quantity_type
6362    , moq.cost_group_id                 cost_group_id
6363    , moq.lpn_id             lpn_id
6364         , to_number(NULL)                      transaction_action_id
6365         , to_char(NULL)                        transfer_subinventory_code
6366         , to_number(NULL)                      transfer_locator_id
6367        FROM
6368           mtl_onhand_quantities_detail       moq
6369      UNION ALL
6370        -- pending transactions in mmtt, lot in MMTT
6371        SELECT
6372             mmtt.organization_id    organization_id
6373           , mmtt.inventory_item_id  inventory_item_id
6374           , mmtt.revision           revision
6375           , mmtt.lot_number         lot_number
6376           , mmtt.subinventory_code  subinventory_code
6377           , mmtt.locator_id         locator_id
6378      --Bug 4185621
6379           --, Decode(mmtt.transaction_status, 2, 1,
6380           , Decode(Decode(mmtt.transaction_status, 2, decode(nvl(mmtt.wms_task_status,-1),4,-1,2), mmtt.transaction_status), 2, 1,
6381       Decode(mmtt.transaction_action_id,1,-1,2,-1,28,-1,3,-1,
6382          Sign(mmtt.primary_quantity)))
6383          * round(Abs(mmtt.primary_quantity),5)
6384       --Bug 4185621
6385            --, Decode(mmtt.transaction_status, 2, 1,
6386            , Decode(Decode(mmtt.transaction_status, 2, decode(nvl(mmtt.wms_task_status,-1),4,-1,2), mmtt.transaction_status), 2, 1,
6387       Decode(mmtt.transaction_action_id,1,-1,2,-1,28,-1,3,-1,
6388          Sign(mmtt.secondary_transaction_quantity)))
6389          * round(Abs(mmtt.secondary_transaction_quantity),5)           -- invConv change
6390             --Bug 4185621
6391             --, Decode(mmtt.transaction_status, 2, 5, 1) quantity_type
6392             , Decode(mmtt.transaction_status, 2, decode(nvl(mmtt.wms_task_status,-1),4,1,5), 1)  quantity_type
6393           , mmtt.cost_group_id       cost_group_id
6394      ,NVL(mmtt.allocated_lpn_id,
6395       NVL(mmtt.content_lpn_id, mmtt.lpn_id)) lpn_id
6396           , Decode(mmtt.transaction_status, 2 , mmtt.transaction_action_id, to_number(NULL)) transaction_action_id
6397           , Decode(mmtt.transaction_status, 2 , mmtt.transfer_subinventory, to_char(NULL)) transfer_subinventory_code
6398           , Decode(mmtt.transaction_status, 2 , mmtt.transfer_to_location, to_number(NULL))  transfer_locator_id
6399        FROM
6400             mtl_material_transactions_temp mmtt
6401        WHERE
6402             mmtt.posting_flag = 'Y'
6403     AND mmtt.lot_number IS NOT NULL
6404     AND mmtt.subinventory_code IS NOT NULL
6405     AND (Nvl(mmtt.transaction_status,0) <> 2 OR
6406             Nvl(mmtt.transaction_status,0) = 2 AND
6407             mmtt.transaction_action_id IN (1,2,28,3,21,29,32,34)
6408         )
6409       -- dont look at scrap and costing txns
6410       -- Bug 3396558 fix. Ignore ownership xfr,planning xfr transactions
6411          AND mmtt.transaction_action_id NOT IN (5,6,24,30)
6412     UNION ALL
6413        --MMTT records, lot in MTLT
6414        SELECT
6415             mmtt.organization_id    organization_id
6416           , mmtt.inventory_item_id  inventory_item_id
6417           , mmtt.revision           revision
6418           , mtlt.lot_number         lot_number
6419           , mmtt.subinventory_code  subinventory_code
6420           , mmtt.locator_id         locator_id
6421      --Bug 4185621
6422           --, Decode(mmtt.transaction_status, 2, 1,
6423           , Decode(Decode(mmtt.transaction_status, 2, decode(nvl(mmtt.wms_task_status,-1),4,-1,2), mmtt.transaction_status), 2, 1,
6424       Decode(mmtt.transaction_action_id,1,-1,2,-1,28,-1,3,-1,
6425       Sign(mmtt.primary_quantity)))
6426        * round(Abs( mtlt.primary_quantity ),5)
6427      --Bug 4185621
6428           --, Decode(mmtt.transaction_status, 2, 1,
6429           , Decode(Decode(mmtt.transaction_status, 2, decode(nvl(mmtt.wms_task_status,-1),4,-1,2), mmtt.transaction_status), 2, 1,
6430       Decode(mmtt.transaction_action_id,1,-1,2,-1,28,-1,3,-1,
6431       Sign(mmtt.secondary_transaction_quantity)))
6432        * round(Abs( mtlt.secondary_quantity ),5)             -- invConv change
6433      --Bug 4185621
6434           --, Decode(mmtt.transaction_status, 2, 5, 1) quantity_type
6435           , Decode(mmtt.transaction_status, 2, decode(nvl(mmtt.wms_task_status,-1),4,1,5), 1)  quantity_type
6436           , mmtt.cost_group_id       cost_group_id
6437      ,NVL(mmtt.allocated_lpn_id,
6438       NVL(mmtt.content_lpn_id, mmtt.lpn_id)) lpn_id
6439           , Decode(mmtt.transaction_status, 2 , mmtt.transaction_action_id, to_number(NULL)) transaction_action_id
6440           , Decode(mmtt.transaction_status, 2 , mmtt.transfer_subinventory, to_char(NULL)) transfer_subinventory_code
6441           , Decode(mmtt.transaction_status, 2 , mmtt.transfer_to_location, to_number(NULL))  transfer_locator_id
6442        FROM
6443            mtl_material_transactions_temp mmtt,
6444       mtl_transaction_lots_temp mtlt
6445        WHERE
6446              mmtt.posting_flag = 'Y'
6447          AND mmtt.transaction_temp_id = mtlt.transaction_temp_id
6448          AND mmtt.lot_number IS NULL
6449     AND mmtt.subinventory_code IS NOT NULL
6450     AND (Nvl(mmtt.transaction_status,0) <> 2 OR
6451          Nvl(mmtt.transaction_status,0) = 2 AND
6452         mmtt.transaction_action_id IN (1,2,28,3,21,29,32,34)
6453       )
6454       -- dont look at scrap and costing txns
6455       -- Bug 3396558 fix. Ignore ownership xfr,planning xfr transactions
6456          AND mmtt.transaction_action_id NOT IN (5,6,24,30)
6457        UNION ALL
6458        -- receiving side of transfers, lot in MMTT
6459        -- Bug 7658493, If wms task is in loaded status, consider allocation like pending transaction.
6460        SELECT
6461             Decode(mmtt.transaction_action_id
6462                , 3, mmtt.transfer_organization
6463                , mmtt.organization_id)   organization_id
6464           , mmtt.inventory_item_id       inventory_item_id
6465           , mmtt.revision                revision
6466           , mmtt.lot_number              lot_number
6467           , mmtt.transfer_subinventory   subinventory_code
6468           , mmtt.transfer_to_location    locator_id
6469           , round(Abs( mmtt.primary_quantity),5)
6470           , round(Abs( mmtt.secondary_transaction_quantity),5)         -- invConv change
6471           , 1                            quantity_type
6472           , mmtt.transfer_cost_group_id  cost_group_id
6473           , NVL(mmtt.content_lpn_id,mmtt.transfer_lpn_id) lpn_id
6474           , to_number(NULL)                      transaction_action_id
6475           , to_char(NULL)                        transfer_subinventory_code
6476           , to_number(NULL)                      transfer_locator_id
6477        FROM
6478             mtl_material_transactions_temp mmtt
6479        WHERE
6480              mmtt.posting_flag = 'Y'
6481           AND mmtt.lot_number IS NOT NULL
6482           AND Decode( Nvl(mmtt.transaction_status,0),
6483                        2, decode(nvl(mmtt.wms_task_status,-1), 4, 1, 2),
6484                        1 ) <> 2
6485           AND mmtt.transaction_action_id IN (2,28,3)
6486        UNION ALL
6487        -- receiving side of transfers, lot in MTLT
6488        -- Bug 7658493, If wms task is in loaded status, consider allocation like pending transaction.
6489        SELECT
6490             Decode(mmtt.transaction_action_id
6491                , 3, mmtt.transfer_organization
6492                , mmtt.organization_id)   organization_id
6493           , mmtt.inventory_item_id       inventory_item_id
6494           , mmtt.revision                revision
6495           , mtlt.lot_number              lot_number
6496           , mmtt.transfer_subinventory   subinventory_code
6497           , mmtt.transfer_to_location    locator_id
6498           , round(Abs( mtlt.primary_quantity ),5)
6499           , round(Abs( mtlt.secondary_quantity ),5)              -- invConv change
6500           , 1                            quantity_type
6501           , mmtt.transfer_cost_group_id  cost_group_id
6502           , NVL(mmtt.content_lpn_id,mmtt.transfer_lpn_id) lpn_id
6503           , to_number(NULL)                      transaction_action_id
6504           , to_char(NULL)                        transfer_subinventory_code
6505           , to_number(NULL)                      transfer_locator_id
6506        FROM
6507             mtl_material_transactions_temp mmtt,
6508        mtl_transaction_lots_temp mtlt
6509        WHERE
6510              mmtt.posting_flag = 'Y'
6511           AND mmtt.lot_number IS NULL
6512           AND mmtt.transaction_temp_id = mtlt.transaction_temp_id
6513           AND Decode( Nvl(mmtt.transaction_status,0),
6514                        2, decode(nvl(mmtt.wms_task_status,-1), 4, 1, 2),
6515                        1 ) <> 2
6516           AND mmtt.transaction_action_id IN (2,28,3)
6517       ) x
6518       WHERE x.organization_id    = l_organization_id
6519         AND x.inventory_item_id  = l_inventory_item_id
6520       GROUP BY
6521            x.organization_id, x.inventory_item_id, x.revision
6522           , x.lot_number,x.subinventory_code, x.locator_id
6523           , x.quantity_type, x.cost_group_id, x.lpn_id
6524           , x.transaction_action_id, x.transfer_subinventory_code
6525           , x.transfer_locator_id
6526    ) x
6527     , mtl_secondary_inventories sub
6528     , mtl_lot_numbers lot
6529  WHERE
6530    x.organization_id    = sub.organization_id          (+)
6531    AND x.subinventory_code = sub.secondary_inventory_name (+)
6532    AND x.organization_id   = lot.organization_id   (+)
6533    AND x.inventory_item_id = lot.inventory_item_id (+)
6534    AND x.lot_number        = lot.lot_number        (+)
6535    AND l_grade_code = lot.grade_code                   -- invConv change
6536    AND (l_asset_subs_only = 2 OR
6537          NVL(sub.asset_inventory,1) = 1)
6538    AND ((l_onhand_source = 1 AND
6539     Nvl(sub.inventory_atp_code, 1) = 1
6540       ) OR
6541         (l_onhand_source = 2 AND
6542        Nvl(sub.availability_type, 1) = 1
6543    ) OR
6544    l_onhand_source =3
6545    OR
6546    (l_onhand_source = 4 AND
6547     Nvl(sub.inventory_atp_code, 1) = 1 AND
6548     Nvl(sub.availability_type, 1) = 1)
6549       )
6550    AND (l_lot_expiration_control = 2 OR
6551         lot.expiration_date IS NULL OR
6552         l_lot_expiration_date IS NULL OR
6553         lot.expiration_date > l_lot_expiration_date);
6554 
6555      CURSOR c_lot_grade_MMS IS
6556       SELECT
6557           x.organization_id       organization_id
6558         , x.inventory_item_id     inventory_item_id
6559         , x.revision              revision
6560         , x.lot_number       lot_number
6561         , lot.expiration_date     lot_expiration_date
6562         , x.subinventory_code     subinventory_code
6563         , sub.reservable_type     reservable_type
6564         , x.locator_id            locator_id
6565         , x.primary_quantity      primary_quantity
6566         , x.secondary_quantity    secondary_quantity       -- invConv change
6567         , x.quantity_type         quantity_type
6568         , x.cost_group_id         cost_group_id
6569         , x.lpn_id        lpn_id
6570         , x.transaction_action_id       transaction_action_id
6571         , x.transfer_subinventory_code  transfer_subinventory_code
6572         , x.transfer_locator_id         transfer_locator_id
6573         , x.status_id -- Onhand Material Status Support
6574      FROM (
6575        SELECT
6576            x.organization_id       organization_id
6577          , x.inventory_item_id     inventory_item_id
6578          , decode(l_revision_control, 2, NULL, x.revision) revision
6579          , x.lot_number            lot_number
6580          , x.subinventory_code     subinventory_code
6581          , x.locator_id            locator_id
6582          , SUM(x.primary_quantity) primary_quantity
6583          , SUM(x.secondary_quantity) secondary_quantity     -- invConv change
6584          , x.quantity_type         quantity_type
6585          , x.cost_group_id         cost_group_id
6586          , x.lpn_id        lpn_id
6587          , x.transaction_action_id       transaction_action_id
6588          , x.transfer_subinventory_code  transfer_subinventory_code
6589          , x.transfer_locator_id         transfer_locator_id
6590          , x.status_id -- Onhand Material Status Support
6591         FROM (
6592        -- reservations
6593        SELECT
6594           mr.organization_id       organization_id
6595         , mr.inventory_item_id     inventory_item_id
6596         , mr.revision              revision
6597         , mr.lot_number            lot_number
6598         , mr.subinventory_code     subinventory_code
6599         , mr.locator_id            locator_id
6600         , mr.primary_reservation_quantity
6601            - Nvl(mr.detailed_quantity,0)    primary_quantity
6602         , mr.secondary_reservation_quantity
6603            - Nvl(mr.secondary_detailed_quantity,0)    secondary_quantity     -- invConv change
6604         , 3                        quantity_type
6605         , to_number(NULL)     cost_group_id
6606         , lpn_id        lpn_id
6607         , to_number(NULL)                      transaction_action_id
6608         , to_char(NULL)                        transfer_subinventory_code
6609         , to_number(NULL)                      transfer_locator_id
6610         , to_number(NULL)                      status_id -- Onhand Material Status Support
6611      FROM mtl_reservations mr
6612      WHERE
6613           Nvl(mr.supply_source_type_id, 13) = 13
6614       AND mr.primary_reservation_quantity >
6615        Nvl(mr.detailed_quantity,0)
6616       AND ((l_no_lpn_reservations <>1)
6617            OR (l_no_lpn_reservations = 1 AND mr.lpn_id IS NULL))
6618       AND (l_tree_mode <> 3 OR
6619           (l_tree_mode = 3
6620       AND NOT
6621              ( l_demand_source_type_id = mr.demand_source_type_id
6622             AND l_demand_source_header_id =  mr.demand_source_header_id
6623             AND Nvl(l_demand_source_line_id, -9999) =
6624       Nvl(mr.demand_source_line_id,-9999)
6625           AND Nvl(l_demand_source_name, '@@@###@@#') =
6626       Nvl(mr.demand_source_name,'@@@###@@#')
6627        AND Nvl(l_demand_source_delivery,-9999) =
6628       Nvl(mr.demand_source_delivery,-9999)
6629               )
6630    ))
6631      UNION ALL
6632        -- onhand quantities
6633        SELECT
6634           moq.organization_id               organization_id
6635         , moq.inventory_item_id             inventory_item_id
6636         , moq.revision                      revision
6637         , moq.lot_number                    lot_number
6638         , moq.subinventory_code             subinventory_code
6639         , moq.locator_id                    locator_id
6640         , moq.primary_transaction_quantity
6641         , moq.secondary_transaction_quantity                            -- invConv change
6642         , 1                                 quantity_type
6643    , moq.cost_group_id                 cost_group_id
6644    , moq.lpn_id             lpn_id
6645         , to_number(NULL)                      transaction_action_id
6646         , to_char(NULL)                        transfer_subinventory_code
6647         , to_number(NULL)                      transfer_locator_id
6648         , moq.status_id                        -- Onhand Material Status Support
6649        FROM
6650           mtl_onhand_quantities_detail       moq
6651      UNION ALL
6652        -- pending transactions in mmtt, lot in MMTT
6653        SELECT
6654             mmtt.organization_id    organization_id
6655           , mmtt.inventory_item_id  inventory_item_id
6656           , mmtt.revision           revision
6657           , mmtt.lot_number         lot_number
6658           , mmtt.subinventory_code  subinventory_code
6659           , mmtt.locator_id         locator_id
6660      --Bug 4185621
6661           --, Decode(mmtt.transaction_status, 2, 1,
6662           , Decode(Decode(mmtt.transaction_status, 2, decode(nvl(mmtt.wms_task_status,-1),4,-1,2), mmtt.transaction_status), 2, 1,
6663       Decode(mmtt.transaction_action_id,1,-1,2,-1,28,-1,3,-1,
6664          Sign(mmtt.primary_quantity)))
6665          * round(Abs(mmtt.primary_quantity),5)
6666      --Bug 4185621
6667           --, Decode(mmtt.transaction_status, 2, 1,
6668           , Decode(Decode(mmtt.transaction_status, 2, decode(nvl(mmtt.wms_task_status,-1),4,-1,2), mmtt.transaction_status), 2, 1,
6669       Decode(mmtt.transaction_action_id,1,-1,2,-1,28,-1,3,-1,
6670          Sign(mmtt.secondary_transaction_quantity)))
6671          * round(Abs(mmtt.secondary_transaction_quantity),5)           -- invConv change
6672      --Bug 4185621
6673           --, Decode(mmtt.transaction_status, 2, 5, 1) quantity_type
6674           , Decode(mmtt.transaction_status, 2, decode(nvl(mmtt.wms_task_status,-1),4,1,5), 1)  quantity_type
6675           , mmtt.cost_group_id       cost_group_id
6676      ,NVL(mmtt.allocated_lpn_id,
6677       NVL(mmtt.content_lpn_id, mmtt.lpn_id)) lpn_id
6678           , Decode(mmtt.transaction_status, 2 , mmtt.transaction_action_id, to_number(NULL)) transaction_action_id
6679           , Decode(mmtt.transaction_status, 2 , mmtt.transfer_subinventory, to_char(NULL)) transfer_subinventory_code
6680           , Decode(mmtt.transaction_status, 2 , mmtt.transfer_to_location, to_number(NULL))  transfer_locator_id
6681           , inv_material_status_grp.get_default_status(mmtt.organization_id
6682                                           ,mmtt.inventory_item_id
6683                                           ,mmtt.subinventory_code
6684                                           ,mmtt.locator_id
6685                                           ,mmtt.lot_number -- lot_number
6686                                           ,NVL(mmtt.allocated_lpn_id,
6687                                  NVL(mmtt.content_lpn_id, mmtt.lpn_id))
6688                                           ) status_id -- Onhand Material Status Support
6689        FROM
6690             mtl_material_transactions_temp mmtt
6691        WHERE
6692             mmtt.posting_flag = 'Y'
6693     AND mmtt.lot_number IS NOT NULL
6694     AND mmtt.subinventory_code IS NOT NULL
6695     AND (Nvl(mmtt.transaction_status,0) <> 2 OR
6696             Nvl(mmtt.transaction_status,0) = 2 AND
6697             mmtt.transaction_action_id IN (1,2,28,3,21,29,32,34)
6698         )
6699       -- dont look at scrap and costing txns
6700       -- Bug 3396558 fix. Ignore ownership xfr,planning xfr transactions
6701          AND mmtt.transaction_action_id NOT IN (5,6,24,30)
6702     UNION ALL
6703        --MMTT records, lot in MTLT
6704        SELECT
6705             mmtt.organization_id    organization_id
6706           , mmtt.inventory_item_id  inventory_item_id
6707           , mmtt.revision           revision
6708           , mtlt.lot_number         lot_number
6709           , mmtt.subinventory_code  subinventory_code
6710           , mmtt.locator_id         locator_id
6711      --Bug 4185621
6712           --, Decode(mmtt.transaction_status, 2, 1,
6713           , Decode(Decode(mmtt.transaction_status, 2, decode(nvl(mmtt.wms_task_status,-1),4,-1,2), mmtt.transaction_status), 2, 1,
6714       Decode(mmtt.transaction_action_id,1,-1,2,-1,28,-1,3,-1,
6715       Sign(mmtt.primary_quantity)))
6716        * round(Abs( mtlt.primary_quantity ),5)
6717      --Bug 4185621
6718           --, Decode(mmtt.transaction_status, 2, 1,
6719           , Decode(Decode(mmtt.transaction_status, 2, decode(nvl(mmtt.wms_task_status,-1),4,-1,2), mmtt.transaction_status), 2, 1,
6720       Decode(mmtt.transaction_action_id,1,-1,2,-1,28,-1,3,-1,
6721       Sign(mmtt.secondary_transaction_quantity)))
6722        * round(Abs( mtlt.secondary_quantity ),5)             -- invConv change
6723      --Bug 4185621
6724           --, Decode(mmtt.transaction_status, 2, 5, 1) quantity_type
6725           , Decode(mmtt.transaction_status, 2, decode(nvl(mmtt.wms_task_status,-1),4,1,5), 1)  quantity_type
6726           , mmtt.cost_group_id       cost_group_id
6727      ,NVL(mmtt.allocated_lpn_id,
6728       NVL(mmtt.content_lpn_id, mmtt.lpn_id)) lpn_id
6729           , Decode(mmtt.transaction_status, 2 , mmtt.transaction_action_id, to_number(NULL)) transaction_action_id
6730           , Decode(mmtt.transaction_status, 2 , mmtt.transfer_subinventory, to_char(NULL)) transfer_subinventory_code
6731           , Decode(mmtt.transaction_status, 2 , mmtt.transfer_to_location, to_number(NULL))  transfer_locator_id
6732           , inv_material_status_grp.get_default_status(mmtt.organization_id
6733                                           ,mmtt.inventory_item_id
6734                                           ,mmtt.subinventory_code
6735                                           ,mmtt.locator_id
6736                                           ,mtlt.lot_number -- lot_number in MTLT
6737                                           ,NVL(mmtt.allocated_lpn_id,
6738                                  NVL(mmtt.content_lpn_id, mmtt.lpn_id))
6739                                           ) status_id -- Onhand Material Status Support
6740        FROM
6741            mtl_material_transactions_temp mmtt,
6742       mtl_transaction_lots_temp mtlt
6743        WHERE
6744              mmtt.posting_flag = 'Y'
6745          AND mmtt.transaction_temp_id = mtlt.transaction_temp_id
6746          AND mmtt.lot_number IS NULL
6747     AND mmtt.subinventory_code IS NOT NULL
6748     AND (Nvl(mmtt.transaction_status,0) <> 2 OR
6749          Nvl(mmtt.transaction_status,0) = 2 AND
6750         mmtt.transaction_action_id IN (1,2,28,3,21,29,32,34)
6751       )
6752       -- dont look at scrap and costing txns
6753       -- Bug 3396558 fix. Ignore ownership xfr,planning xfr transactions
6754          AND mmtt.transaction_action_id NOT IN (5,6,24,30)
6755        UNION ALL
6756        -- receiving side of transfers, lot in MMTT
6757        -- Bug 7658493, If wms task is in loaded status, consider allocation like pending transaction.
6758        SELECT
6759             Decode(mmtt.transaction_action_id
6760                , 3, mmtt.transfer_organization
6761                , mmtt.organization_id)   organization_id
6762           , mmtt.inventory_item_id       inventory_item_id
6763           , mmtt.revision                revision
6764           , mmtt.lot_number              lot_number
6765           , mmtt.transfer_subinventory   subinventory_code
6766           , mmtt.transfer_to_location    locator_id
6767           , round(Abs( mmtt.primary_quantity),5)
6768           , round(Abs( mmtt.secondary_transaction_quantity),5)         -- invConv change
6769           , 1                            quantity_type
6770           , mmtt.transfer_cost_group_id  cost_group_id
6771           , NVL(mmtt.content_lpn_id,mmtt.transfer_lpn_id) lpn_id
6772           , to_number(NULL)                      transaction_action_id
6773           , to_char(NULL)                        transfer_subinventory_code
6774           , to_number(NULL)                      transfer_locator_id
6775           , inv_material_status_grp.get_default_status(Decode(mmtt.transaction_action_id
6776                                                , 3, mmtt.transfer_organization
6777                                                , mmtt.organization_id)
6778                                           ,mmtt.inventory_item_id
6779                                           ,mmtt.transfer_subinventory
6780                                           ,mmtt.transfer_to_location
6781                                           ,mmtt.lot_number -- lot_number
6782                                           ,NVL(mmtt.content_lpn_id,mmtt.transfer_lpn_id)
6783                                           ,mmtt.transaction_action_id
6784                                           ,inv_material_status_grp.get_default_status(mmtt.organization_id
6785                                                   ,mmtt.inventory_item_id
6786                                                   ,mmtt.subinventory_code
6787                                                   ,mmtt.locator_id
6788                                                   ,mmtt.lot_number -- lot_number
6789                                                   ,NVL(mmtt.allocated_lpn_id,
6790                                         NVL(mmtt.content_lpn_id, mmtt.lpn_id))
6791                                                   )
6792                                           ) status_id -- Onhand Material Status Support
6793        FROM
6794             mtl_material_transactions_temp mmtt
6795        WHERE
6796              mmtt.posting_flag = 'Y'
6797           AND mmtt.lot_number IS NOT NULL
6798           AND Decode( Nvl(mmtt.transaction_status,0),
6799                        2, decode(nvl(mmtt.wms_task_status,-1), 4, 1, 2),
6800                        1 ) <> 2
6801           AND mmtt.transaction_action_id IN (2,28,3)
6802         UNION ALL
6803        -- receiving side of transfers, lot in MTLT
6804        -- Bug 7658493, If wms task is in loaded status, consider allocation like pending transaction.
6805        SELECT
6806             Decode(mmtt.transaction_action_id
6807                , 3, mmtt.transfer_organization
6808                , mmtt.organization_id)   organization_id
6809           , mmtt.inventory_item_id       inventory_item_id
6810           , mmtt.revision                revision
6811           , mtlt.lot_number              lot_number
6812           , mmtt.transfer_subinventory   subinventory_code
6813           , mmtt.transfer_to_location    locator_id
6814           , round(Abs( mtlt.primary_quantity ),5)
6815           , round(Abs( mtlt.secondary_quantity ),5)              -- invConv change
6816           , 1                            quantity_type
6817           , mmtt.transfer_cost_group_id  cost_group_id
6818           , NVL(mmtt.content_lpn_id,mmtt.transfer_lpn_id) lpn_id
6819           , to_number(NULL)                      transaction_action_id
6820           , to_char(NULL)                        transfer_subinventory_code
6821           , to_number(NULL)                      transfer_locator_id
6822           , inv_material_status_grp.get_default_status(Decode(mmtt.transaction_action_id
6823                                                , 3, mmtt.transfer_organization
6824                                                , mmtt.organization_id)
6825                                           ,mmtt.inventory_item_id
6826                                           ,mmtt.transfer_subinventory
6827                                           ,mmtt.transfer_to_location
6828                                           ,mtlt.lot_number -- lot_number
6829                                           ,NVL(mmtt.content_lpn_id,mmtt.transfer_lpn_id)
6830                                           ,mmtt.transaction_action_id
6831                                           ,inv_material_status_grp.get_default_status(mmtt.organization_id
6832                                                   ,mmtt.inventory_item_id
6833                                                   ,mmtt.subinventory_code
6834                                                   ,mmtt.locator_id
6835                                                   ,mtlt.lot_number -- lot_number
6836                                                   ,NVL(mmtt.allocated_lpn_id,
6837                                         NVL(mmtt.content_lpn_id, mmtt.lpn_id))
6838                                                   )
6839                                           ) status_id -- Onhand Material Status Support
6840        FROM
6841             mtl_material_transactions_temp mmtt,
6842        mtl_transaction_lots_temp mtlt
6843        WHERE
6844              mmtt.posting_flag = 'Y'
6845           AND mmtt.lot_number IS NULL
6846           AND mmtt.transaction_temp_id = mtlt.transaction_temp_id
6847           AND Decode( Nvl(mmtt.transaction_status,0),
6848                        2, decode(nvl(mmtt.wms_task_status,-1), 4, 1, 2),
6849                        1 ) <> 2
6850           AND mmtt.transaction_action_id IN (2,28,3)
6851       ) x
6852       WHERE x.organization_id    = l_organization_id
6853         AND x.inventory_item_id  = l_inventory_item_id
6854       GROUP BY
6855            x.organization_id, x.inventory_item_id, x.revision
6856           , x.lot_number,x.subinventory_code, x.locator_id
6857           , x.quantity_type, x.cost_group_id, x.lpn_id
6858           , x.transaction_action_id, x.transfer_subinventory_code
6859           , x.transfer_locator_id, x.status_id -- Onhand Material Status Support
6860    ) x
6861     , mtl_secondary_inventories sub
6862     , mtl_item_locations loc                                      -- invConv change
6863     , mtl_lot_numbers lot
6864     , mtl_parameters mp -- Onhand Material Status Support
6865     , mtl_material_statuses_b mms -- Onhand Material Status Support
6866  WHERE
6867        x.inventory_item_id = lot.inventory_item_id        (+)     -- invConv change
6868    AND x.organization_id = lot.organization_id            (+)     -- invConv change
6869    AND x.lot_number = lot.lot_number                      (+)     -- invConv change
6870    AND x.organization_id = loc.organization_id            (+)     -- invConv change
6871    AND x.locator_id = loc.inventory_location_id           (+)     -- invConv change
6872    AND x.organization_id    = sub.organization_id         (+)
6873    AND x.subinventory_code = sub.secondary_inventory_name (+)
6874    AND x.organization_id   = lot.organization_id   (+)
6875    AND x.inventory_item_id = lot.inventory_item_id (+)
6876    AND x.lot_number        = lot.lot_number        (+)
6877    AND x.organization_id    = mp.organization_id   (+) -- Onhand Material Status Support
6878    AND x.status_id = mms.status_id                 (+) -- Onhand Material Status Support
6879    AND l_grade_code = lot.grade_code                   -- invConv change
6880    AND (l_asset_subs_only = 2 OR
6881          NVL(sub.asset_inventory,1) = 1)
6882    AND
6883    (
6884      (mp.default_status_id is null and
6885        ((l_onhand_source = 1 AND
6886                  Nvl(sub.inventory_atp_code, 1) = 1
6887              AND Nvl(loc.inventory_atp_code, 1) = 1                  -- invConv change
6888              AND Nvl(lot.inventory_atp_code, 1) = 1                  -- invConv change
6889       ) OR
6890         (l_onhand_source = 2 AND
6891        Nvl(sub.availability_type, 1) = 1
6892              AND Nvl(loc.availability_type, 1) = 1                   -- invConv change
6893              AND Nvl(lot.availability_type, 1) = 1                   -- invConv change
6894    ) OR
6895    l_onhand_source =3
6896    OR
6897    (l_onhand_source = 4 AND
6898               Nvl(sub.inventory_atp_code, 1) = 1
6899           AND Nvl(loc.inventory_atp_code, 1) = 1                  -- invConv change
6900           AND Nvl(lot.inventory_atp_code, 1) = 1                  -- invConv change
6901           AND Nvl(loc.availability_type, 1) = 1                   -- invConv change
6902           AND Nvl(lot.availability_type, 1) = 1                   -- invConv change
6903           AND Nvl(sub.availability_type, 1) = 1)
6904       )
6905      )
6906      OR -- Onhand Material Status Support
6907      (
6908        mp.default_status_id is not null and
6909            ((l_onhand_source =1 AND
6910                Nvl(mms.inventory_atp_code, 1) = 1
6911              )
6912           OR (l_onhand_source = 2 AND
6913          Nvl(mms.availability_type, 1) = 1
6914         )
6915      OR l_onhand_source =3
6916           OR (l_onhand_source = 4 AND
6917          (nvl(mms.inventory_atp_code,1) = 1
6918          AND nvl(mms.availability_type,1)=1
6919               )
6920              )
6921            )
6922      )
6923    )
6924    AND (l_lot_expiration_control = 2 OR
6925         lot.expiration_date IS NULL OR
6926         l_lot_expiration_date IS NULL OR
6927         lot.expiration_date > l_lot_expiration_date);
6928      -- invConv changes end : c_lot_grade with MMS about ATP/Nettable...
6929 
6930      CURSOR c_unit IS
6931      SELECT
6932           x.organization_id       organization_id
6933         , x.inventory_item_id     inventory_item_id
6934         , x.revision              revision
6935    , NULL           lot_number
6936         , NULL         lot_expiration_date
6937         , x.subinventory_code     subinventory_code
6938         , sub.reservable_type     reservable_type
6939         , x.locator_id            locator_id
6940         , x.primary_quantity      primary_quantity
6941         , x.secondary_quantity    secondary_quantity          -- invConv change
6942         , x.quantity_type         quantity_type
6943         , x.cost_group_id         cost_group_id
6944         , x.lpn_id        lpn_id
6945         , x.transaction_action_id       transaction_action_id
6946         , x.transfer_subinventory_code  transfer_subinventory_code
6947         , x.transfer_locator_id         transfer_locator_id
6948      FROM (
6949        SELECT
6950            x.organization_id       organization_id
6951          , x.inventory_item_id     inventory_item_id
6952          , decode(l_revision_control, 2, NULL
6953       , x.revision)       revision
6954          , NULL                      lot_number
6955          , x.subinventory_code     subinventory_code
6956          , x.locator_id            locator_id
6957          , SUM(x.primary_quantity) primary_quantity
6958          , SUM(x.secondary_quantity) secondary_quantity        -- invConv change
6959          , x.quantity_type         quantity_type
6960          , x.cost_group_id         cost_group_id
6961          , x.lpn_id        lpn_id
6962          , x.transaction_action_id       transaction_action_id
6963          , x.transfer_subinventory_code  transfer_subinventory_code
6964          , x.transfer_locator_id         transfer_locator_id
6965         FROM (
6966        -- reservations
6967        SELECT
6968           mr.organization_id       organization_id
6969         , mr.inventory_item_id     inventory_item_id
6970         , mr.revision              revision
6971         , mr.lot_number            lot_number
6972         , mr.subinventory_code     subinventory_code
6973         , mr.locator_id            locator_id
6974         , mr.primary_reservation_quantity
6975            - Nvl(mr.detailed_quantity,0)    primary_quantity
6976         , mr.secondary_reservation_quantity
6977            - Nvl(mr.secondary_detailed_quantity,0)    secondary_quantity       -- invConv change
6978         , 3                        quantity_type
6979         , to_number(NULL)     cost_group_id
6980       , lpn_id       lpn_id
6981         , to_number(NULL)                      transaction_action_id
6982         , to_char(NULL)                        transfer_subinventory_code
6983         , to_number(NULL)                      transfer_locator_id
6984      FROM mtl_reservations mr
6985      WHERE
6986           Nvl(mr.supply_source_type_id, 13) = 13
6987       AND mr.primary_reservation_quantity > Nvl(mr.detailed_quantity,0)
6988       AND ((l_no_lpn_reservations <>1)
6989            OR (l_no_lpn_reservations = 1 AND mr.lpn_id IS NULL))
6990       AND (l_tree_mode <> 3 OR
6991           (l_tree_mode = 3
6992       AND NOT (l_demand_source_type_id = mr.demand_source_type_id
6993                AND  l_demand_source_header_id = mr.demand_source_header_id
6994                AND  Nvl(l_demand_source_line_id, -9999) =
6995          Nvl(mr.demand_source_line_id,-9999)
6996                AND  Nvl(l_demand_source_name, '@@@###@@#') =
6997          Nvl(mr.demand_source_name,'@@@###@@#')
6998           AND Nvl(l_demand_source_delivery,-9999) =
6999          Nvl(mr.demand_source_delivery,-9999)
7000       )
7001           ))
7002      UNION ALL
7003        -- onhand quantities
7004        SELECT
7005           moq.organization_id               organization_id
7006         , moq.inventory_item_id             inventory_item_id
7007         , moq.revision                      revision
7008         , moq.lot_number                    lot_number
7009         , moq.subinventory_code             subinventory_code
7010         , moq.locator_id                    locator_id
7011         , decode(l_demand_source_line_id,
7012       NULL, sum(moq.primary_transaction_quantity),
7013            pjm_ueff_onhand.onhand_quantity(
7014          l_demand_source_line_id
7015          ,moq.inventory_item_id
7016          ,moq.organization_id
7017          ,moq.revision
7018          ,moq.subinventory_code
7019          ,moq.locator_id
7020          ,moq.lot_number
7021          ,moq.lpn_id
7022          ,moq.cost_group_id)
7023           )
7024         , decode(l_demand_source_line_id,
7025       NULL, sum(moq.secondary_transaction_quantity),
7026            pjm_ueff_onhand.onhand_quantity(
7027          l_demand_source_line_id
7028          ,moq.inventory_item_id
7029          ,moq.organization_id
7030          ,moq.revision
7031          ,moq.subinventory_code
7032          ,moq.locator_id
7033          ,moq.lot_number
7034          ,moq.lpn_id
7035          ,moq.cost_group_id)
7036           )                                                         -- invConv change
7037         , 1                                 quantity_type
7038    , moq.cost_group_id                 cost_group_id
7039    , moq.lpn_id             lpn_id
7040         , to_number(NULL)                      transaction_action_id
7041         , to_char(NULL)                        transfer_subinventory_code
7042         , to_number(NULL)                      transfer_locator_id
7043        FROM
7044           mtl_onhand_quantities_detail       moq
7045        GROUP BY moq.organization_id,moq.inventory_item_id,moq.revision,
7046            moq.subinventory_code,moq.locator_id,moq.lot_number,
7047            moq.lpn_id,moq.cost_group_id
7048      UNION ALL
7049        -- pending transactions in mmtt
7050        SELECT
7051             mmtt.organization_id    organization_id
7052           , mmtt.inventory_item_id  inventory_item_id
7053           , mmtt.revision           revision
7054           , NULL                 lot_number
7055           , mmtt.subinventory_code  subinventory_code
7056           , mmtt.locator_id         locator_id
7057      --Bug 4185621
7058           --, Decode(mmtt.transaction_status, 2, 1,
7059           , Decode(Decode(mmtt.transaction_status, 2, decode(nvl(mmtt.wms_task_status,-1),4,-1,2), mmtt.transaction_status), 2, 1,
7060       Decode(mmtt.transaction_action_id,1,-1,2,-1,28,-1,3,-1,
7061              Sign(mmtt.primary_quantity))) *
7062            round(Abs(decode(l_demand_source_line_id,
7063                   NULL, mmtt.primary_quantity,
7064          Nvl(pjm_ueff_onhand.txn_quantity(
7065                 l_demand_source_line_id
7066             ,mmtt.transaction_temp_id
7067             ,mmtt.lot_number
7068                   ,'Y'
7069             ,mmtt.inventory_item_id
7070             ,mmtt.organization_id
7071             ,mmtt.transaction_source_type_id
7072             ,mmtt.transaction_source_id
7073             ,mmtt.rcv_transaction_id
7074                ,sign(mmtt.primary_quantity)
7075                   ),mmtt.primary_quantity
7076             )
7077       )),5)
7078      --Bug 4185621
7079           --, Decode(mmtt.transaction_status, 2, 1,
7080           , Decode(Decode(mmtt.transaction_status, 2, decode(nvl(mmtt.wms_task_status,-1),4,-1,2), mmtt.transaction_status), 2, 1,
7081       Decode(mmtt.transaction_action_id,1,-1,2,-1,28,-1,3,-1,
7082              Sign(mmtt.secondary_transaction_quantity))) *
7083            round(Abs(decode(l_demand_source_line_id,
7084                   NULL, mmtt.secondary_transaction_quantity,
7085          Nvl(pjm_ueff_onhand.txn_quantity(
7086                 l_demand_source_line_id
7087             ,mmtt.transaction_temp_id
7088             ,mmtt.lot_number
7089                   ,'Y'
7090             ,mmtt.inventory_item_id
7091             ,mmtt.organization_id
7092             ,mmtt.transaction_source_type_id
7093             ,mmtt.transaction_source_id
7094             ,mmtt.rcv_transaction_id
7095                ,sign(mmtt.secondary_transaction_quantity)
7096                   ),mmtt.secondary_transaction_quantity
7097             )
7098       )),5)                                                          -- invConv change
7099      --Bug 4185621
7100           --, Decode(mmtt.transaction_status, 2, 5, 1) quantity_type
7101           , Decode(mmtt.transaction_status, 2, decode(nvl(mmtt.wms_task_status,-1),4,1,5), 1)  quantity_type
7102           , mmtt.cost_group_id       cost_group_id
7103      ,NVL(mmtt.allocated_lpn_id,
7104       NVL(mmtt.content_lpn_id, mmtt.lpn_id)) lpn_id
7105           , Decode(mmtt.transaction_status, 2 , mmtt.transaction_action_id, to_number(NULL)) transaction_action_id
7106           , Decode(mmtt.transaction_status, 2 , mmtt.transfer_subinventory, to_char(NULL)) transfer_subinventory_code
7107           , Decode(mmtt.transaction_status, 2 , mmtt.transfer_to_location, to_number(NULL))  transfer_locator_id
7108        FROM
7109             mtl_material_transactions_temp mmtt
7110        WHERE
7111              mmtt.posting_flag = 'Y'
7112     AND mmtt.subinventory_code IS NOT NULL
7113     AND (Nvl(mmtt.transaction_status,0) <> 2 OR
7114          Nvl(mmtt.transaction_status,0) = 2 AND
7115          mmtt.transaction_action_id IN (1,2,28,3,21,29,32,34)
7116         )
7117       -- dont look at scrap and costing txns
7118       -- Bug 3396558 fix. Ignore ownership xfr,planning xfr transactions
7119          AND mmtt.transaction_action_id NOT IN (5,6, 24,30)
7120        UNION ALL
7121        -- receiving side of transfers
7122        -- added 5/23/00
7123        -- if quantity is in an lpn, then it is containerized
7124        -- Bug 7658493, If wms task is in loaded status, consider allocation like pending transaction.
7125        SELECT
7126             Decode(mmtt.transaction_action_id
7127                , 3, mmtt.transfer_organization
7128                , mmtt.organization_id)   organization_id
7129           , mmtt.inventory_item_id       inventory_item_id
7130           , mmtt.revision                revision
7131           , NULL                         lot_number
7132           , mmtt.transfer_subinventory   subinventory_code
7133           , mmtt.transfer_to_location    locator_id
7134      , round(Abs(decode(l_demand_source_line_id,
7135             NULL, mmtt.primary_quantity,
7136             Nvl(pjm_ueff_onhand.txn_quantity(
7137                    l_demand_source_line_id
7138                ,mmtt.transaction_temp_id
7139                ,mmtt.lot_number
7140                   ,'Y'
7141                ,mmtt.inventory_item_id
7142                ,mmtt.organization_id
7143                ,mmtt.transaction_source_type_id
7144                ,mmtt.transaction_source_id
7145                ,mmtt.rcv_transaction_id
7146                   ,sign(mmtt.primary_quantity)
7147                      ),mmtt.primary_quantity
7148             )
7149       )),5)
7150      , round(Abs(decode(l_demand_source_line_id,
7151             NULL, mmtt.secondary_transaction_quantity,
7152             Nvl(pjm_ueff_onhand.txn_quantity(
7153                    l_demand_source_line_id
7154                ,mmtt.transaction_temp_id
7155                ,mmtt.lot_number
7156                   ,'Y'
7157                ,mmtt.inventory_item_id
7158                ,mmtt.organization_id
7159                ,mmtt.transaction_source_type_id
7160                ,mmtt.transaction_source_id
7161                ,mmtt.rcv_transaction_id
7162                   ,sign(mmtt.secondary_transaction_quantity)
7163                      ),mmtt.secondary_transaction_quantity
7164             )
7165       )),5)                                                       -- invConv change
7166           , 1                            quantity_type
7167           , mmtt.transfer_cost_group_id  cost_group_id
7168           , NVL(mmtt.content_lpn_id,mmtt.transfer_lpn_id) lpn_id
7169           , to_number(NULL)                      transaction_action_id
7170           , to_char(NULL)                        transfer_subinventory_code
7171           , to_number(NULL)                      transfer_locator_id
7172        FROM
7173             mtl_material_transactions_temp mmtt
7174        WHERE
7175              mmtt.posting_flag = 'Y'
7176           AND Decode( Nvl(mmtt.transaction_status,0),
7177                        2, decode(nvl(mmtt.wms_task_status,-1), 4, 1, 2),
7178                        1 ) <> 2
7179           AND mmtt.transaction_action_id IN (2,28,3)
7180       ) x
7181       WHERE x.organization_id    = l_organization_id
7182         AND x.inventory_item_id  = l_inventory_item_id
7183       GROUP BY
7184            x.organization_id, x.inventory_item_id, x.revision
7185           , x.lot_number, x.subinventory_code, x.locator_id
7186           , x.quantity_type, x.cost_group_id, x.lpn_id
7187           , x.transaction_action_id, x.transfer_subinventory_code
7188           , x.transfer_locator_id
7189    ) x
7190     , mtl_secondary_inventories sub
7191  WHERE
7192    x.organization_id    = sub.organization_id          (+)
7193    AND x.subinventory_code = sub.secondary_inventory_name (+)
7194    AND (l_asset_subs_only = 2 OR
7195          NVL(sub.asset_inventory,1) = 1)
7196    AND ((l_onhand_source = 1 AND
7197    Nvl(sub.inventory_atp_code, 1) = 1
7198         ) OR
7199         (l_onhand_source = 2 AND
7200        Nvl(sub.availability_type, 1) = 1
7201    ) OR
7202     l_onhand_source =3
7203    OR
7204    (l_onhand_source = 4 AND
7205     Nvl(sub.inventory_atp_code, 1) = 1 AND
7206      Nvl(sub.availability_type, 1) = 1)
7207       );
7208 
7209   --Lot Controlled and Unit Effective
7210   -- invConv change : grade_code filter is in cursor c_lot_unit_grade.
7211   -- invConv : no change here... see c_lot_unit_grade
7212   CURSOR c_lot_unit IS
7213    SELECT
7214           x.organization_id       organization_id
7215         , x.inventory_item_id     inventory_item_id
7216         , x.revision              revision
7217         , x.lot_number       lot_number
7218         , lot.expiration_date     lot_expiration_date
7219         , x.subinventory_code     subinventory_code
7220         , sub.reservable_type     reservable_type
7221         , x.locator_id            locator_id
7222         , x.primary_quantity      primary_quantity
7223         , x.secondary_quantity    secondary_quantity        -- invConv change
7224         , x.quantity_type         quantity_type
7225         , x.cost_group_id         cost_group_id
7226         , x.lpn_id        lpn_id
7227         , x.transaction_action_id       transaction_action_id
7228         , x.transfer_subinventory_code  transfer_subinventory_code
7229         , x.transfer_locator_id         transfer_locator_id
7230      FROM (
7231        SELECT
7232            x.organization_id       organization_id
7233          , x.inventory_item_id     inventory_item_id
7234          , decode(l_revision_control, 2, NULL
7235          , x.revision)       revision
7236          , x.lot_number             lot_number
7237          , x.subinventory_code     subinventory_code
7238          , x.locator_id            locator_id
7239          , SUM(x.primary_quantity) primary_quantity
7240          , SUM(x.secondary_quantity) secondary_quantity        -- invConv change
7241          , x.quantity_type         quantity_type
7242          , x.cost_group_id         cost_group_id
7243          , x.lpn_id        lpn_id
7244          , x.transaction_action_id       transaction_action_id
7245          , x.transfer_subinventory_code  transfer_subinventory_code
7246          , x.transfer_locator_id         transfer_locator_id
7247         FROM (
7248        -- reservations
7249        SELECT
7250           mr.organization_id       organization_id
7251         , mr.inventory_item_id     inventory_item_id
7252         , mr.revision              revision
7253         , mr.lot_number            lot_number
7254         , mr.subinventory_code     subinventory_code
7255         , mr.locator_id            locator_id
7256         , mr.primary_reservation_quantity
7257            - Nvl(mr.detailed_quantity,0)    primary_quantity
7258         , mr.secondary_reservation_quantity
7259            - Nvl(mr.secondary_detailed_quantity,0)    secondary_quantity        -- invConv change
7260         , 3                        quantity_type
7261         , to_number(NULL)       cost_group_id
7262         , lpn_id        lpn_id
7263         , to_number(NULL)                      transaction_action_id
7264         , to_char(NULL)                        transfer_subinventory_code
7265         , to_number(NULL)                      transfer_locator_id
7266      FROM mtl_reservations mr
7267      WHERE
7268           Nvl(mr.supply_source_type_id, 13) = 13
7269       AND mr.primary_reservation_quantity >
7270       Nvl(mr.detailed_quantity,0)
7271       AND ((l_no_lpn_reservations <>1)
7272            OR (l_no_lpn_reservations = 1 AND mr.lpn_id IS NULL))
7273       AND (l_tree_mode <> 3 OR
7274           (l_tree_mode = 3
7275       AND NOT (l_demand_source_type_id = mr.demand_source_type_id
7276          AND l_demand_source_header_id = mr.demand_source_header_id
7277          AND Nvl(l_demand_source_line_id, -9999) =
7278          Nvl(mr.demand_source_line_id,-9999)
7279          AND Nvl(l_demand_source_name, '@@@###@@#') =
7280          Nvl(mr.demand_source_name,'@@@###@@#')
7281       AND Nvl(l_demand_source_delivery,-9999) =
7282          Nvl(mr.demand_source_delivery,-9999)
7283               )
7284      ))
7285      UNION ALL
7286        -- onhand quantities
7287        SELECT
7288           moq.organization_id               organization_id
7289         , moq.inventory_item_id             inventory_item_id
7290         , moq.revision                      revision
7291         , moq.lot_number                    lot_number
7292         , moq.subinventory_code             subinventory_code
7293         , moq.locator_id                    locator_id
7294         , decode(l_demand_source_line_id,
7295          NULL, sum(moq.primary_transaction_quantity),
7296          pjm_ueff_onhand.onhand_quantity(
7297              l_demand_source_line_id
7298             ,moq.inventory_item_id
7299             ,moq.organization_id
7300             ,moq.revision
7301             ,moq.subinventory_code
7302             ,moq.locator_id
7303             ,moq.lot_number
7304             ,moq.lpn_id
7305             ,moq.cost_group_id)
7306           )
7307         , decode(l_demand_source_line_id,
7308          NULL, sum(moq.secondary_transaction_quantity),
7309          pjm_ueff_onhand.onhand_quantity(
7310              l_demand_source_line_id
7311             ,moq.inventory_item_id
7312             ,moq.organization_id
7313             ,moq.revision
7314             ,moq.subinventory_code
7315             ,moq.locator_id
7316             ,moq.lot_number
7317             ,moq.lpn_id
7318             ,moq.cost_group_id)
7319           )
7320         , 1                                 quantity_type
7321    , moq.cost_group_id                 cost_group_id
7322         , moq.lpn_id           lpn_id
7323         , to_number(NULL)                      transaction_action_id
7324         , to_char(NULL)                        transfer_subinventory_code
7325         , to_number(NULL)                      transfer_locator_id
7326        FROM
7327           mtl_onhand_quantities_detail moq
7328        GROUP BY moq.organization_id,moq.inventory_item_id,moq.revision,
7329            moq.subinventory_code,moq.locator_id,moq.lot_number,
7330            moq.lpn_id,moq.cost_group_id
7331      UNION ALL
7332        -- pending transactions in mmtt, lot in MMTT
7333        SELECT
7334             mmtt.organization_id    organization_id
7335           , mmtt.inventory_item_id  inventory_item_id
7336           , mmtt.revision           revision
7337           , mmtt.lot_number         lot_number
7338           , mmtt.subinventory_code  subinventory_code
7339           , mmtt.locator_id         locator_id
7340      --Bug 4185621
7341           --, Decode(mmtt.transaction_status, 2, 1,
7342           , Decode(Decode(mmtt.transaction_status, 2, decode(nvl(mmtt.wms_task_status,-1),4,-1,2), mmtt.transaction_status), 2, 1,
7343       Decode(mmtt.transaction_action_id,1,-1,2,-1,28,-1,3,-1,
7344          Sign(mmtt.primary_quantity))) *
7345       round(Abs(decode(l_demand_source_line_id,
7346          NULL, mmtt.primary_quantity,
7347          Nvl(pjm_ueff_onhand.txn_quantity(
7348                 l_demand_source_line_id
7349             ,mmtt.transaction_temp_id
7350             ,mmtt.lot_number
7351                   ,'Y'
7352             ,mmtt.inventory_item_id
7353             ,mmtt.organization_id
7354             ,mmtt.transaction_source_type_id
7355             ,mmtt.transaction_source_id
7356             ,mmtt.rcv_transaction_id
7357                ,sign(mmtt.primary_quantity)
7358                ),mmtt.primary_quantity
7359          )
7360       )),5)
7361      --Bug 4185621
7362           --, Decode(mmtt.transaction_status, 2, 1,
7363           , Decode(Decode(mmtt.transaction_status, 2, decode(nvl(mmtt.wms_task_status,-1),4,-1,2), mmtt.transaction_status), 2, 1,
7364       Decode(mmtt.transaction_action_id,1,-1,2,-1,28,-1,3,-1,
7365          Sign(mmtt.secondary_transaction_quantity))) *
7366       round(Abs(decode(l_demand_source_line_id,
7367          NULL, mmtt.secondary_transaction_quantity,
7368          Nvl(pjm_ueff_onhand.txn_quantity(
7369                 l_demand_source_line_id
7370             ,mmtt.transaction_temp_id
7371             ,mmtt.lot_number
7372                   ,'Y'
7373             ,mmtt.inventory_item_id
7374             ,mmtt.organization_id
7375             ,mmtt.transaction_source_type_id
7376             ,mmtt.transaction_source_id
7377             ,mmtt.rcv_transaction_id
7378                ,sign(mmtt.secondary_transaction_quantity)
7379                ),mmtt.secondary_transaction_quantity
7380          )
7381       )),5)                                              -- invConv change
7382    --Bug 4185621
7383         --, Decode(mmtt.transaction_status, 2, 5, 1) quantity_type
7384         , Decode(mmtt.transaction_status, 2, decode(nvl(mmtt.wms_task_status,-1),4,1,5), 1)  quantity_type
7385         , mmtt.cost_group_id      cost_group_id
7386    ,NVL(mmtt.allocated_lpn_id,
7387       NVL(mmtt.content_lpn_id, mmtt.lpn_id)) lpn_id
7388           , Decode(mmtt.transaction_status, 2 , mmtt.transaction_action_id, to_number(NULL)) transaction_action_id
7389           , Decode(mmtt.transaction_status, 2 , mmtt.transfer_subinventory, to_char(NULL)) transfer_subinventory_code
7390           , Decode(mmtt.transaction_status, 2 , mmtt.transfer_to_location, to_number(NULL))  transfer_locator_id
7391        FROM
7392             mtl_material_transactions_temp mmtt
7393        WHERE
7394             mmtt.posting_flag = 'Y'
7395     AND mmtt.lot_number IS NOT NULL
7396     AND mmtt.subinventory_code IS NOT NULL
7397     AND (Nvl(mmtt.transaction_status,0) <> 2 OR
7398             Nvl(mmtt.transaction_status,0) = 2 AND
7399          mmtt.transaction_action_id IN (1,2,28,3,21,29,32,34)
7400         )
7401       -- dont look at scrap and costing txns
7402       -- Bug 3396558 fix. Ignore ownership xfr,planning xfr transactions
7403          AND mmtt.transaction_action_id NOT IN (5,6, 24,30)
7404     UNION ALL
7405        --MMTT records, lot in MTLT
7406        SELECT
7407             mmtt.organization_id    organization_id
7408           , mmtt.inventory_item_id  inventory_item_id
7409           , mmtt.revision           revision
7410           , mtlt.lot_number         lot_number
7411           , mmtt.subinventory_code  subinventory_code
7412           , mmtt.locator_id         locator_id
7413      --Bug 4185621
7414           --, Decode(mmtt.transaction_status, 2, 1,
7415           , Decode(Decode(mmtt.transaction_status, 2, decode(nvl(mmtt.wms_task_status,-1),4,-1,2), mmtt.transaction_status), 2, 1,
7416       Decode(mmtt.transaction_action_id,1,-1,2,-1,28,-1,3,-1,
7417          Sign(mmtt.primary_quantity))) *
7418       round(Abs(decode(l_demand_source_line_id,
7419          NULL, mtlt.primary_quantity,
7420          Nvl(pjm_ueff_onhand.txn_quantity(
7421                 l_demand_source_line_id
7422             ,mmtt.transaction_temp_id
7423             ,mtlt.lot_number
7424                   ,'Y'
7425             ,mmtt.inventory_item_id
7426             ,mmtt.organization_id
7427             ,mmtt.transaction_source_type_id
7428             ,mmtt.transaction_source_id
7429             ,mmtt.rcv_transaction_id
7430                ,sign(mmtt.primary_quantity)
7431                ),mtlt.primary_quantity)
7432       )),5)
7433      --Bug 4185621
7434           --, Decode(mmtt.transaction_status, 2, 1,
7435           , Decode(Decode(mmtt.transaction_status, 2, decode(nvl(mmtt.wms_task_status,-1),4,-1,2), mmtt.transaction_status), 2, 1,
7436       Decode(mmtt.transaction_action_id,1,-1,2,-1,28,-1,3,-1,
7437          Sign(mmtt.secondary_transaction_quantity))) *
7438       round(Abs(decode(l_demand_source_line_id,
7439          NULL, mtlt.secondary_quantity,
7440          Nvl(pjm_ueff_onhand.txn_quantity(
7441                 l_demand_source_line_id
7442             ,mmtt.transaction_temp_id
7443             ,mtlt.lot_number
7444                   ,'Y'
7445             ,mmtt.inventory_item_id
7446             ,mmtt.organization_id
7447             ,mmtt.transaction_source_type_id
7448             ,mmtt.transaction_source_id
7449             ,mmtt.rcv_transaction_id
7450                ,sign(mmtt.secondary_transaction_quantity)
7451                ),mtlt.secondary_quantity)
7452       )),5)                                                  -- invConv change
7453     --Bug 4185621
7454          --, Decode(mmtt.transaction_status, 2, 5, 1) quantity_type
7455          , Decode(mmtt.transaction_status, 2, decode(nvl(mmtt.wms_task_status,-1),4,1,5), 1)  quantity_type
7456           , mmtt.cost_group_id       cost_group_id
7457      ,NVL(mmtt.allocated_lpn_id,
7458       NVL(mmtt.content_lpn_id, mmtt.lpn_id)) lpn_id
7459           , Decode(mmtt.transaction_status, 2 , mmtt.transaction_action_id, to_number(NULL)) transaction_action_id
7460           , Decode(mmtt.transaction_status, 2 , mmtt.transfer_subinventory, to_char(NULL)) transfer_subinventory_code
7461           , Decode(mmtt.transaction_status, 2 , mmtt.transfer_to_location, to_number(NULL))  transfer_locator_id
7462        FROM
7463             mtl_material_transactions_temp mmtt,
7464       mtl_transaction_lots_temp mtlt
7465        WHERE
7466              mmtt.posting_flag = 'Y'
7467          AND mmtt.transaction_temp_id = mtlt.transaction_temp_id
7468          AND mmtt.lot_number IS NULL
7469     AND mmtt.subinventory_code IS NOT NULL
7470     AND (Nvl(mmtt.transaction_status,0) <> 2 OR
7471             Nvl(mmtt.transaction_status,0) = 2 AND
7472             mmtt.transaction_action_id IN (1,2,28,3,21,29,32,34)
7473         )
7474       -- dont look at scrap and costing txns
7475       -- Bug 3396558 fix. Ignore ownership xfr,planning xfr transactions
7476          AND mmtt.transaction_action_id NOT IN (5,6, 24,30)
7477        UNION ALL
7478        -- receiving side of transfers lot in MMTT
7479        -- Bug 7658493, If wms task is in loaded status, consider allocation like pending transaction.
7480        SELECT
7481             Decode(mmtt.transaction_action_id
7482                , 3, mmtt.transfer_organization
7483                , mmtt.organization_id)   organization_id
7484           , mmtt.inventory_item_id       inventory_item_id
7485           , mmtt.revision                revision
7486           , mmtt.lot_number              lot_number
7487           , mmtt.transfer_subinventory   subinventory_code
7488           , mmtt.transfer_to_location    locator_id
7489      , round(Abs(decode(l_demand_source_line_id,
7490          NULL, mmtt.primary_quantity,
7491          Nvl(pjm_ueff_onhand.txn_quantity(
7492                 l_demand_source_line_id
7493             ,mmtt.transaction_temp_id
7494             ,mmtt.lot_number
7495                ,'Y'
7496             ,mmtt.inventory_item_id
7497             ,mmtt.organization_id
7498             ,mmtt.transaction_source_type_id
7499             ,mmtt.transaction_source_id
7500             ,mmtt.rcv_transaction_id
7501                ,sign(mmtt.primary_quantity)
7502                ),mmtt.primary_quantity)
7503          )),5)
7504      , round(Abs(decode(l_demand_source_line_id,
7505          NULL, mmtt.secondary_transaction_quantity,
7506          Nvl(pjm_ueff_onhand.txn_quantity(
7507                 l_demand_source_line_id
7508             ,mmtt.transaction_temp_id
7509             ,mmtt.lot_number
7510                ,'Y'
7511             ,mmtt.inventory_item_id
7512             ,mmtt.organization_id
7513             ,mmtt.transaction_source_type_id
7514             ,mmtt.transaction_source_id
7515             ,mmtt.rcv_transaction_id
7516                ,sign(mmtt.secondary_transaction_quantity)
7517                ),mmtt.secondary_transaction_quantity)
7518          )),5)                                                            -- invConv change
7519           , 1                            quantity_type
7520           , mmtt.transfer_cost_group_id  cost_group_id
7521           , NVL(mmtt.content_lpn_id,mmtt.transfer_lpn_id)  lpn_id
7522           , to_number(NULL)                      transaction_action_id
7523           , to_char(NULL)                        transfer_subinventory_code
7524           , to_number(NULL)                      transfer_locator_id
7525        FROM
7526             mtl_material_transactions_temp mmtt
7527        WHERE
7528              mmtt.posting_flag = 'Y'
7529          AND mmtt.lot_number IS NOT NULL
7530          AND Decode( Nvl(mmtt.transaction_status,0),
7531                        2, decode(nvl(mmtt.wms_task_status,-1), 4, 1, 2),
7532                        1 ) <> 2
7533          AND mmtt.transaction_action_id IN (2,28,3)
7534         UNION ALL
7535         -- receiving side of transfers  lot in MTLT
7536         -- Bug 7658493, If wms task is in loaded status, consider allocation like pending transaction.
7537        SELECT
7538             Decode(mmtt.transaction_action_id
7539                , 3, mmtt.transfer_organization
7540                , mmtt.organization_id)   organization_id
7541           , mmtt.inventory_item_id       inventory_item_id
7542           , mmtt.revision                revision
7543           , mtlt.lot_number              lot_number
7544           , mmtt.transfer_subinventory   subinventory_code
7545           , mmtt.transfer_to_location    locator_id
7546      , round(Abs(decode(l_demand_source_line_id,
7547          NULL, mtlt.primary_quantity,
7548          Nvl(pjm_ueff_onhand.txn_quantity(
7549                 l_demand_source_line_id
7550             ,mmtt.transaction_temp_id
7551             ,mtlt.lot_number
7552                ,'Y'
7553             ,mmtt.inventory_item_id
7554             ,mmtt.organization_id
7555             ,mmtt.transaction_source_type_id
7556             ,mmtt.transaction_source_id
7557             ,mmtt.rcv_transaction_id
7558                ,sign(mmtt.primary_quantity)
7559                ),mtlt.primary_quantity)
7560       )),5)
7561      , round(Abs(decode(l_demand_source_line_id,
7562          NULL, mtlt.secondary_quantity,
7563          Nvl(pjm_ueff_onhand.txn_quantity(
7564                 l_demand_source_line_id
7565             ,mmtt.transaction_temp_id
7566             ,mtlt.lot_number
7567                ,'Y'
7568             ,mmtt.inventory_item_id
7569             ,mmtt.organization_id
7570             ,mmtt.transaction_source_type_id
7571             ,mmtt.transaction_source_id
7572             ,mmtt.rcv_transaction_id
7573                ,sign(mmtt.secondary_transaction_quantity)
7574                ),mtlt.secondary_quantity)
7575       )),5)                                                    -- invConv change
7576           , 1                            quantity_type
7577           , mmtt.transfer_cost_group_id  cost_group_id
7578           , NVL(mmtt.content_lpn_id,mmtt.transfer_lpn_id) lpn_id
7579           , to_number(NULL)                      transaction_action_id
7580           , to_char(NULL)                        transfer_subinventory_code
7581           , to_number(NULL)                      transfer_locator_id
7582        FROM
7583             mtl_material_transactions_temp mmtt
7584       ,mtl_transaction_lots_temp mtlt
7585        WHERE
7586              mmtt.posting_flag = 'Y'
7587           AND mmtt.lot_number IS NULL
7588           AND mmtt.transaction_temp_id = mtlt.transaction_temp_id
7589           AND Decode( Nvl(mmtt.transaction_status,0),
7590                        2, decode(nvl(mmtt.wms_task_status,-1), 4, 1, 2),
7591                        1 ) <> 2
7592           AND mmtt.transaction_action_id IN (2,28,3)
7593       ) x
7594       WHERE x.organization_id    = l_organization_id
7595         AND x.inventory_item_id  = l_inventory_item_id
7596       GROUP BY
7597            x.organization_id, x.inventory_item_id, x.revision
7598           , x.lot_number,x.subinventory_code, x.locator_id
7599           , x.quantity_type, x.cost_group_id, x.lpn_id
7600           , x.transaction_action_id, x.transfer_subinventory_code
7601           , x.transfer_locator_id
7602    ) x
7603     , mtl_secondary_inventories sub
7604     , mtl_lot_numbers lot
7605  WHERE
7606    x.organization_id    = sub.organization_id          (+)
7607    AND x.subinventory_code = sub.secondary_inventory_name (+)
7608    AND x.organization_id   = lot.organization_id   (+)
7609    AND x.inventory_item_id = lot.inventory_item_id (+)
7610    AND x.lot_number        = lot.lot_number        (+)
7611    AND (l_asset_subs_only = 2 OR
7612          NVL(sub.asset_inventory,1) = 1)
7613    AND ((l_onhand_source = 1 AND
7614       Nvl(sub.inventory_atp_code, 1) = 1
7615     ) OR
7616         (l_onhand_source = 2 AND
7617        Nvl(sub.availability_type, 1) = 1
7618     ) OR
7619     l_onhand_source =3
7620       OR
7621     (l_onhand_source = 4 AND
7622       Nvl(sub.inventory_atp_code, 1) = 1 AND
7623                 Nvl(sub.availability_type, 1) = 1
7624     )
7625       )
7626    AND (l_lot_expiration_control = 2 OR
7627         lot.expiration_date IS NULL OR
7628         l_lot_expiration_date IS NULL OR
7629         lot.expiration_date > l_lot_expiration_date);
7630 
7631   -- invConv change : grade_code filter is in here
7632   CURSOR c_lot_unit_grade IS
7633    SELECT
7634           x.organization_id       organization_id
7635         , x.inventory_item_id     inventory_item_id
7636         , x.revision              revision
7637         , x.lot_number       lot_number
7638         , lot.expiration_date     lot_expiration_date
7639         , x.subinventory_code     subinventory_code
7640         , sub.reservable_type     reservable_type
7641         , x.locator_id            locator_id
7642         , x.primary_quantity      primary_quantity
7643         , x.secondary_quantity    secondary_quantity        -- invConv change
7644         , x.quantity_type         quantity_type
7645         , x.cost_group_id         cost_group_id
7646         , x.lpn_id        lpn_id
7647         , x.transaction_action_id       transaction_action_id
7648         , x.transfer_subinventory_code  transfer_subinventory_code
7649         , x.transfer_locator_id         transfer_locator_id
7650      FROM (
7651        SELECT
7652            x.organization_id       organization_id
7653          , x.inventory_item_id     inventory_item_id
7654          , decode(l_revision_control, 2, NULL
7655          , x.revision)       revision
7656          , x.lot_number             lot_number
7657          , x.subinventory_code     subinventory_code
7658          , x.locator_id            locator_id
7659          , SUM(x.primary_quantity) primary_quantity
7660          , SUM(x.secondary_quantity) secondary_quantity        -- invConv change
7661          , x.quantity_type         quantity_type
7662          , x.cost_group_id         cost_group_id
7663          , x.lpn_id        lpn_id
7664          , x.transaction_action_id       transaction_action_id
7665          , x.transfer_subinventory_code  transfer_subinventory_code
7666          , x.transfer_locator_id         transfer_locator_id
7667         FROM (
7668        -- reservations
7669        SELECT
7670           mr.organization_id       organization_id
7671         , mr.inventory_item_id     inventory_item_id
7672         , mr.revision              revision
7673         , mr.lot_number            lot_number
7674         , mr.subinventory_code     subinventory_code
7675         , mr.locator_id            locator_id
7676         , mr.primary_reservation_quantity
7677            - Nvl(mr.detailed_quantity,0)    primary_quantity
7678         , mr.secondary_reservation_quantity
7679            - Nvl(mr.secondary_detailed_quantity,0)    secondary_quantity        -- invConv change
7680         , 3                        quantity_type
7681         , to_number(NULL)       cost_group_id
7682         , lpn_id        lpn_id
7683         , to_number(NULL)                      transaction_action_id
7684         , to_char(NULL)                        transfer_subinventory_code
7685         , to_number(NULL)                      transfer_locator_id
7686      FROM mtl_reservations mr
7687      WHERE
7688           Nvl(mr.supply_source_type_id, 13) = 13
7689       AND mr.primary_reservation_quantity >
7690       Nvl(mr.detailed_quantity,0)
7691       AND ((l_no_lpn_reservations <>1)
7692            OR (l_no_lpn_reservations = 1 AND mr.lpn_id IS NULL))
7693       AND (l_tree_mode <> 3 OR
7694           (l_tree_mode = 3
7695       AND NOT (l_demand_source_type_id = mr.demand_source_type_id
7696          AND l_demand_source_header_id = mr.demand_source_header_id
7697          AND Nvl(l_demand_source_line_id, -9999) =
7698          Nvl(mr.demand_source_line_id,-9999)
7699          AND Nvl(l_demand_source_name, '@@@###@@#') =
7700          Nvl(mr.demand_source_name,'@@@###@@#')
7701       AND Nvl(l_demand_source_delivery,-9999) =
7702          Nvl(mr.demand_source_delivery,-9999)
7703               )
7704      ))
7705      UNION ALL
7706        -- onhand quantities
7707        SELECT
7708           moq.organization_id               organization_id
7709         , moq.inventory_item_id             inventory_item_id
7710         , moq.revision                      revision
7711         , moq.lot_number                    lot_number
7712         , moq.subinventory_code             subinventory_code
7713         , moq.locator_id                    locator_id
7714         , decode(l_demand_source_line_id,
7715          NULL, sum(moq.primary_transaction_quantity),
7716          pjm_ueff_onhand.onhand_quantity(
7717              l_demand_source_line_id
7718             ,moq.inventory_item_id
7719             ,moq.organization_id
7720             ,moq.revision
7721             ,moq.subinventory_code
7722             ,moq.locator_id
7723             ,moq.lot_number
7724             ,moq.lpn_id
7725             ,moq.cost_group_id)
7726           )
7727         , decode(l_demand_source_line_id,
7728          NULL, sum(moq.secondary_transaction_quantity),
7729          pjm_ueff_onhand.onhand_quantity(
7730              l_demand_source_line_id
7731             ,moq.inventory_item_id
7732             ,moq.organization_id
7733             ,moq.revision
7734             ,moq.subinventory_code
7735             ,moq.locator_id
7736             ,moq.lot_number
7737             ,moq.lpn_id
7738             ,moq.cost_group_id)
7739           )
7740         , 1                                 quantity_type
7741    , moq.cost_group_id                 cost_group_id
7742         , moq.lpn_id           lpn_id
7743         , to_number(NULL)                      transaction_action_id
7744         , to_char(NULL)                        transfer_subinventory_code
7745         , to_number(NULL)                      transfer_locator_id
7746        FROM
7747           mtl_onhand_quantities_detail moq
7748        GROUP BY moq.organization_id,moq.inventory_item_id,moq.revision,
7749            moq.subinventory_code,moq.locator_id,moq.lot_number,
7750            moq.lpn_id,moq.cost_group_id
7751      UNION ALL
7752        -- pending transactions in mmtt, lot in MMTT
7753        SELECT
7754             mmtt.organization_id    organization_id
7755           , mmtt.inventory_item_id  inventory_item_id
7756           , mmtt.revision           revision
7757           , mmtt.lot_number         lot_number
7758           , mmtt.subinventory_code  subinventory_code
7759           , mmtt.locator_id         locator_id
7760      --Bug 4185621
7761           --, Decode(mmtt.transaction_status, 2, 1,
7762           , Decode(Decode(mmtt.transaction_status, 2, decode(nvl(mmtt.wms_task_status,-1),4,-1,2), mmtt.transaction_status), 2, 1,
7763       Decode(mmtt.transaction_action_id,1,-1,2,-1,28,-1,3,-1,
7764          Sign(mmtt.primary_quantity))) *
7765       round(Abs(decode(l_demand_source_line_id,
7766          NULL, mmtt.primary_quantity,
7767          Nvl(pjm_ueff_onhand.txn_quantity(
7768                 l_demand_source_line_id
7769             ,mmtt.transaction_temp_id
7770             ,mmtt.lot_number
7771                   ,'Y'
7772             ,mmtt.inventory_item_id
7773             ,mmtt.organization_id
7774             ,mmtt.transaction_source_type_id
7775             ,mmtt.transaction_source_id
7776             ,mmtt.rcv_transaction_id
7777                ,sign(mmtt.primary_quantity)
7778                ),mmtt.primary_quantity
7779          )
7780       )),5)
7781      --Bug 4185621
7782           --, Decode(mmtt.transaction_status, 2, 1,
7783           , Decode(Decode(mmtt.transaction_status, 2, decode(nvl(mmtt.wms_task_status,-1),4,-1,2), mmtt.transaction_status), 2, 1,
7784       Decode(mmtt.transaction_action_id,1,-1,2,-1,28,-1,3,-1,
7785          Sign(mmtt.secondary_transaction_quantity))) *
7786       round(Abs(decode(l_demand_source_line_id,
7787          NULL, mmtt.secondary_transaction_quantity,
7788          Nvl(pjm_ueff_onhand.txn_quantity(
7789                 l_demand_source_line_id
7790             ,mmtt.transaction_temp_id
7791             ,mmtt.lot_number
7792                   ,'Y'
7793             ,mmtt.inventory_item_id
7794             ,mmtt.organization_id
7795             ,mmtt.transaction_source_type_id
7796             ,mmtt.transaction_source_id
7797             ,mmtt.rcv_transaction_id
7798                ,sign(mmtt.secondary_transaction_quantity)
7799                ),mmtt.secondary_transaction_quantity
7800          )
7801       )),5)                                              -- invConv change
7802    --Bug 4185621
7803         --, Decode(mmtt.transaction_status, 2, 5, 1) quantity_type
7804         , Decode(mmtt.transaction_status, 2, decode(nvl(mmtt.wms_task_status,-1),4,1,5), 1)  quantity_type
7805         , mmtt.cost_group_id      cost_group_id
7806    ,NVL(mmtt.allocated_lpn_id,
7807       NVL(mmtt.content_lpn_id, mmtt.lpn_id)) lpn_id
7808           , Decode(mmtt.transaction_status, 2 , mmtt.transaction_action_id, to_number(NULL)) transaction_action_id
7809           , Decode(mmtt.transaction_status, 2 , mmtt.transfer_subinventory, to_char(NULL)) transfer_subinventory_code
7810           , Decode(mmtt.transaction_status, 2 , mmtt.transfer_to_location, to_number(NULL))  transfer_locator_id
7811        FROM
7812             mtl_material_transactions_temp mmtt
7813        WHERE
7814             mmtt.posting_flag = 'Y'
7815     AND mmtt.lot_number IS NOT NULL
7816     AND mmtt.subinventory_code IS NOT NULL
7817     AND (Nvl(mmtt.transaction_status,0) <> 2 OR
7818             Nvl(mmtt.transaction_status,0) = 2 AND
7819          mmtt.transaction_action_id IN (1,2,28,3,21,29,32,34)
7820         )
7821       -- dont look at scrap and costing txns
7822       -- Bug 3396558 fix. Ignore ownership xfr,planning xfr transactions
7823          AND mmtt.transaction_action_id NOT IN (5,6, 24,30)
7824     UNION ALL
7825        --MMTT records, lot in MTLT
7826        SELECT
7827             mmtt.organization_id    organization_id
7828           , mmtt.inventory_item_id  inventory_item_id
7829           , mmtt.revision           revision
7830           , mtlt.lot_number         lot_number
7831           , mmtt.subinventory_code  subinventory_code
7832           , mmtt.locator_id         locator_id
7833      --Bug 4185621
7834           --, Decode(mmtt.transaction_status, 2, 1,
7835           , Decode(Decode(mmtt.transaction_status, 2, decode(nvl(mmtt.wms_task_status,-1),4,-1,2), mmtt.transaction_status), 2, 1,
7836       Decode(mmtt.transaction_action_id,1,-1,2,-1,28,-1,3,-1,
7837          Sign(mmtt.primary_quantity))) *
7838       round(Abs(decode(l_demand_source_line_id,
7839          NULL, mtlt.primary_quantity,
7840          Nvl(pjm_ueff_onhand.txn_quantity(
7841                 l_demand_source_line_id
7842             ,mmtt.transaction_temp_id
7843             ,mtlt.lot_number
7844                   ,'Y'
7845             ,mmtt.inventory_item_id
7846             ,mmtt.organization_id
7847             ,mmtt.transaction_source_type_id
7848             ,mmtt.transaction_source_id
7849             ,mmtt.rcv_transaction_id
7850                ,sign(mmtt.primary_quantity)
7851                ),mtlt.primary_quantity)
7852       )),5)
7853      --Bug 4185621
7854           --, Decode(mmtt.transaction_status, 2, 1,
7855           , Decode(Decode(mmtt.transaction_status, 2, decode(nvl(mmtt.wms_task_status,-1),4,-1,2), mmtt.transaction_status), 2, 1,
7856       Decode(mmtt.transaction_action_id,1,-1,2,-1,28,-1,3,-1,
7857          Sign(mmtt.secondary_transaction_quantity))) *
7858       round(Abs(decode(l_demand_source_line_id,
7859          NULL, mtlt.secondary_quantity,
7860          Nvl(pjm_ueff_onhand.txn_quantity(
7861                 l_demand_source_line_id
7862             ,mmtt.transaction_temp_id
7863             ,mtlt.lot_number
7864                   ,'Y'
7865             ,mmtt.inventory_item_id
7866             ,mmtt.organization_id
7867             ,mmtt.transaction_source_type_id
7868             ,mmtt.transaction_source_id
7869             ,mmtt.rcv_transaction_id
7870                ,sign(mmtt.secondary_transaction_quantity)
7871                ),mtlt.secondary_quantity)
7872       )),5)                                                  -- invConv change
7873     --Bug 4185621
7874          --, Decode(mmtt.transaction_status, 2, 5, 1) quantity_type
7875          , Decode(mmtt.transaction_status, 2, decode(nvl(mmtt.wms_task_status,-1),4,1,5), 1)  quantity_type
7876           , mmtt.cost_group_id       cost_group_id
7877      ,NVL(mmtt.allocated_lpn_id,
7878       NVL(mmtt.content_lpn_id, mmtt.lpn_id)) lpn_id
7879           , Decode(mmtt.transaction_status, 2 , mmtt.transaction_action_id, to_number(NULL)) transaction_action_id
7880           , Decode(mmtt.transaction_status, 2 , mmtt.transfer_subinventory, to_char(NULL)) transfer_subinventory_code
7881           , Decode(mmtt.transaction_status, 2 , mmtt.transfer_to_location, to_number(NULL))  transfer_locator_id
7882        FROM
7883             mtl_material_transactions_temp mmtt,
7884       mtl_transaction_lots_temp mtlt
7885        WHERE
7886              mmtt.posting_flag = 'Y'
7887          AND mmtt.transaction_temp_id = mtlt.transaction_temp_id
7888          AND mmtt.lot_number IS NULL
7889     AND mmtt.subinventory_code IS NOT NULL
7890     AND (Nvl(mmtt.transaction_status,0) <> 2 OR
7891             Nvl(mmtt.transaction_status,0) = 2 AND
7892             mmtt.transaction_action_id IN (1,2,28,3,21,29,32,34)
7893         )
7894       -- dont look at scrap and costing txns
7895       -- Bug 3396558 fix. Ignore ownership xfr,planning xfr transactions
7896          AND mmtt.transaction_action_id NOT IN (5,6, 24,30)
7897        UNION ALL
7898        -- receiving side of transfers lot in MMTT
7899        -- Bug 7658493, If wms task is in loaded status, consider allocation like pending transaction.
7900        SELECT
7901             Decode(mmtt.transaction_action_id
7902                , 3, mmtt.transfer_organization
7903                , mmtt.organization_id)   organization_id
7904           , mmtt.inventory_item_id       inventory_item_id
7905           , mmtt.revision                revision
7906           , mmtt.lot_number              lot_number
7907           , mmtt.transfer_subinventory   subinventory_code
7908           , mmtt.transfer_to_location    locator_id
7909      , round(Abs(decode(l_demand_source_line_id,
7910          NULL, mmtt.primary_quantity,
7911          Nvl(pjm_ueff_onhand.txn_quantity(
7912                 l_demand_source_line_id
7913             ,mmtt.transaction_temp_id
7914             ,mmtt.lot_number
7915                ,'Y'
7916             ,mmtt.inventory_item_id
7917             ,mmtt.organization_id
7918             ,mmtt.transaction_source_type_id
7919             ,mmtt.transaction_source_id
7920             ,mmtt.rcv_transaction_id
7921                ,sign(mmtt.primary_quantity)
7922                ),mmtt.primary_quantity)
7923          )),5)
7924      , round(Abs(decode(l_demand_source_line_id,
7925          NULL, mmtt.secondary_transaction_quantity,
7926          Nvl(pjm_ueff_onhand.txn_quantity(
7927                 l_demand_source_line_id
7928             ,mmtt.transaction_temp_id
7929             ,mmtt.lot_number
7930                ,'Y'
7931             ,mmtt.inventory_item_id
7932             ,mmtt.organization_id
7933             ,mmtt.transaction_source_type_id
7934             ,mmtt.transaction_source_id
7935             ,mmtt.rcv_transaction_id
7936                ,sign(mmtt.secondary_transaction_quantity)
7937                ),mmtt.secondary_transaction_quantity)
7938          )),5)                                                            -- invConv change
7939           , 1                            quantity_type
7940           , mmtt.transfer_cost_group_id  cost_group_id
7941           , NVL(mmtt.content_lpn_id,mmtt.transfer_lpn_id)  lpn_id
7942           , to_number(NULL)                      transaction_action_id
7943           , to_char(NULL)                        transfer_subinventory_code
7944           , to_number(NULL)                      transfer_locator_id
7945        FROM
7946             mtl_material_transactions_temp mmtt
7947        WHERE
7948              mmtt.posting_flag = 'Y'
7949          AND mmtt.lot_number IS NOT NULL
7950          AND Decode( Nvl(mmtt.transaction_status,0),
7951                        2, decode(nvl(mmtt.wms_task_status,-1), 4, 1, 2),
7952                        1 ) <> 2
7953          AND mmtt.transaction_action_id IN (2,28,3)
7954        UNION ALL
7955    -- receiving side of transfers  lot in MTLT
7956    -- Bug 7658493, If wms task is in loaded status, consider allocation like pending transaction.
7957        SELECT
7958             Decode(mmtt.transaction_action_id
7959                , 3, mmtt.transfer_organization
7960                , mmtt.organization_id)   organization_id
7961           , mmtt.inventory_item_id       inventory_item_id
7962           , mmtt.revision                revision
7963           , mtlt.lot_number              lot_number
7964           , mmtt.transfer_subinventory   subinventory_code
7965           , mmtt.transfer_to_location    locator_id
7966      , round(Abs(decode(l_demand_source_line_id,
7967          NULL, mtlt.primary_quantity,
7968          Nvl(pjm_ueff_onhand.txn_quantity(
7969                 l_demand_source_line_id
7970             ,mmtt.transaction_temp_id
7971             ,mtlt.lot_number
7972                ,'Y'
7973             ,mmtt.inventory_item_id
7974             ,mmtt.organization_id
7975             ,mmtt.transaction_source_type_id
7976             ,mmtt.transaction_source_id
7977             ,mmtt.rcv_transaction_id
7978                ,sign(mmtt.primary_quantity)
7979                ),mtlt.primary_quantity)
7980       )),5)
7981      , round(Abs(decode(l_demand_source_line_id,
7982          NULL, mtlt.secondary_quantity,
7983          Nvl(pjm_ueff_onhand.txn_quantity(
7984                 l_demand_source_line_id
7985             ,mmtt.transaction_temp_id
7986             ,mtlt.lot_number
7987                ,'Y'
7988             ,mmtt.inventory_item_id
7989             ,mmtt.organization_id
7990             ,mmtt.transaction_source_type_id
7991             ,mmtt.transaction_source_id
7992             ,mmtt.rcv_transaction_id
7993                ,sign(mmtt.secondary_transaction_quantity)
7994                ),mtlt.secondary_quantity)
7995       )),5)                                                    -- invConv change
7996           , 1                            quantity_type
7997           , mmtt.transfer_cost_group_id  cost_group_id
7998           , NVL(mmtt.content_lpn_id,mmtt.transfer_lpn_id) lpn_id
7999           , to_number(NULL)                      transaction_action_id
8000           , to_char(NULL)                        transfer_subinventory_code
8001           , to_number(NULL)                      transfer_locator_id
8002        FROM
8003             mtl_material_transactions_temp mmtt
8004            ,mtl_transaction_lots_temp mtlt
8005        WHERE
8006              mmtt.posting_flag = 'Y'
8007           AND mmtt.lot_number IS NULL
8008           AND mmtt.transaction_temp_id = mtlt.transaction_temp_id
8009           AND Decode( Nvl(mmtt.transaction_status,0),
8010                        2, decode(nvl(mmtt.wms_task_status,-1), 4, 1, 2),
8011                        1 ) <> 2
8012           AND mmtt.transaction_action_id IN (2,28,3)
8013       ) x
8014       WHERE x.organization_id    = l_organization_id
8015         AND x.inventory_item_id  = l_inventory_item_id
8016       GROUP BY
8017            x.organization_id, x.inventory_item_id, x.revision
8018           , x.lot_number,x.subinventory_code, x.locator_id
8019           , x.quantity_type, x.cost_group_id, x.lpn_id
8020           , x.transaction_action_id, x.transfer_subinventory_code
8021           , x.transfer_locator_id
8022    ) x
8023     , mtl_secondary_inventories sub
8024     , mtl_lot_numbers lot
8025  WHERE
8026    x.organization_id    = sub.organization_id          (+)
8027    AND x.subinventory_code = sub.secondary_inventory_name (+)
8028    AND x.organization_id   = lot.organization_id   (+)
8029    AND x.inventory_item_id = lot.inventory_item_id (+)
8030    AND x.lot_number        = lot.lot_number        (+)
8031    AND l_grade_code = lot.grade_code                             -- invConv change
8032    AND (l_asset_subs_only = 2 OR
8033          NVL(sub.asset_inventory,1) = 1)
8034    AND ((l_onhand_source = 1 AND
8035       Nvl(sub.inventory_atp_code, 1) = 1
8036     ) OR
8037         (l_onhand_source = 2 AND
8038        Nvl(sub.availability_type, 1) = 1
8039     ) OR
8040     l_onhand_source =3
8041       OR
8042     (l_onhand_source = 4 AND
8043       Nvl(sub.inventory_atp_code, 1) = 1 AND
8044                 Nvl(sub.availability_type, 1) = 1
8045     )
8046       )
8047    AND (l_lot_expiration_control = 2 OR
8048         lot.expiration_date IS NULL OR
8049         l_lot_expiration_date IS NULL OR
8050         lot.expiration_date > l_lot_expiration_date);
8051 
8052 BEGIN
8053    IF g_debug = 1 THEN
8054       print_debug('  ' || l_api_name || ' Entered',9);
8055    END IF;
8056 
8057    -- invConv change (for display)
8058    print_debug('odab entering build_tree grade_code='||g_rootinfos(p_tree_id).grade_code);
8059    if (g_is_lot_control = TRUE)
8060    then
8061               print_debug('In build_tree.   g_is_lot_control=TRUE');
8062    else
8063               print_debug('In build_tree.   g_is_lot_control=FALSE');
8064    end if;
8065 
8066    zero_tree_node(l_return_status, g_rootinfos(p_tree_id).item_node_index);
8067    IF l_return_status = fnd_api.g_ret_sts_error THEN
8068       RAISE fnd_api.g_exc_error;
8069    End IF ;
8070 
8071    IF l_return_status = fnd_api.g_ret_sts_unexp_error THEN
8072       RAISE fnd_api.g_exc_unexpected_error;
8073    End IF;
8074 
8075    --bug 2668448
8076    --quantity tree returned wrong values if the tree is rebuilt
8077    --but the information stored in g_rsv_info is not deleted.
8078    --This resulted in the tree displaying too little quantity being available.
8079    IF g_rsv_tree_id <> 0 AND
8080       g_demand_info.exists(g_rsv_tree_id) THEN
8081 
8082       If g_demand_info(g_rsv_tree_id).root_id = p_tree_id Then
8083          g_rsv_tree_id := 0;
8084          g_rsv_counter := 0;
8085          g_rsv_info.DELETE;
8086       End If;
8087    END IF;
8088 
8089   /*   NOT USED ANY MORE.
8090    -- build the sql statement
8091    build_cursor
8092      (  l_return_status
8093       , g_rootinfos(p_tree_id).organization_id
8094       , g_rootinfos(p_tree_id).inventory_item_id
8095       , g_rootinfos(p_tree_id).tree_mode
8096       , g_rootinfos(p_tree_id).demand_source_type_id
8097       , g_rootinfos(p_tree_id).demand_source_header_id
8098       , g_rootinfos(p_tree_id).demand_source_line_id
8099       , g_rootinfos(p_tree_id).demand_source_name
8100       , g_rootinfos(p_tree_id).demand_source_delivery
8101       , g_rootinfos(p_tree_id).is_lot_control
8102       , g_rootinfos(p_tree_id).asset_sub_only
8103       , g_rootinfos(p_tree_id).include_suggestion
8104       , g_rootinfos(p_tree_id).lot_expiration_date
8105       , g_rootinfos(p_tree_id).onhand_source
8106       , g_rootinfos(p_tree_id).pick_release
8107       , l_cursor
8108       , g_rootinfos(p_tree_id).is_revision_control
8109       );
8110 
8111    IF l_return_status = fnd_api.g_ret_sts_error THEN
8112       RAISE fnd_api.g_exc_error;
8113    End IF ;
8114    IF l_return_status = fnd_api.g_ret_sts_unexp_error THEN
8115       RAISE fnd_api.g_exc_unexpected_error;
8116    End IF;
8117    dbms_sql.define_array(l_cursor, 1,v_organization_id,l_num_recs_fetch,l_index_start);
8118    dbms_sql.define_array(l_cursor, 2,v_inventory_item_id,l_num_recs_fetch,l_index_start);
8119    dbms_sql.define_array(l_cursor, 3,v_revision,l_num_recs_fetch,l_index_start);
8120    dbms_sql.define_array(l_cursor, 4,v_lot_number,l_num_recs_fetch,l_index_start);
8121    dbms_sql.define_array(l_cursor, 5,v_lot_expiration_date,l_num_recs_fetch,l_index_start);
8122    dbms_sql.define_array(l_cursor, 6,v_subinventory_code,l_num_recs_fetch,l_index_start);
8123    dbms_sql.define_array(l_cursor, 7,v_reservable_type,l_num_recs_fetch,l_index_start);
8124    dbms_sql.define_array(l_cursor, 8,v_locator_id,l_num_recs_fetch,l_index_start);
8125    dbms_sql.define_array(l_cursor, 9,v_primary_quantity,l_num_recs_fetch,l_index_start);
8126    dbms_sql.define_array(l_cursor,10,v_secondary_quantity,l_num_recs_fetch,l_index_start);
8127    dbms_sql.define_array(l_cursor,11,v_date_received,l_num_recs_fetch,l_index_start);
8128    dbms_sql.define_array(l_cursor,12,v_quantity_type,l_num_recs_fetch,l_index_start);
8129    dbms_sql.define_array(l_cursor,13,v_cost_group_id,l_num_recs_fetch,l_index_start);
8130    dbms_sql.define_array(l_cursor,14,v_lpn_id,l_num_recs_fetch,l_index_start);
8131 
8132    l_dummy := dbms_sql.execute(l_cursor);
8133 
8134    LOOP
8135       l_cur_num_rows:=dbms_sql.fetch_rows(l_cursor);
8136       IF l_cur_num_rows = 0 THEN
8137          EXIT;
8138       END IF;
8139       l_tot_num_rows := l_tot_num_rows + l_cur_num_rows;
8140       dbms_sql.column_value(l_cursor,1,v_organization_id);
8141       dbms_sql.column_value(l_cursor,2,v_inventory_item_id);
8142       dbms_sql.column_value(l_cursor,3,v_revision);
8143       dbms_sql.column_value(l_cursor,4,v_lot_number);
8144       dbms_sql.column_value(l_cursor,5,v_lot_expiration_date);
8145       dbms_sql.column_value(l_cursor,6,v_subinventory_code);
8146       dbms_sql.column_value(l_cursor,7,v_reservable_type);
8147       dbms_sql.column_value(l_cursor,8,v_locator_id);
8148       dbms_sql.column_value(l_cursor,9,v_primary_quantity);
8149       dbms_sql.column_value(l_cursor,10,v_date_received);
8150       dbms_sql.column_value(l_cursor,11,v_quantity_type);
8151       dbms_sql.column_value(l_cursor,12,v_cost_group_id);
8152       dbms_sql.column_value(l_cursor,13,v_lpn_id);
8153       EXIT WHEN l_cur_num_rows < l_num_recs_fetch;
8154    END LOOP;
8155   */
8156 
8157    l_organization_id          := g_rootinfos(p_tree_id).organization_id;
8158    l_inventory_item_id        := g_rootinfos(p_tree_id).inventory_item_id;
8159    l_demand_source_type_id    := g_rootinfos(p_tree_id).demand_source_type_id;
8160    l_demand_source_header_id  := g_rootinfos(p_tree_id).demand_source_header_id;
8161    l_demand_source_line_id    := g_rootinfos(p_tree_id).demand_source_line_id;
8162    l_demand_source_name       := g_rootinfos(p_tree_id).demand_source_name;
8163    l_demand_source_delivery   := g_rootinfos(p_tree_id).demand_source_delivery;
8164    l_tree_mode                := g_rootinfos(p_tree_id).tree_mode;
8165    l_lot_expiration_date      := g_rootinfos(p_tree_id).lot_expiration_date;
8166    l_onhand_source            := g_rootinfos(p_tree_id).onhand_source;
8167    l_grade_code               := g_rootinfos(p_tree_id).grade_code;      -- invConv change
8168 
8169    IF g_rootinfos(p_tree_id).is_revision_control THEN
8170       l_revision_control := 1;
8171    ELSE
8172       l_revision_control := 2;
8173    END IF;
8174    IF g_rootinfos(p_tree_id).asset_sub_only THEN
8175       l_asset_subs_only := 1;
8176    ELSE
8177       l_asset_subs_only := 2;
8178    END IF;
8179    IF l_tree_mode = g_no_lpn_rsvs_mode THEN
8180       l_no_lpn_reservations := 1;
8181    ELSE
8182       l_no_lpn_reservations := 2;
8183    END IF;
8184 
8185    print_debug('build_tree: l_revision_control='||l_revision_control);
8186    print_debug('build_tree: l_asset_subs_only='||l_asset_subs_only);
8187    print_debug('build_tree: l_no_lpn_reservations='||l_no_lpn_reservations);
8188    print_debug('build_tree: l_onhand_source='||l_onhand_source);
8189    print_debug('build_tree: l_grade_code='||l_grade_code);
8190    print_debug('build_tree: l_lot_expiration_date='||l_lot_expiration_date);
8191 
8192    -- invConv changes begin : Material Status CTL = need to build the QT with lotCTL
8193    --     Even in the Header Misc UI, BUT the tree is created as prior Convergence :
8194    --     without lot_number (but using the c_lot% cursors)
8195    -- IF g_rootinfos(p_tree_id).is_lot_control THEN
8196    IF g_is_lot_control OR g_rootinfos(p_tree_id).is_lot_control
8197    THEN
8198       -- invConv changes end.
8199 
8200       l_lot_expiration_control := 1;
8201       IF g_rootinfos(p_tree_id).unit_effective = 1 THEN
8202          --item is lot controlled and unit effective
8203          IF l_grade_code IS NULL                  -- invConv change
8204          THEN                                     -- invConv change
8205             print_debug('build_tree: open c_lot_unit');
8206             OPEN c_lot_unit;
8207             FETCH c_lot_unit BULK COLLECT INTO
8208                    v_organization_id
8209                   ,v_inventory_item_id
8210                   ,v_revision
8211                   ,v_lot_number
8212                   ,v_lot_expiration_date
8213                   ,v_subinventory_code
8214                   ,v_reservable_type
8215                   ,v_locator_id
8216                   ,v_primary_quantity
8217                   ,v_secondary_quantity
8218                   ,v_quantity_type
8219                   ,v_cost_group_id
8220                   ,v_lpn_id
8221                   ,v_transaction_action_id
8222                   ,v_transfer_subinventory_code
8223                   ,v_transfer_locator_id
8224             ;
8225             CLOSE c_lot_unit;
8226             -- invConv changes begin : adding grade where clause in a separate cursor
8227          ELSE
8228             print_debug('build_tree: open c_lot_unit_grade');
8229             OPEN c_lot_unit_grade;
8230             FETCH c_lot_unit_grade BULK COLLECT INTO
8231                     v_organization_id
8232                    ,v_inventory_item_id
8233                    ,v_revision
8234                    ,v_lot_number
8235                    ,v_lot_expiration_date
8236                    ,v_subinventory_code
8237                    ,v_reservable_type
8238                    ,v_locator_id
8239                    ,v_primary_quantity
8240                    ,v_secondary_quantity
8241                    ,v_quantity_type
8242                    ,v_cost_group_id
8243                    ,v_lpn_id
8244                    ,v_transaction_action_id
8245                    ,v_transfer_subinventory_code
8246                    ,v_transfer_locator_id
8247                ;
8248             CLOSE c_lot_unit_grade;
8249          END IF;
8250          -- invConv changes end.
8251 
8252       ELSE
8253          --item is lot controlled
8254          IF l_grade_code IS NULL                  -- invConv change
8255          THEN                                     -- invConv change
8256             IF (g_is_lot_control = FALSE)
8257             THEN
8258                print_debug('build_tree: open c_lot');
8259                OPEN c_lot;
8260                FETCH c_lot BULK COLLECT INTO
8261                       v_organization_id
8262                      ,v_inventory_item_id
8263                      ,v_revision
8264                      ,v_lot_number
8265                      ,v_lot_expiration_date
8266                      ,v_subinventory_code
8267                      ,v_reservable_type
8268                      ,v_locator_id
8269                      ,v_primary_quantity
8270                      ,v_secondary_quantity
8271                      ,v_quantity_type
8272                      ,v_cost_group_id
8273                      ,v_lpn_id
8274                      ,v_transaction_action_id
8275                      ,v_transfer_subinventory_code
8276                      ,v_transfer_locator_id
8277                ;
8278                CLOSE c_lot;
8279             ELSE
8280                print_debug('build_tree: open c_lot_MMS');
8281                OPEN c_lot_MMS;
8282                FETCH c_lot_MMS BULK COLLECT INTO
8283                       v_organization_id
8284                      ,v_inventory_item_id
8285                      ,v_revision
8286                      ,v_lot_number
8287                      ,v_lot_expiration_date
8288                      ,v_subinventory_code
8289                      ,v_reservable_type
8290                      ,v_locator_id
8291                      ,v_primary_quantity
8292                      ,v_secondary_quantity
8293                      ,v_quantity_type
8294                      ,v_cost_group_id
8295                      ,v_lpn_id
8296                      ,v_transaction_action_id
8297                      ,v_transfer_subinventory_code
8298                      ,v_transfer_locator_id
8299                      ,v_status_id            -- Onhand Material Status Support
8300                ;
8301                CLOSE c_lot_MMS;
8302             END IF;     -- (g_is_lot_control = FALSE)
8303             -- invConv changes begin : adding grade where clause in a separate cursor
8304          ELSE
8305             IF (g_is_lot_control = FALSE)
8306             THEN
8307                print_debug('build_tree: open c_lot_grade');
8308                OPEN c_lot_grade;
8309                FETCH c_lot_grade BULK COLLECT INTO
8310                       v_organization_id
8311                      ,v_inventory_item_id
8312                      ,v_revision
8313                      ,v_lot_number
8314                      ,v_lot_expiration_date
8315                      ,v_subinventory_code
8316                      ,v_reservable_type
8317                      ,v_locator_id
8318                      ,v_primary_quantity
8319                      ,v_secondary_quantity
8320                      ,v_quantity_type
8321                      ,v_cost_group_id
8322                      ,v_lpn_id
8323                      ,v_transaction_action_id
8324                      ,v_transfer_subinventory_code
8325                      ,v_transfer_locator_id
8326                ;
8327                CLOSE c_lot_grade;
8328             ELSE
8329                print_debug('build_tree: open c_lot_grade_MMS');
8330                OPEN c_lot_grade_MMS;
8331                FETCH c_lot_grade_MMS BULK COLLECT INTO
8332                       v_organization_id
8333                      ,v_inventory_item_id
8334                      ,v_revision
8335                      ,v_lot_number
8336                      ,v_lot_expiration_date
8337                      ,v_subinventory_code
8338                      ,v_reservable_type
8339                      ,v_locator_id
8340                      ,v_primary_quantity
8341                      ,v_secondary_quantity
8342                      ,v_quantity_type
8343                      ,v_cost_group_id
8344                      ,v_lpn_id
8345                      ,v_transaction_action_id
8346                      ,v_transfer_subinventory_code
8347                      ,v_transfer_locator_id
8348                      ,v_status_id            -- Onhand Material Status Support
8349                ;
8350                CLOSE c_lot_grade_MMS;
8351             END IF;    -- (g_is_lot_control = FALSE)
8352          END IF;  -- l_grade_code
8353          -- invConv changes end.
8354 
8355       END IF;
8356    ELSE
8357       l_lot_expiration_control := 2;
8358       IF g_rootinfos(p_tree_id).unit_effective = 1 THEN
8359          print_debug('build_tree: open c_unit');
8360          --item is unit effective
8361          OPEN c_unit;
8362          FETCH c_unit BULK COLLECT INTO
8363                    v_organization_id
8364                   ,v_inventory_item_id
8365                   ,v_revision
8366                   ,v_lot_number
8367                   ,v_lot_expiration_date
8368                   ,v_subinventory_code
8369                   ,v_reservable_type
8370                   ,v_locator_id
8371                   ,v_primary_quantity
8372                   ,v_secondary_quantity
8373                   ,v_quantity_type
8374                   ,v_cost_group_id
8375                   ,v_lpn_id
8376                   ,v_transaction_action_id
8377                   ,v_transfer_subinventory_code
8378                   ,v_transfer_locator_id
8379          ;
8380          CLOSE c_unit;
8381       ELSE
8382          IF (inv_quantity_tree_pvt.g_is_mat_status_used = 2) /* Bug 7158174 */
8383          THEN
8384             print_debug('build_tree: open c_plain');
8385             --item is not lot controlled or unit effective
8386             OPEN c_plain;
8387             FETCH c_plain BULK COLLECT INTO
8388                    v_organization_id
8389                   ,v_inventory_item_id
8390                   ,v_revision
8391                   ,v_lot_number
8392                   ,v_lot_expiration_date
8393                   ,v_subinventory_code
8394                   ,v_reservable_type
8395                   ,v_locator_id
8396                   ,v_primary_quantity
8397                   ,v_secondary_quantity
8398                   ,v_quantity_type
8399                   ,v_cost_group_id
8400                   ,v_lpn_id
8401                   ,v_transaction_action_id
8402                   ,v_transfer_subinventory_code
8403                   ,v_transfer_locator_id
8404             ;
8405             CLOSE c_plain;
8406          ELSE
8407             print_debug('build_tree: open c_plain_MMS');
8408             --item is not lot controlled or unit effective
8409             OPEN c_plain_MMS;
8410             FETCH c_plain_MMS BULK COLLECT INTO
8411                    v_organization_id
8412                   ,v_inventory_item_id
8413                   ,v_revision
8414                   ,v_lot_number
8415                   ,v_lot_expiration_date
8416                   ,v_subinventory_code
8417                   ,v_reservable_type
8418                   ,v_locator_id
8419                   ,v_primary_quantity
8420                   ,v_secondary_quantity
8421                   ,v_quantity_type
8422                   ,v_cost_group_id
8423                   ,v_lpn_id
8424                   ,v_transaction_action_id
8425                   ,v_transfer_subinventory_code
8426                   ,v_transfer_locator_id
8427                   ,v_status_id            -- Onhand Material Status Support
8428             ;
8429             CLOSE c_plain_MMS;
8430          END IF;    -- (g_is_lot_control = FALSE)
8431       END IF;
8432    END IF;
8433    print_debug('build_tree: l_lot_expiration_control='||l_lot_expiration_control);
8434 
8435    --WHILE (l_index < l_tot_num_rows) LOOP
8436    l_index := v_organization_id.FIRST;
8437    LOOP
8438       print_debug('build_tree: loop index='||l_index||'.');
8439       EXIT WHEN l_index IS NULL;
8440       IF (l_tree_mode = g_loose_only_mode
8441           AND v_quantity_type(l_index) = g_qr_same_demand) THEN
8442          -- the record should not be used to build the tree
8443          -- as it is a reservation for the same demand
8444          NULL;
8445          print_debug('... QT not build because mode=looose_only and qty_type=qr_same_demand...');
8446       ELSE
8447          IF v_reservable_type(l_index) IS NOT NULL THEN
8448             IF v_reservable_type(l_index) = 1 THEN
8449                l_is_reservable_sub := TRUE;
8450              ELSIF v_reservable_type(l_index) = 2 THEN
8451                l_is_reservable_sub := FALSE;
8452              ELSE
8453                l_is_reservable_sub := NULL;
8454             END IF;
8455          ELSE
8456             l_is_reservable_sub := NULL;
8457          END IF;
8458 
8459          -- invConv changes begin :
8460          print_debug('org='||l_organization_id||', item='||l_inventory_item_id||', sub='||v_subinventory_code(l_index)||', loc='||v_locator_id(l_index)||', lot='||substr(v_lot_number(l_index), 1, 10)||', priqty='||v_primary_quantity(l_index));
8461          check_is_reservable
8462               ( x_return_status     => l_return_status
8463               , p_inventory_item_id => l_inventory_item_id
8464               , p_organization_id   => l_organization_id
8465               , p_subinventory_code => v_subinventory_code(l_index)
8466               , p_locator_id        => v_locator_id(l_index)
8467               , p_lot_number        => v_lot_number(l_index)
8468               , p_root_id           => p_tree_id
8469               , x_is_reservable     => l_is_reservable_sub
8470               , p_lpn_id            => v_lpn_id(l_index)); -- Onhand Material Status Support
8471 
8472          if l_is_reservable_sub then
8473              print_debug('after check_is_reservable, rsv=TRUE');
8474          else
8475              print_debug('after check_is_reservable, rsv=FALSE');
8476          end if;
8477          -- invConv changes end.
8478 
8479 --       dbms_output.put(', item '||l_inventory_item_id);
8480 --       dbms_output.put(', sub '||l_subinventory_code);
8481 --       dbms_output.put(', loc '||To_char(l_locator_id));
8482 --       dbms_output.put(', lot '||l_lot_number);
8483 --       print_debug(', priqty '|| To_char(l_primary_quantity));
8484 --     dbms_output.put(', rev '||l_revision);
8485 --     dbms_output.put(', lotdate: '|| fnd_date.date_to_canonical(l_lot_expiration_date));
8486 --     dbms_output.put(', rsvtype '|| To_char(l_reservable_type));
8487 --     dbms_output.put(', datercv '||To_char(l_date_received));
8488 --     dbms_output.put_line(', qtytype '||l_quantity_type);
8489 
8490          -- invConv changes begin : Only with mat_stat CTL, Create the tree with lotCTL FALSE :
8491          if g_is_lot_control AND g_rootinfos(p_tree_id).is_lot_control = FALSE
8492          then
8493             print_debug(' Calling add_quantities  for summary node ...');
8494             add_quantities
8495               (
8496                  x_return_status     => l_return_status
8497                , p_tree_id           => p_tree_id
8498                , p_revision          => v_revision(l_index)
8499                , p_lot_number        => NULL
8500                , p_subinventory_code => v_subinventory_code(l_index)
8501                , p_is_reservable_sub => l_is_reservable_sub
8502                , p_locator_id        => v_locator_id(l_index)
8503                , p_primary_quantity  => v_primary_quantity(l_index)
8504                , p_secondary_quantity=> v_secondary_quantity(l_index)
8505                , p_quantity_type     => v_quantity_type (l_index)
8506                , p_set_check_mark    => FALSE
8507                , p_cost_group_id     => v_cost_group_id(l_index)
8508                , p_lpn_id         => v_lpn_id(l_index)
8509                --Bug 4294336
8510                , p_transaction_action_id => v_transaction_action_id(l_index)
8511                , p_transfer_subinventory_code => v_transfer_subinventory_code(l_index)
8512                , p_transfer_locator_id   =>   v_transfer_locator_id(l_index)
8513                  );
8514 
8515             IF l_return_status = fnd_api.g_ret_sts_error THEN
8516                RAISE fnd_api.g_exc_error;
8517             End IF ;
8518 
8519             IF l_return_status = fnd_api.g_ret_sts_unexp_error THEN
8520                RAISE fnd_api.g_exc_unexpected_error;
8521             End IF;
8522          ELSE
8523             -- invConv changes end.
8524             print_debug(' Calling add_quantities for qty1='||v_primary_quantity(l_index)||', qty2='||v_secondary_quantity(l_index)||'...');
8525             add_quantities
8526               (
8527                  x_return_status     => l_return_status
8528                , p_tree_id           => p_tree_id
8529                , p_revision          => v_revision(l_index)
8530                , p_lot_number        => v_lot_number(l_index)
8531                , p_subinventory_code => v_subinventory_code(l_index)
8532                , p_is_reservable_sub => l_is_reservable_sub
8533                , p_locator_id        => v_locator_id(l_index)
8534                , p_primary_quantity  => v_primary_quantity(l_index)
8535                , p_secondary_quantity=> v_secondary_quantity(l_index)
8536                , p_quantity_type     => v_quantity_type (l_index)
8537                , p_set_check_mark    => FALSE
8538                , p_cost_group_id     => v_cost_group_id(l_index)
8539                , p_lpn_id            => v_lpn_id(l_index)
8540                --Bug 4294336
8541                , p_transaction_action_id => v_transaction_action_id(l_index)
8542                , p_transfer_subinventory_code => v_transfer_subinventory_code(l_index)
8543                , p_transfer_locator_id   =>   v_transfer_locator_id(l_index)
8544                  );
8545 
8546             IF l_return_status = fnd_api.g_ret_sts_error THEN
8547                RAISE fnd_api.g_exc_error;
8548             End IF ;
8549 
8550             IF l_return_status = fnd_api.g_ret_sts_unexp_error THEN
8551                RAISE fnd_api.g_exc_unexpected_error;
8552             End IF;
8553             -- invConv changes begin : Closing test on g_is_lot_ctl
8554          END IF;
8555          -- invConv changes end.
8556       END IF;
8557 
8558       EXIT WHEN l_index = v_organization_id.LAST;
8559       l_index := v_organization_id.NEXT(l_index);
8560    END LOOP;
8561 
8562    print_debug('... end of build_tree loop...');
8563 
8564    -- close cursor
8565    --dbms_sql.CLOSE_cursor(l_cursor);
8566    g_rootinfos(p_tree_id).need_refresh := FALSE;
8567    x_return_status := l_return_status;
8568 
8569    IF g_debug = 1 THEN
8570       print_debug('  '||l_api_name || ' Exited with status = '||l_return_status,9);
8571    END IF;
8572 
8573 EXCEPTION
8574    WHEN fnd_api.g_exc_error THEN
8575         print_debug('build_tree: exc_err='||sqlerrm,9);
8576         x_return_status := fnd_api.g_ret_sts_error;
8577 
8578    WHEN fnd_api.g_exc_unexpected_error THEN
8579         print_debug('build_tree: unexp_err='||sqlerrm,9);
8580         x_return_status := fnd_api.g_ret_sts_unexp_error ;
8581 
8582     WHEN OTHERS THEN
8583         print_debug('build_tree: others='||sqlerrm,9);
8584         x_return_status := fnd_api.g_ret_sts_unexp_error ;
8585 
8586         IF fnd_msg_pub.check_msg_level(fnd_msg_pub.g_msg_lvl_unexp_error)
8587           THEN
8588            fnd_msg_pub.add_exc_msg
8589              (  g_pkg_name
8590               , 'Build_Tree'
8591               );
8592         END IF;
8593 
8594 END build_tree;
8595 
8596 -- Function
8597 --   check_node_violation
8598 -- Description
8599 --   return false if there is violation, true otherwise
8600 FUNCTION check_node_violation
8601   (  x_return_status      OUT NOCOPY VARCHAR2
8602    , p_node_index         IN  INTEGER
8603    , p_tree_mode          IN  INTEGER
8604    , p_negative_allowed   IN  BOOLEAN
8605    , p_item_node_index    IN  INTEGER
8606    ) RETURN BOOLEAN
8607   IS
8608    l_return_status        VARCHAR2(1) := fnd_api.g_ret_sts_success;
8609    l_child_index          INTEGER;
8610    l_no_violation         BOOLEAN;
8611    l_node_index           INTEGER;
8612 BEGIN
8613    print_debug('Entering check_node_violation...');
8614 
8615    -- check this node
8616    print_debug('mode='||p_tree_mode||', att='||g_nodes(p_node_index).att||', qr='||g_nodes(p_item_node_index).qr||' AND atr='||g_nodes(p_item_node_index).atr);
8617    print_debug('Secondaries: satt='||g_nodes(p_node_index).satt||', sqr='||g_nodes(p_item_node_index).sqr||' AND satr='||g_nodes(p_item_node_index).satr);
8618    IF p_tree_mode IN (g_transaction_mode, g_loose_only_mode)
8619      AND g_nodes(p_node_index).check_mark
8620      AND g_nodes(p_node_index).att < 0
8621      AND (p_negative_allowed = FALSE
8622      OR (g_nodes(p_item_node_index).qr > 0 AND g_nodes(p_item_node_index).atr < 0 )) THEN
8623       --OR g_nodes(p_item_node_index).atr < 0 ) THEN
8624       --Bug 3383756 fix, redoing bug 3078863 fix made in 115.121, but
8625       --missing in this version
8626       print_debug('... return=FALSE, with status='||l_return_status||' ... because :');
8627       print_debug('mode='||p_tree_mode||', check_mark=TRUE, att='||g_nodes(p_node_index).att||', (negative_allowed=FALSE OR {qr='||g_nodes(p_item_node_index).qr||' >0 AND atr='||g_nodes(p_item_node_index).atr||' <0}');
8628       RETURN FALSE;
8629    END IF;
8630 
8631    IF p_tree_mode = g_reservation_mode
8632      AND g_nodes(p_node_index).check_mark
8633      AND g_nodes(p_node_index).atr < 0 THEN
8634       print_debug('... return=FALSE, with status='||l_return_status||' ... because :');
8635       print_debug('mode='||p_tree_mode||', check_mark=TRUE, atr='||g_nodes(p_node_index).atr||' <0.');
8636       RETURN FALSE;
8637    END IF;
8638 
8639    -- check child nodes
8640    l_child_index := g_nodes(p_node_index).first_child_index;
8641    l_no_violation := TRUE;
8642    WHILE (l_child_index <> 0) LOOP
8643       l_no_violation := check_node_violation(
8644            x_return_status    => l_return_status
8645          , p_node_index       => l_child_index
8646          , p_tree_mode        => p_tree_mode
8647          , p_negative_allowed => p_negative_allowed
8648          , p_item_node_index  => p_item_node_index
8649          );
8650 
8651       IF l_no_violation = FALSE THEN
8652          print_debug('... exiting the loop with return=FALSE');
8653          EXIT;
8654       END IF;
8655 
8656       l_child_index := g_nodes(l_child_index).next_sibling_index;
8657    END LOOP;
8658 
8659    x_return_status := l_return_status;
8660 
8661    IF l_no_violation
8662    THEN
8663       print_debug('Normal end of check_node_violation. status='||l_return_status||', no_violation=TRUE');
8664    ELSE
8665       print_debug('Normal end of check_node_violation. status='||l_return_status||', no_violation=FALSE');
8666    END IF;
8667    RETURN l_no_violation;
8668 
8669 EXCEPTION
8670    WHEN fnd_api.g_exc_error THEN
8671         x_return_status := fnd_api.g_ret_sts_error;
8672 
8673    WHEN fnd_api.g_exc_unexpected_error THEN
8674         x_return_status := fnd_api.g_ret_sts_unexp_error ;
8675 
8676    WHEN OTHERS THEN
8677       x_return_status := fnd_api.g_ret_sts_unexp_error ;
8678 
8679       IF fnd_msg_pub.check_msg_level(fnd_msg_pub.g_msg_lvl_unexp_error)
8680         THEN
8681          fnd_msg_pub.add_exc_msg
8682            (  g_pkg_name
8683               , 'Check_Node_Violation'
8684               );
8685       END IF;
8686       RETURN FALSE;
8687 
8688 END check_node_violation;
8689 
8690 --add_demand_qty
8691 -- When in transaction_mode, this procedure will fix
8692 -- the quantity tree to reflect the correct available quantities.
8693 -- To do this, it queries the mtl_reservations table to find
8694 -- reservations which correspond to the demand info.  For each
8695 -- reservation, it calls add_quantities to subtract those reservations
8696 -- from the quantity tree (since that quantity should be available
8697 -- for this transaction).  We call add_quantities with a negative
8698 -- quantity so that QR is decreased, and ATT is increased.
8699 -- We also add the reservation data to the rsv_info plsql table.
8700 -- Saving the data keeps us from having to query the table again.
8701 -- After this, querying the tree will
8702 -- reflect the actual ATT.
8703 
8704 -- Bug 4194323 While cosidering Reservations against demand information
8705 -- specified we should consider supply type reservations of Inventory only
8706 
8707 PROCEDURE add_demand_qty(
8708     x_return_status  OUT NOCOPY VARCHAR2
8709         ,p_tree_id     IN  INTEGER
8710  ) IS
8711 
8712   l_root_id    INTEGER;
8713   l_revision    VARCHAR2(3);
8714   l_lot_number  VARCHAR2(80);                -- invConv change (size)
8715   l_subinventory_code VARCHAR2(10);
8716   l_locator_id  NUMBER;
8717   l_lpn_id  NUMBER;
8718   l_quantity    NUMBER;
8719   l_quantity2    NUMBER;                     -- invConv change
8720   l_mult NUMBER := -1;
8721 
8722 
8723   --We need 6 possible queries to improve performance and make best
8724   -- use of the indices on mtl_reservations, while avoid dynamic sql.
8725 
8726   -- demand line is not NULL, not pick release
8727   -- Bug 4494038: exclude crossdock reservations
8728   CURSOR c_demand_dl IS
8729   SELECT   revision
8730          , lot_number
8731          , subinventory_code
8732          , locator_id
8733          , lpn_id
8734          , primary_reservation_quantity - NVL(detailed_quantity, 0)
8735          , NVL(secondary_reservation_quantity, 0) - NVL(secondary_detailed_quantity, 0)           -- invConv change
8736   FROM mtl_reservations
8737   WHERE organization_id                      = g_rootinfos(l_root_id).organization_id
8738     AND inventory_item_id                    = g_rootinfos(l_root_id).inventory_item_id
8739     AND demand_source_type_id                = g_demand_info(p_tree_id).demand_source_type_id
8740     AND demand_source_header_id              = g_demand_info(p_tree_id).demand_source_header_id
8741     AND demand_source_line_id                = g_demand_info(p_tree_id).demand_source_line_id
8742     AND NVL(demand_source_name, '@@@###@@#') = NVL(g_demand_info(p_tree_id).demand_source_name, '@@@###@@#')
8743     AND NVL(demand_source_delivery, -99999)  = NVL(g_demand_info(p_tree_id).demand_source_delivery, -99999)
8744     AND demand_source_line_detail IS NULL
8745     AND nvl(supply_source_type_id,13) = 13 ;                -- Bug 4194323
8746 
8747   -- demand name is not null, not pick release
8748   -- Bug 4494038: exclude crossdock reservations
8749   CURSOR c_demand_dn IS
8750   SELECT  revision
8751          ,lot_number
8752          ,subinventory_code
8753          ,locator_id
8754          ,lpn_id
8755          ,primary_reservation_quantity - NVL(detailed_quantity, 0)
8756          ,NVL(secondary_reservation_quantity, 0) - NVL(secondary_detailed_quantity, 0)           -- invConv change
8757    FROM mtl_reservations
8758   WHERE organization_id                      = g_rootinfos(l_root_id).organization_id
8759     AND inventory_item_id                    = g_rootinfos(l_root_id).inventory_item_id
8760     AND demand_source_type_id                = g_demand_info(p_tree_id).demand_source_type_id
8761     AND demand_source_header_id              = g_demand_info(p_tree_id).demand_source_header_id
8762     AND demand_source_name                   = g_demand_info(p_tree_id).demand_source_name
8763     AND demand_source_line_id IS NULL
8764     AND NVL(demand_source_delivery, -99999)  = NVL(g_demand_info(p_tree_id).demand_source_delivery, -99999)
8765     AND demand_source_line_detail IS NULL
8766     AND nvl(supply_source_type_id,13) = 13 ;                -- Bug 4194323
8767 
8768   -- query based on org and item
8769   -- Bug 4494038: exclude crossdock reservations
8770   CURSOR c_demand IS
8771   SELECT  revision
8772          ,lot_number
8773          ,subinventory_code
8774          ,locator_id
8775          ,lpn_id
8776          ,primary_reservation_quantity - NVL(detailed_quantity, 0)
8777          ,NVL(secondary_reservation_quantity, 0) - NVL(secondary_detailed_quantity, 0)           -- invConv change
8778    FROM mtl_reservations
8779   WHERE organization_id                      = g_rootinfos(l_root_id).organization_id
8780     AND inventory_item_id                    = g_rootinfos(l_root_id).inventory_item_id
8781     AND demand_source_type_id                = g_demand_info(p_tree_id).demand_source_type_id
8782     AND demand_source_header_id              = g_demand_info(p_tree_id).demand_source_header_id
8783     AND demand_source_line_id IS NULL
8784     AND demand_source_name IS NULL
8785     AND NVL(demand_source_delivery, -99999)  = NVL(g_demand_info(p_tree_id).demand_source_delivery, -99999)
8786     AND demand_source_line_detail IS NULL
8787     AND nvl(supply_source_type_id,13) = 13 ;                -- Bug 4194323
8788 
8789     -- pick release, query based on demand_source_line_id
8790   -- Bug 4494038: exclude crossdock reservations
8791   CURSOR c_demand_stage_dl IS
8792   SELECT  revision
8793          ,lot_number
8794          ,subinventory_code
8795          ,locator_id
8796          ,lpn_id
8797          ,primary_reservation_quantity - NVL(detailed_quantity, 0)
8798          ,NVL(secondary_reservation_quantity, 0) - NVL(secondary_detailed_quantity, 0)           -- invConv change
8799    FROM mtl_reservations
8800    WHERE demand_source_line_id               = g_demand_info(p_tree_id).demand_source_line_id
8801     AND NVL(organization_id, 0)              = g_rootinfos(l_root_id).organization_id
8802     AND NVL(inventory_item_id,0)             = g_rootinfos(l_root_id).inventory_item_id
8803     AND demand_source_type_id                = g_demand_info(p_tree_id).demand_source_type_id
8804     AND demand_source_header_id              = g_demand_info(p_tree_id).demand_source_header_id
8805     AND NVL(demand_source_name, '@@@###@@#') = NVL(g_demand_info(p_tree_id).demand_source_name, '@@@###@@#')
8806     AND NVL(demand_source_delivery, -99999)  = NVL(g_demand_info(p_tree_id).demand_source_delivery, -99999)
8807     AND NVL(staged_flag, 'N') = 'N'
8808     AND demand_source_line_detail IS NULL
8809     AND nvl(supply_source_type_id,13) = 13 ;                -- Bug 4194323
8810 
8811   -- pick release, query based on demand_source_name
8812   -- Bug 4494038: exclude crossdock reservations
8813   CURSOR c_demand_stage_dn IS
8814   SELECT  revision
8815          ,lot_number
8816          ,subinventory_code
8817          ,locator_id
8818          ,lpn_id
8819          ,primary_reservation_quantity - NVL(detailed_quantity, 0)
8820          ,NVL(secondary_reservation_quantity, 0) - NVL(secondary_detailed_quantity, 0)           -- invConv change
8821    FROM mtl_reservations
8822   WHERE organization_id                      = g_rootinfos(l_root_id).organization_id
8823     AND inventory_item_id                    = g_rootinfos(l_root_id).inventory_item_id
8824     AND demand_source_type_id                = g_demand_info(p_tree_id).demand_source_type_id
8825     AND demand_source_header_id              = g_demand_info(p_tree_id).demand_source_header_id
8826     AND demand_source_name                   = g_demand_info(p_tree_id).demand_source_name
8827     AND demand_source_line_id IS NULL
8828     AND NVL(demand_source_delivery, -99999)  = NVL(g_demand_info(p_tree_id).demand_source_delivery, -99999)
8829     AND NVL(staged_flag, 'N') = 'N'
8830     AND demand_source_line_detail IS NULL
8831     AND nvl(supply_source_type_id,13) = 13 ;                -- Bug 4194323
8832 
8833   -- pick release, query based on org and item
8834   -- Bug 4494038: exclude crossdock reservations
8835   CURSOR c_demand_stage IS
8836   SELECT  revision
8837          ,lot_number
8838          ,subinventory_code
8839          ,locator_id
8840          ,lpn_id
8841          ,primary_reservation_quantity - NVL(detailed_quantity, 0)
8842          ,NVL(secondary_reservation_quantity, 0) - NVL(secondary_detailed_quantity, 0)           -- invConv change
8843    FROM mtl_reservations
8844   WHERE organization_id                      = g_rootinfos(l_root_id).organization_id
8845     AND inventory_item_id                    = g_rootinfos(l_root_id).inventory_item_id
8846     AND demand_source_type_id                = g_demand_info(p_tree_id).demand_source_type_id
8847     AND demand_source_header_id              = g_demand_info(p_tree_id).demand_source_header_id
8848     AND demand_source_line_id IS NULL
8849     AND demand_source_name = NULL
8850     AND NVL(demand_source_delivery, -99999)  = NVL(g_demand_info(p_tree_id).demand_source_delivery, -99999)
8851     AND NVL(staged_flag, 'N') = 'N'
8852     AND demand_source_line_detail IS NULL
8853     AND nvl(supply_source_type_id,13) = 13 ;                -- Bug 4194323
8854   is_lot_control Boolean :=false; -- Bug 4194323
8855 BEGIN
8856 
8857    x_return_status := fnd_api.g_ret_sts_success;
8858    g_rsv_info.DELETE;
8859    g_rsv_counter := 0;
8860    l_root_id := g_demand_info(p_tree_id).root_id;
8861    is_lot_control:=g_rootinfos(l_root_id).is_lot_control;
8862    print_debug('in add_demand_qty, tree='||p_tree_id||', root='||l_root_id||', pick_release:'||g_demand_info(p_tree_id).pick_release||' ?= pick_release_yes:'||g_pick_release_yes);
8863    print_debug('demand_source__line_id='||g_demand_info(p_tree_id).demand_source_line_id);
8864    IF g_demand_info(p_tree_id).pick_release = g_pick_release_yes THEN
8865 
8866       -- have to make sure we don't picking from staging location
8867       if g_demand_info(p_tree_id).demand_source_line_id IS NOT NULL THEN
8868          OPEN c_demand_stage_dl;
8869          LOOP
8870             FETCH c_demand_stage_dl INTO
8871                   l_revision
8872                  ,l_lot_number
8873                  ,l_subinventory_code
8874                  ,l_locator_id
8875                  ,l_lpn_id
8876                  ,l_quantity
8877                  ,l_quantity2;                          -- invConv change
8878 
8879             EXIT WHEN c_demand_stage_dl%NOTFOUND;
8880 
8881             print_debug('in add_demand_qty, calling add_quantities, lot='||substr(l_lot_number,1,10)||', subinv='||l_subinventory_code||', loct_id='||l_locator_id||', qty1='||(l_mult * l_quantity)||', qty2='||(l_mult * l_quantity2)||'.');
8882             add_quantities(
8883                  x_return_status     => x_return_status
8884                , p_tree_id           => l_root_id
8885                , p_revision          => l_revision
8886                , p_lot_number        => l_lot_number
8887                , p_subinventory_code => l_subinventory_code
8888                , p_is_reservable_sub => TRUE
8889                , p_locator_id        => l_locator_id
8890                , p_primary_quantity  => l_mult * l_quantity
8891                , p_secondary_quantity=> l_mult * l_quantity2               -- invConv change
8892                , p_quantity_type     => g_qr_other_demand
8893                , p_set_check_mark    => FALSE
8894                , p_cost_group_id     => NULL
8895                , p_lpn_id            => l_lpn_id
8896                  );
8897 
8898             print_debug('... after add_quantities... x_return_status='||x_return_status||', qty='||l_quantity||', qty2='||l_quantity2);
8899             IF x_return_status = fnd_api.g_ret_sts_error THEN
8900                RAISE fnd_api.g_exc_error;
8901             ELSIF x_return_status = fnd_api.g_ret_sts_unexp_error THEN
8902                RAISE fnd_api.g_exc_unexpected_error;
8903             END IF;
8904 
8905             g_rsv_counter := g_rsv_counter + 1;
8906             g_rsv_info(g_rsv_counter).revision := l_revision;
8907             g_rsv_info(g_rsv_counter).lot_number := l_lot_number;
8908             g_rsv_info(g_rsv_counter).subinventory_code := l_subinventory_code;
8909             g_rsv_info(g_rsv_counter).locator_id := l_locator_id;
8910             g_rsv_info(g_rsv_counter).lpn_id := l_lpn_id;
8911             g_rsv_info(g_rsv_counter).quantity := l_quantity;
8912             g_rsv_info(g_rsv_counter).secondary_quantity := l_quantity2;   -- invConv change
8913          END LOOP;
8914          CLOSE c_demand_stage_dl;
8915       ELSIF g_demand_info(p_tree_id).demand_source_name IS NOT NULL then
8916          OPEN c_demand_stage_dn;
8917          LOOP
8918             FETCH c_demand_stage_dn INTO
8919                   l_revision
8920                  ,l_lot_number
8921                  ,l_subinventory_code
8922                  ,l_locator_id
8923                  ,l_lpn_id
8924                  ,l_quantity
8925                  ,l_quantity2;                          -- invConv change
8926 
8927             EXIT WHEN c_demand_stage_dn%NOTFOUND;
8928 
8929             print_debug('in add_demand_qty, calling add_quantities 2, lot='||substr(l_lot_number,1,10)||', subinv='||l_subinventory_code||', loct_id='||l_locator_id||', qty1='||(l_mult * l_quantity)||', qty2='||(l_mult * l_quantity2)||'.');
8930             add_quantities(
8931                  x_return_status     => x_return_status
8932                , p_tree_id           => l_root_id
8933                , p_revision          => l_revision
8934                , p_lot_number        => l_lot_number
8935                , p_subinventory_code => l_subinventory_code
8936                , p_is_reservable_sub => TRUE
8937                , p_locator_id        => l_locator_id
8938                , p_primary_quantity  => l_mult * l_quantity
8939                , p_secondary_quantity=> l_mult * l_quantity2               -- invConv change
8940                , p_quantity_type     => g_qr_other_demand
8941                , p_set_check_mark    => FALSE
8942                , p_cost_group_id     => NULL
8943                , p_lpn_id      => l_lpn_id
8944                  );
8945 
8946             print_debug('... after add_quantities 2... x_return_status='||x_return_status||', qty='||l_quantity||', qty2='||l_quantity2);
8947 
8948             IF x_return_status = fnd_api.g_ret_sts_error THEN
8949                RAISE fnd_api.g_exc_error;
8950             ELSIF x_return_status = fnd_api.g_ret_sts_unexp_error THEN
8951                RAISE fnd_api.g_exc_unexpected_error;
8952             END IF;
8953 
8954             g_rsv_counter := g_rsv_counter + 1;
8955             g_rsv_info(g_rsv_counter).revision := l_revision;
8956             g_rsv_info(g_rsv_counter).lot_number := l_lot_number;
8957             g_rsv_info(g_rsv_counter).subinventory_code := l_subinventory_code;
8958             g_rsv_info(g_rsv_counter).locator_id := l_locator_id;
8959             g_rsv_info(g_rsv_counter).lpn_id := l_lpn_id;
8960             g_rsv_info(g_rsv_counter).quantity := l_quantity;
8961             g_rsv_info(g_rsv_counter).secondary_quantity := l_quantity2;   -- invConv change
8962          END LOOP;
8963          CLOSE c_demand_stage_dn;
8964       else
8965          OPEN c_demand_stage;
8966          LOOP
8967             FETCH c_demand_stage INTO
8968                   l_revision
8969                  ,l_lot_number
8970                  ,l_subinventory_code
8971                  ,l_locator_id
8972                  ,l_lpn_id
8973                  ,l_quantity
8974                  ,l_quantity2;                          -- invConv change
8975 
8976             EXIT WHEN c_demand_stage%NOTFOUND;
8977 
8978             print_debug('in add_demand_qty, calling add_quantities 3, lot='||substr(l_lot_number,1,10)||', subinv='||l_subinventory_code||', loct_id='||l_locator_id||', qty1='||(l_mult * l_quantity)||', qty2='||(l_mult * l_quantity2)||'.');
8979             add_quantities(
8980                  x_return_status     => x_return_status
8981                , p_tree_id           => l_root_id
8982                , p_revision          => l_revision
8983                , p_lot_number        => l_lot_number
8984                , p_subinventory_code => l_subinventory_code
8985                , p_is_reservable_sub => TRUE
8986                , p_locator_id        => l_locator_id
8987                , p_primary_quantity  => l_mult * l_quantity
8988                , p_secondary_quantity=> l_mult * l_quantity2               -- invConv change
8989                , p_quantity_type     => g_qr_other_demand
8990                , p_set_check_mark    => FALSE
8991                , p_cost_group_id     => NULL
8992                , p_lpn_id            => l_lpn_id
8993                  );
8994 
8995             print_debug('... after add_quantities 3... x_return_status='||x_return_status||', qty='||l_quantity||', qty2='||l_quantity2);
8996 
8997             IF x_return_status = fnd_api.g_ret_sts_error THEN
8998                RAISE fnd_api.g_exc_error;
8999             ELSIF x_return_status = fnd_api.g_ret_sts_unexp_error THEN
9000                RAISE fnd_api.g_exc_unexpected_error;
9001             END IF;
9002 
9003             g_rsv_counter := g_rsv_counter + 1;
9004             g_rsv_info(g_rsv_counter).revision := l_revision;
9005             g_rsv_info(g_rsv_counter).lot_number := l_lot_number;
9006             g_rsv_info(g_rsv_counter).subinventory_code := l_subinventory_code;
9007             g_rsv_info(g_rsv_counter).locator_id := l_locator_id;
9008             g_rsv_info(g_rsv_counter).lpn_id := l_lpn_id;
9009             g_rsv_info(g_rsv_counter).quantity := l_quantity;
9010             g_rsv_info(g_rsv_counter).secondary_quantity := l_quantity2;   -- invConv change
9011          END LOOP;
9012          CLOSE c_demand_stage;
9013       end if;
9014    ELSE
9015       if g_demand_info(p_tree_id).demand_source_line_id IS NOT NULL THEN
9016          OPEN c_demand_dl;
9017          LOOP
9018             FETCH c_demand_dl INTO
9019                   l_revision
9020                  ,l_lot_number
9021                  ,l_subinventory_code
9022                  ,l_locator_id
9023                  ,l_lpn_id
9024                  ,l_quantity
9025                  ,l_quantity2;                          -- invConv change
9026 
9027             if NOT is_lot_control then  -- Bug 4194323
9028                l_lot_number:=null;
9029             end if;
9030 
9031             EXIT WHEN c_demand_dl%NOTFOUND;
9032 
9033             print_debug('in add_demand_qty, calling add_quantities 4, lot='||substr(l_lot_number,1,10)||', subinv='||l_subinventory_code||', loct_id='||l_locator_id||', qty1='||(l_mult * l_quantity)||', qty2='||(l_mult * l_quantity2)||'.');
9034             add_quantities(
9035                  x_return_status     => x_return_status
9036                , p_tree_id           => l_root_id
9037                , p_revision          => l_revision
9038                , p_lot_number        => l_lot_number
9039                , p_subinventory_code => l_subinventory_code
9040                , p_is_reservable_sub => TRUE
9041                , p_locator_id        => l_locator_id
9042                , p_primary_quantity  => l_mult * l_quantity
9043                , p_secondary_quantity=> l_mult * l_quantity2               -- invConv change
9044                , p_quantity_type     => g_qr_other_demand
9045                , p_set_check_mark    => FALSE
9046                , p_cost_group_id     => NULL
9047                , p_lpn_id            => l_lpn_id
9048                  );
9049 
9050             print_debug('... after add_quantities 4... x_return_status='||x_return_status||', qty='||l_quantity||', qty2='||l_quantity2);
9051 
9052             IF x_return_status = fnd_api.g_ret_sts_error THEN
9053                RAISE fnd_api.g_exc_error;
9054             ELSIF x_return_status = fnd_api.g_ret_sts_unexp_error THEN
9055                RAISE fnd_api.g_exc_unexpected_error;
9056             END IF;
9057 
9058             g_rsv_counter := g_rsv_counter + 1;
9059             g_rsv_info(g_rsv_counter).revision := l_revision;
9060             g_rsv_info(g_rsv_counter).lot_number := l_lot_number;
9061             g_rsv_info(g_rsv_counter).subinventory_code := l_subinventory_code;
9062             g_rsv_info(g_rsv_counter).locator_id := l_locator_id;
9063             g_rsv_info(g_rsv_counter).lpn_id := l_lpn_id;
9064             g_rsv_info(g_rsv_counter).quantity := l_quantity;
9065             g_rsv_info(g_rsv_counter).secondary_quantity := l_quantity2;   -- invConv change
9066 
9067         END LOOP;
9068         CLOSE c_demand_dl;
9069      elsif g_demand_info(p_tree_id).demand_source_name IS NOT NULL THEN
9070         OPEN c_demand_dn;
9071         LOOP
9072            FETCH c_demand_dn INTO
9073                   l_revision
9074                  ,l_lot_number
9075                  ,l_subinventory_code
9076                  ,l_locator_id
9077                  ,l_lpn_id
9078                  ,l_quantity
9079                  ,l_quantity2;                          -- invConv change
9080 
9081             EXIT WHEN c_demand_dn%NOTFOUND;
9082 
9083             print_debug('in add_demand_qty, calling add_quantities 5, lot='||substr(l_lot_number,1,10)||', subinv='||l_subinventory_code||', loct_id='||l_locator_id||', qty1='||(l_mult * l_quantity)||', qty2='||(l_mult * l_quantity2)||'.');
9084             add_quantities(
9085                  x_return_status     => x_return_status
9086                , p_tree_id           => l_root_id
9087                , p_revision          => l_revision
9088                , p_lot_number        => l_lot_number
9089                , p_subinventory_code => l_subinventory_code
9090                , p_is_reservable_sub => TRUE
9091                , p_locator_id        => l_locator_id
9092                , p_primary_quantity  => l_mult * l_quantity
9093                , p_secondary_quantity=> l_mult * l_quantity2               -- invConv change
9094                , p_quantity_type     => g_qr_other_demand
9095                , p_set_check_mark    => FALSE
9096                , p_cost_group_id     => NULL
9097                , p_lpn_id            => l_lpn_id
9098                  );
9099 
9100             print_debug('... after add_quantities 5... x_return_status='||x_return_status||', qty='||l_quantity||', qty2='||l_quantity2);
9101 
9102             IF x_return_status = fnd_api.g_ret_sts_error THEN
9103                RAISE fnd_api.g_exc_error;
9104             ELSIF x_return_status = fnd_api.g_ret_sts_unexp_error THEN
9105                RAISE fnd_api.g_exc_unexpected_error;
9106             END IF;
9107 
9108             g_rsv_counter := g_rsv_counter + 1;
9109             g_rsv_info(g_rsv_counter).revision := l_revision;
9110             g_rsv_info(g_rsv_counter).lot_number := l_lot_number;
9111             g_rsv_info(g_rsv_counter).subinventory_code := l_subinventory_code;
9112             g_rsv_info(g_rsv_counter).locator_id := l_locator_id;
9113             g_rsv_info(g_rsv_counter).lpn_id := l_lpn_id;
9114             g_rsv_info(g_rsv_counter).quantity := l_quantity;
9115             g_rsv_info(g_rsv_counter).secondary_quantity := l_quantity2;   -- invConv change
9116 
9117         END LOOP;
9118         CLOSE c_demand_dn;
9119      else
9120         OPEN c_demand;
9121         LOOP
9122             FETCH  c_demand INTO
9123                   l_revision
9124                  ,l_lot_number
9125                  ,l_subinventory_code
9126                  ,l_locator_id
9127                  ,l_lpn_id
9128                  ,l_quantity
9129                  ,l_quantity2;                          -- invConv change
9130 
9131             EXIT WHEN c_demand%NOTFOUND;
9132 
9133             print_debug('in add_demand_qty, calling add_quantities 6, lot='||substr(l_lot_number,1,10)||', subinv='||l_subinventory_code||', loct_id='||l_locator_id||', qty1='||(l_mult * l_quantity)||', qty2='||(l_mult * l_quantity2)||'.');
9134             add_quantities(
9135                  x_return_status     => x_return_status
9136                , p_tree_id           => l_root_id
9137                , p_revision          => l_revision
9138                , p_lot_number        => l_lot_number
9139                , p_subinventory_code => l_subinventory_code
9140                , p_is_reservable_sub => TRUE
9141                , p_locator_id        => l_locator_id
9142                , p_primary_quantity  => l_mult * l_quantity
9143                , p_secondary_quantity=> l_mult * l_quantity2               -- invConv change
9144                , p_quantity_type     => g_qr_other_demand
9145                , p_set_check_mark    => FALSE
9146                , p_cost_group_id     => NULL
9147                , p_lpn_id            => l_lpn_id
9148                  );
9149 
9150             print_debug('... after add_quantities 6... x_return_status='||x_return_status||', qty='||l_quantity||', qty2='||l_quantity2);
9151 
9152             IF x_return_status = fnd_api.g_ret_sts_error THEN
9153                RAISE fnd_api.g_exc_error;
9154             ELSIF x_return_status = fnd_api.g_ret_sts_unexp_error THEN
9155                RAISE fnd_api.g_exc_unexpected_error;
9156             END IF;
9157 
9158             g_rsv_counter := g_rsv_counter + 1;
9159             g_rsv_info(g_rsv_counter).revision := l_revision;
9160             g_rsv_info(g_rsv_counter).lot_number := l_lot_number;
9161             g_rsv_info(g_rsv_counter).subinventory_code := l_subinventory_code;
9162             g_rsv_info(g_rsv_counter).locator_id := l_locator_id;
9163             g_rsv_info(g_rsv_counter).lpn_id := l_lpn_id;
9164             g_rsv_info(g_rsv_counter).quantity := l_quantity;
9165             g_rsv_info(g_rsv_counter).secondary_quantity := l_quantity2;   -- invConv change
9166 
9167         END LOOP;
9168         CLOSE c_demand;
9169      end if;
9170    END IF;
9171    print_debug('... ending add_demand_qty');
9172 
9173 EXCEPTION
9174    WHEN fnd_api.g_exc_error THEN
9175         x_return_status := fnd_api.g_ret_sts_error;
9176 
9177    WHEN fnd_api.g_exc_unexpected_error THEN
9178         x_return_status := fnd_api.g_ret_sts_unexp_error ;
9179 
9180    WHEN OTHERS THEN
9181       x_return_status := fnd_api.g_ret_sts_unexp_error ;
9182       IF fnd_msg_pub.check_msg_level(fnd_msg_pub.g_msg_lvl_unexp_error)
9183         THEN
9184          fnd_msg_pub.add_exc_msg
9185            (  g_pkg_name
9186               ,'Add_Demand_Qty'
9187               );
9188       END IF;
9189 END add_demand_qty;
9190 
9191 
9192 --subtract_demand_qty
9193 -- This counteracts the actions of add_demand_qty.
9194 -- For each record in the rsv_info table, add_quantities is called,
9195 -- which increases QR and decrease ATT.
9196 PROCEDURE subtract_demand_qty(
9197     x_return_status  OUT NOCOPY VARCHAR2
9198         ,p_tree_id     IN  INTEGER
9199  ) IS
9200 
9201   l_root_id    INTEGER;
9202 
9203 BEGIN
9204    print_debug('... entering subtract_demand_qty');
9205 
9206    x_return_status := fnd_api.g_ret_sts_success;
9207 
9208    l_root_id := g_demand_info(p_tree_id).root_id;
9209 
9210    FOR i in 1..g_rsv_counter LOOP
9211       print_debug('in subtract_demand_qty, calling add_quantities, qty1='||g_rsv_info(i).quantity||', qty2='||g_rsv_info(i).secondary_quantity||';');
9212 
9213       add_quantities(
9214               x_return_status     => x_return_status
9215             , p_tree_id           => l_root_id
9216             , p_revision          => g_rsv_info(i).revision
9217             , p_lot_number        => g_rsv_info(i).lot_number
9218             , p_subinventory_code => g_rsv_info(i).subinventory_code
9219             , p_is_reservable_sub => TRUE
9220             , p_locator_id        => g_rsv_info(i).locator_id
9221             , p_primary_quantity  => g_rsv_info(i).quantity
9222             , p_secondary_quantity=> g_rsv_info(i).secondary_quantity         -- invConv change
9223             , p_quantity_type     => g_qr_other_demand
9224             , p_set_check_mark    => FALSE
9225             , p_cost_group_id     => NULL
9226             , p_lpn_id            => g_rsv_info(i).lpn_id
9227               );
9228 
9229       IF x_return_status = fnd_api.g_ret_sts_error THEN
9230          RAISE fnd_api.g_exc_error;
9231       ELSIF x_return_status = fnd_api.g_ret_sts_unexp_error THEN
9232          RAISE fnd_api.g_exc_unexpected_error;
9233       END IF;
9234 
9235    END LOOP;
9236 
9237 EXCEPTION
9238    WHEN fnd_api.g_exc_error THEN
9239         x_return_status := fnd_api.g_ret_sts_error;
9240 
9241    WHEN fnd_api.g_exc_unexpected_error THEN
9242         x_return_status := fnd_api.g_ret_sts_unexp_error ;
9243 
9244    WHEN OTHERS THEN
9245       x_return_status := fnd_api.g_ret_sts_unexp_error ;
9246       IF fnd_msg_pub.check_msg_level(fnd_msg_pub.g_msg_lvl_unexp_error)
9247         THEN
9248          fnd_msg_pub.add_exc_msg
9249            (  g_pkg_name
9250               ,'Subtract_Demand_Qty'
9251               );
9252       END IF;
9253 END subtract_demand_qty;
9254 
9255 --check_demand_trees
9256 --    Returns TRUE if two entries in the demand info
9257 -- plsql table are equivalent.  Used to determine if the
9258 -- demand info needs to be subtracted from the qty tree.
9259 FUNCTION check_demand_trees(
9260          p_rsv_tree    IN  INTEGER
9261    ,p_new_tree   IN  INTEGER
9262  ) RETURN BOOLEAN IS
9263 
9264 BEGIN
9265 
9266   IF (g_demand_info(p_rsv_tree).root_id = g_demand_info(p_new_tree).root_id)
9267     AND
9268      (g_demand_info(p_rsv_tree).demand_source_type_id = g_demand_info(p_new_tree).demand_source_type_id)
9269     AND
9270      ((g_demand_info(p_rsv_tree).demand_source_header_id IS NULL AND
9271        g_demand_info(p_new_tree).demand_source_header_id IS NULL) OR
9272       (g_demand_info(p_rsv_tree).demand_source_header_id = g_demand_info(p_new_tree).demand_source_header_id))
9273     AND
9274      ((g_demand_info(p_rsv_tree).demand_source_line_id IS NULL AND
9275        g_demand_info(p_new_tree).demand_source_line_id IS NULL) OR
9276       (g_demand_info(p_rsv_tree).demand_source_line_id = g_demand_info(p_new_tree).demand_source_line_id))
9277     AND
9278      ((g_demand_info(p_rsv_tree).demand_source_name IS NULL AND
9279        g_demand_info(p_new_tree).demand_source_name IS NULL) OR
9280       (g_demand_info(p_rsv_tree).demand_source_name = g_demand_info(p_new_tree).demand_source_name))
9281     AND
9282      ((g_demand_info(p_rsv_tree).demand_source_delivery IS NULL AND
9283        g_demand_info(p_new_tree).demand_source_delivery IS NULL) OR
9284       (g_demand_info(p_rsv_tree).demand_source_delivery = g_demand_info(p_new_tree).demand_source_delivery))
9285     AND
9286      ((g_demand_info(p_rsv_tree).pick_release IS NULL AND
9287        g_demand_info(p_new_tree).pick_release IS NULL) OR
9288       (g_demand_info(p_rsv_tree).pick_release = g_demand_info(p_new_tree).pick_release))
9289   THEN
9290      return TRUE;
9291   ELSE
9292      return FALSE;
9293   END IF;
9294 END check_demand_trees;
9295 
9296 -- Public Functions and Procedures
9297 
9298 PROCEDURE clear_quantity_cache IS
9299 BEGIN
9300    g_rootinfos.DELETE;
9301    g_nodes.DELETE;
9302    g_rootinfo_counter :=0;
9303    g_org_item_trees.DELETE;
9304    g_all_roots.DELETE;
9305    g_all_roots_counter := 0;
9306    g_saveroots.DELETE;
9307    g_nodes.DELETE;
9308    g_demand_info.DELETE;
9309    g_demand_counter := 0;
9310    g_rsv_info.DELETE;
9311    g_rsv_counter := 0;
9312    g_rsv_tree_id := 0;
9313    g_max_hash_rec := 0;
9314    print_debug('All Quantity Trees distroyed',9);
9315 END clear_quantity_cache;
9316 
9317 -- Procedure
9318 --   query tree
9319 --
9320 --  Version
9321 --   Current version       1.0
9322 --   Initial version       1.0
9323 --
9324 -- Input parameters:
9325 --   p_api_version_number   standard input parameter
9326 --   p_init_msg_lst         standard input parameter
9327 --   p_tree_id              tree_id
9328 --   p_revision             revision
9329 --   p_lot_number           lot_number
9330 --   p_subinventory_code    subinventory code
9331 --   p_locator_id           locator_id
9332 --
9333 -- Output parameters:
9334 --   x_return_status       standard output parameter
9335 --   x_msg_count           standard output parameter
9336 --   x_msg_data            standard output parameter
9337 --   x_qoh                 qoh
9338 --   x_rqoh                rqoh
9339 --   x_qr                  qr
9340 --   x_qs                  qs
9341 --   x_att                 att
9342 --   x_atr                 atr
9343 --
9344 PROCEDURE query_tree
9345   (   p_api_version_number   IN  NUMBER
9346    ,  p_init_msg_lst         IN  VARCHAR2
9347    ,  x_return_status        OUT NOCOPY VARCHAR2
9348    ,  x_msg_count            OUT NOCOPY NUMBER
9349    ,  x_msg_data             OUT NOCOPY VARCHAR2
9350    ,  p_tree_id              IN  INTEGER
9351    ,  p_revision             IN  VARCHAR2
9352    ,  p_lot_number           IN  VARCHAR2
9353    ,  p_subinventory_code    IN  VARCHAR2
9354    ,  p_locator_id           IN  NUMBER
9355    ,  x_qoh                  OUT NOCOPY NUMBER
9356    ,  x_rqoh                 OUT NOCOPY NUMBER
9357    ,  x_qr                   OUT NOCOPY NUMBER
9358    ,  x_qs                   OUT NOCOPY NUMBER
9359    ,  x_att                  OUT NOCOPY NUMBER
9360    ,  x_atr                  OUT NOCOPY NUMBER
9361    ,  p_transfer_subinventory_code IN  VARCHAR2
9362    ,  p_cost_group_id        IN  NUMBER
9363    ,  p_lpn_id               IN  NUMBER
9364    ,  p_transfer_locator_id  IN  NUMBER
9365    ) IS
9366 
9367    l_sqoh    NUMBER;     -- invConv change
9368    l_srqoh   NUMBER;     -- invConv change
9369    l_sqr     NUMBER;     -- invConv change
9370    l_sqs     NUMBER;     -- invConv change
9371    l_satt    NUMBER;     -- invConv change
9372    l_satr    NUMBER;     -- invConv change
9373 
9374 BEGIN
9375    -- invConv changes begin:
9376    -- Calling the new signature API.
9377    query_tree(
9378       p_api_version_number  =>  p_api_version_number
9379    ,  p_init_msg_lst        =>  p_init_msg_lst
9380    ,  x_return_status       =>  x_return_status
9381    ,  x_msg_count           =>  x_msg_count
9382    ,  x_msg_data            =>  x_msg_data
9383    ,  p_tree_id             =>  p_tree_id
9384    ,  p_revision            =>  p_revision
9385    ,  p_lot_number          =>  p_lot_number
9386    ,  p_subinventory_code   =>  p_subinventory_code
9387    ,  p_locator_id          =>  p_locator_id
9388    ,  x_qoh                 =>  x_qoh
9389    ,  x_rqoh                =>  x_rqoh
9390    ,  x_qr                  =>  x_qr
9391    ,  x_qs                  =>  x_qs
9392    ,  x_att                 =>  x_att
9393    ,  x_atr                 =>  x_atr
9394    ,  x_sqoh                =>  l_sqoh           -- invConv change
9395    ,  x_srqoh               =>  l_srqoh          -- invConv change
9396    ,  x_sqr                 =>  l_sqr            -- invConv change
9397    ,  x_sqs                 =>  l_sqs            -- invConv change
9398    ,  x_satt                =>  l_satt           -- invConv change
9399    ,  x_satr                =>  l_satr           -- invConv change
9400    ,  p_transfer_subinventory_code => p_transfer_subinventory_code
9401    ,  p_cost_group_id       =>  p_cost_group_id
9402    ,  p_lpn_id              =>  p_lpn_id
9403    ,  p_transfer_locator_id =>  p_transfer_locator_id
9404    );
9405 
9406    -- Calling the new signature API.
9407 
9408 END query_tree;
9409 
9410 PROCEDURE query_tree
9411   (   p_api_version_number   IN  NUMBER
9412    ,  p_init_msg_lst         IN  VARCHAR2
9413    ,  x_return_status        OUT NOCOPY VARCHAR2
9414    ,  x_msg_count            OUT NOCOPY NUMBER
9415    ,  x_msg_data             OUT NOCOPY VARCHAR2
9416    ,  p_tree_id              IN  INTEGER
9417    ,  p_revision             IN  VARCHAR2
9418    ,  p_lot_number           IN  VARCHAR2
9419    ,  p_subinventory_code    IN  VARCHAR2
9420    ,  p_locator_id           IN  NUMBER
9421    ,  x_qoh                  OUT NOCOPY NUMBER
9422    ,  x_rqoh                 OUT NOCOPY NUMBER
9423    ,  x_qr                   OUT NOCOPY NUMBER
9424    ,  x_qs                   OUT NOCOPY NUMBER
9425    ,  x_att                  OUT NOCOPY NUMBER
9426    ,  x_atr                  OUT NOCOPY NUMBER
9427    ,  x_sqoh                 OUT NOCOPY NUMBER     -- invConv change
9428    ,  x_srqoh                OUT NOCOPY NUMBER     -- invConv change
9429    ,  x_sqr                  OUT NOCOPY NUMBER     -- invConv change
9430    ,  x_sqs                  OUT NOCOPY NUMBER     -- invConv change
9431    ,  x_satt                 OUT NOCOPY NUMBER     -- invConv change
9432    ,  x_satr                 OUT NOCOPY NUMBER     -- invConv change
9433    ,  p_transfer_subinventory_code IN  VARCHAR2
9434    ,  p_cost_group_id        IN  NUMBER
9435    ,  p_lpn_id               IN  NUMBER
9436    ,  p_transfer_locator_id  IN  NUMBER
9437    ) IS
9438       l_api_version_number   CONSTANT NUMBER       := 1.0;
9439       l_api_name             CONSTANT VARCHAR2(30) := 'QUERY_TREE';
9440       l_return_status        VARCHAR2(1) := fnd_api.g_ret_sts_success;
9441       l_node_index           INTEGER;
9442       l_atr                  NUMBER;
9443       l_att                  NUMBER;
9444       l_satr                 NUMBER;             -- invConv change
9445       l_satt                 NUMBER;             -- invConv change
9446       l_tree_id              NUMBER;             -- invConv change
9447       l_is_reservable_sub    BOOLEAN;
9448       l_is_reservable_transfer_sub BOOLEAN;
9449       l_found                BOOLEAN;
9450       l_loop_index           INTEGER;
9451       l_sub_index            NUMBER;
9452       l_root_id              INTEGER;
9453       l_lpn_id               NUMBER;
9454       l_is_reservable_item   BOOLEAN;
9455       --Bug 4294336
9456       l_atr2                 NUMBER;
9457       l_satr2                NUMBER;
9458 
9459 -- l_is_temp_table_used   VARCHAR2(2);   -- invConv
9460 -- ll_qoh    NUMBER;        -- invConv
9461 -- ll_rqoh   NUMBER;        -- invConv
9462 -- ll_pqoh   NUMBER;        -- invConv
9463 -- ll_qr     NUMBER;        -- invConv
9464 -- ll_qs     NUMBER;        -- invConv
9465 -- ll_att    NUMBER;        -- invConv
9466 -- ll_atr    NUMBER;        -- invConv
9467 -- ll_sqoh   NUMBER;        -- invConv
9468 -- ll_srqoh  NUMBER;        -- invConv
9469 -- ll_spqoh  NUMBER;        -- invConv
9470 -- ll_sqr    NUMBER;        -- invConv
9471 -- ll_sqs    NUMBER;        -- invConv
9472 -- ll_satt   NUMBER;        -- invConv
9473 -- ll_satr   NUMBER;        -- invConv
9474 
9475 BEGIN
9476    IF g_debug = 1 THEN
9477       print_debug(l_api_name || ' Entered',9);
9478    END IF;
9479 
9480    --  Standard call to check for call compatibility
9481    IF NOT fnd_api.compatible_api_call(l_api_version_number
9482                                       , p_api_version_number
9483                                       , l_api_name
9484                                       , G_PKG_NAME
9485                                       ) THEN
9486       RAISE fnd_api.g_exc_unexpected_error;
9487    END IF;
9488 
9489    --  Initialize message list.
9490    IF fnd_api.to_boolean(p_init_msg_lst) THEN
9491       fnd_msg_pub.initialize;
9492    END IF;
9493 
9494    l_root_id := g_demand_info(p_tree_id).root_id;
9495    -- check if tree id is valid
9496    IF is_tree_valid(l_root_id) = FALSE THEN
9497       fnd_message.set_name('INV', 'INV-Qtyroot not found');
9498       fnd_message.set_token('ROUTINE', 'Query_Tree');
9499       fnd_msg_pub.ADD;
9500       RAISE fnd_api.g_exc_error;
9501    END IF;
9502 
9503    print_debug('>>>>>> In query_tree, mode='||g_demand_info(p_tree_id).tree_mode||', tree_id='||p_tree_id
9504       ||'..for item='||g_rootinfos(l_root_id).inventory_item_id||' rev='||p_revision||' lot='||p_lot_number
9505       ||' sub='||p_subinventory_code||' loc='||p_locator_id||' lpn='||p_lpn_id,9);
9506 
9507    -- For unpacked quantities, cost group will be specified while
9508    -- LPN is NULL.  To handle this, we have a dummy LPN of lpn_Id
9509    -- -99999 to hold loose quantity. We only need to use this
9510    -- when the cost group is specified, but the LPN is Null.
9511    --
9512    -- With removal of Cost group from quantity tree, we no longer need
9513    -- to take this step
9514    /*
9515    *IF p_lpn_Id IS NULL AND p_cost_group_id IS NOT NULL THEN
9516    *   l_lpn_id := g_loose_lpn_id;
9517    *ELSE
9518    *   l_lpn_id := p_lpn_id;
9519    *END IF;
9520    */
9521 
9522    --subtract out reservations added when tree was queried in txn mode
9523    IF g_demand_info(p_tree_id).tree_mode = g_reservation_mode THEN
9524       print_debug('QT, RESERVATION MODE.. calling subtract_demand_qty, tree_id='||g_rsv_tree_id);
9525       if g_rsv_tree_id <> 0 then
9526          subtract_demand_qty(
9527               x_return_status => l_return_status
9528             , p_tree_id       => g_rsv_tree_id
9529          );
9530 
9531          IF l_return_status = fnd_api.g_ret_sts_error THEN
9532             RAISE fnd_api.g_exc_error;
9533          ELSIF l_return_status = fnd_api.g_ret_sts_unexp_error THEN
9534             RAISE fnd_api.g_exc_unexpected_error;
9535          END IF;
9536          g_rsv_tree_id := 0;
9537          g_rsv_counter := 0;
9538          g_rsv_info.DELETE;
9539       end if;
9540    ELSIF g_demand_info(p_tree_id).tree_mode = g_transaction_mode THEN
9541       --subtract out rsv info if the tree is currently for a diff demand source
9542       print_debug('QT, TRANSACTION MODE.. calling subtract_demand_qty (yes/no)?, rsv_tree_id='||g_rsv_tree_id);
9543       if g_rsv_tree_id <> 0 AND check_demand_trees(g_rsv_tree_id, p_tree_id) = FALSE then
9544 
9545          subtract_demand_qty(
9546               x_return_status => l_return_status
9547             , p_tree_id       => g_rsv_tree_id
9548          );
9549 
9550          IF l_return_status = fnd_api.g_ret_sts_error THEN
9551             RAISE fnd_api.g_exc_error;
9552          ELSIF l_return_status = fnd_api.g_ret_sts_unexp_error THEN
9553             RAISE fnd_api.g_exc_unexpected_error;
9554          END IF;
9555          g_rsv_tree_id := 0;
9556          g_rsv_counter := 0;
9557          g_rsv_info.DELETE;
9558       end if;
9559 
9560       if g_rsv_tree_id = 0 then
9561          print_debug('QT, TREE_ID==0.. calling add_demand_qty, tree_id='||g_rsv_tree_id);
9562          add_demand_qty(
9563                x_return_status => l_return_status
9564              , p_tree_id       => p_tree_id
9565              );
9566 
9567          IF l_return_status = fnd_api.g_ret_sts_error THEN
9568             RAISE fnd_api.g_exc_error;
9569          ELSIF l_return_status = fnd_api.g_ret_sts_unexp_error THEN
9570             RAISE fnd_api.g_exc_unexpected_error;
9571          END IF;
9572          g_rsv_tree_id := p_tree_id;
9573       end if;
9574    END IF;   -- tree_mode
9575 
9576    print_debug('QT, calling find_tree_node, tree_id='||l_root_id||', p_tree_id='||p_tree_id);
9577    l_found := find_tree_node(
9578                       x_return_status      => l_return_status
9579                     , p_tree_id            => l_root_id
9580                     , p_revision           => p_revision
9581                     , p_lot_number         => p_lot_number
9582                     , p_subinventory_code  => p_subinventory_code
9583                     , p_is_reservable_sub  => NULL
9584                     , p_locator_id         => p_locator_id
9585                     , x_node_index         => l_node_index
9586                     , p_lpn_id             => p_lpn_id
9587                     , p_cost_group_id      => p_cost_group_id
9588                     );
9589 
9590    IF l_return_status = fnd_api.g_ret_sts_error THEN
9591       RAISE fnd_api.g_exc_error;
9592    End IF ;
9593 
9594    IF l_return_status = fnd_api.g_ret_sts_unexp_error THEN
9595       RAISE fnd_api.g_exc_unexpected_error;
9596    End IF;
9597 
9598    IF l_found = FALSE THEN
9599       fnd_message.set_name('INV','INV-Cannot find node');
9600       fnd_message.set_token('ROUTINE', 'Query_Tree');
9601       fnd_msg_pub.ADD;
9602       RAISE fnd_api.g_exc_unexpected_error;
9603    End IF;
9604 
9605    x_qoh  := g_nodes(l_node_index).qoh;
9606    x_rqoh := g_nodes(l_node_index).rqoh;
9607    x_qr   := g_nodes(l_node_index).qr;
9608    x_qs   := g_nodes(l_node_index).qs;
9609    x_sqoh  := g_nodes(l_node_index).sqoh;      -- invConv change
9610    x_srqoh := g_nodes(l_node_index).srqoh;     -- invConv change
9611    x_sqr   := g_nodes(l_node_index).sqr;       -- invConv change
9612    x_sqs   := g_nodes(l_node_index).sqs;       -- invConv change
9613 
9614    g_pqoh := g_nodes(l_node_index).pqoh;
9615    g_spqoh := g_nodes(l_node_index).spqoh;     -- invConv change
9616 
9617   /*********************************************************************
9618    * Logic for finding ATT and ATR:
9619    *  (Secondary quantities follow the same computation)       -- invConv change
9620    * If Node is at Sub level or below
9621    *    Get reservable for From Sub and To Sub
9622    *    If From Sub is not reservable
9623    *       ATT = ATT of node; ATR = 0
9624    *    If From Sub = To Sub
9625    *       ATT = min(ATT of node, ATR of ancestor nodes below sub)
9626    *       ATR = min(ATR of node, ATR of ancestor nodes below sub)
9627    *         (don't need to look at upper reservations, since all reservations
9628    *          except those at Locator and lpn level are not affected by move)
9629    *    If To Sub is Reservable
9630    *       ATT = min(ATT of node, ATR of ancestor nodes up to sub)
9631    *       ATR = min(ATR of node, ATR of ancestor nodes up to sub)
9632    *          (don't need to look at upper reservations, since
9633    *           all reservations
9634    *           above Sub level are not affected by move)
9635    *    Else (From Sub is reservable and To Sub is not Reservable)
9636    *       ATT = min (ATT of node, ATR of all ancestor nodes)
9637    *       ATR = min (ATR of node, ATR of all ancestor nodes)
9638    * Else (node above sub level)
9639    *    ATR = min (ATR at node, ATR of all ancestor nodes)
9640    *    ATT = min (ATT at node, ATT of all ancestor nodes)
9641    *********************************************************************/
9642 
9643 
9644    print_debug('QT, calling ATT/ATR computation, tree_id='||g_rsv_tree_id||', subinv='||p_subinventory_code);
9645    -- find out reservable_type if sub code is not null
9646    IF (p_subinventory_code IS NOT NULL) THEN
9647 
9648       l_sub_index := get_ancestor_sub(l_node_index);
9649       print_debug('--after get_ancestor_sub... node_index='||l_node_index||', l_sub_index='||l_sub_index||', level='||g_nodes(l_sub_index).node_level);
9650       l_is_reservable_sub:=g_nodes(l_sub_index).is_reservable_sub;
9651       -- invConv changes begin :
9652       IF l_is_reservable_sub = TRUE
9653       THEN
9654           print_debug('.... is reservable_sub=TRUE');
9655       ELSIF l_is_reservable_sub = FALSE
9656       THEN
9657           print_debug('.... is reservable_sub=FALSES');
9658       ELSE
9659           print_debug('.... is reservable_sub=other value');
9660       END IF;
9661 
9662       -- get that info from db table if not in the node
9663       -- invConv changes begin (test changes)
9664       --     why: because, if reservable_sub=FALSE, everything below will be NON-reservable.
9665       --                   if reservable_sub=TRUE, must check the other level.
9666       -- IF l_is_reservable_sub IS NULL  THEN
9667       IF (l_is_reservable_sub IS NULL OR l_is_reservable_sub = TRUE)
9668       THEN
9669          -- invConv changes begin (replaced call)
9670          --check_is_reservable_sub
9671          --  (
9672          --     x_return_status     => l_return_status
9673          --   , p_organization_id   => g_rootinfos(l_root_id).organization_id
9674          --   , p_subinventory_code => p_subinventory_code
9675          --   , x_is_reservable_sub => l_is_reservable_sub
9676          --   );
9677          check_is_reservable
9678               ( x_return_status     => l_return_status
9679               , p_inventory_item_id => g_rootinfos(l_root_id).inventory_item_id
9680               , p_organization_id   => g_rootinfos(l_root_id).organization_id
9681               , p_subinventory_code => p_subinventory_code
9682               , p_locator_id        => p_locator_id
9683               , p_lot_number        => p_lot_number
9684               , p_root_id           => l_root_id
9685               , x_is_reservable     => l_is_reservable_sub
9686               , p_lpn_id            => p_lpn_id); -- Onhand Material Status Support
9687 
9688             -- invConv changes end
9689 
9690          IF l_return_status = fnd_api.g_ret_sts_error THEN
9691             RAISE fnd_api.g_exc_error;
9692          End IF ;
9693 
9694          IF l_return_status = fnd_api.g_ret_sts_unexp_error THEN
9695             RAISE fnd_api.g_exc_unexpected_error;
9696          End IF;
9697 
9698       END IF;   -- l_is_reservable_sub
9699 
9700       --get reservable type for to sub
9701       IF (p_transfer_subinventory_code IS NOT NULL) THEN
9702          -- invConv changes begin (replaced call)
9703          -- check_is_reservable_sub
9704          --   (
9705          --     x_return_status     => l_return_status
9706          --   , p_organization_id   => g_rootinfos(l_root_id).organization_id
9707          --   , p_subinventory_code => p_transfer_subinventory_code
9708          --   , x_is_reservable_sub => l_is_reservable_transfer_sub
9709          --    );
9710          check_is_reservable
9711               ( x_return_status     => l_return_status
9712               , p_inventory_item_id => g_rootinfos(l_root_id).inventory_item_id
9713               , p_organization_id   => g_rootinfos(l_root_id).organization_id
9714               , p_subinventory_code => p_transfer_subinventory_code
9715               , p_locator_id        => p_locator_id
9716               , p_lot_number        => p_lot_number
9717               , p_root_id           => l_root_id
9718               , x_is_reservable     => l_is_reservable_transfer_sub
9719               , p_lpn_id            => p_lpn_id); -- Onhand Material Status Support
9720 
9721             -- invConv changes end
9722 
9723          IF l_return_status = fnd_api.g_ret_sts_error THEN
9724             RAISE fnd_api.g_exc_error;
9725          End IF ;
9726 
9727          IF l_return_status = fnd_api.g_ret_sts_unexp_error THEN
9728             RAISE fnd_api.g_exc_unexpected_error;
9729          End IF;
9730       ELSE
9731          l_is_reservable_transfer_sub := FALSE;
9732       END IF;     -- p_transfer_subinventory_code
9733 
9734       --From sub is not reservable
9735       IF l_is_reservable_sub = FALSE THEN
9736           l_atr := 0;
9737           l_att := g_nodes(l_node_index).att;
9738           l_satr := 0;                              -- invConv change
9739           l_satt := g_nodes(l_node_index).satt;     -- invConv change
9740 
9741       --From Loc = To Loc (LPN unpack)
9742       ELSIF (p_transfer_locator_id IS NOT NULL AND p_transfer_locator_id = p_locator_id) THEN
9743           l_atr := g_nodes(l_node_index).atr;
9744           l_att := g_nodes(l_node_index).att;
9745           l_satr := g_nodes(l_node_index).satr;       -- invConv change
9746           l_satt := g_nodes(l_node_index).satt;       -- invConv change
9747           l_loop_index := g_nodes(l_node_index).parent_index;
9748           LOOP
9749              EXIT WHEN g_nodes(l_loop_index).node_level <= g_locator_level;
9750              IF l_atr > g_nodes(l_loop_index).atr THEN
9751                 l_atr := g_nodes(l_loop_index).atr;
9752                 l_satr := g_nodes(l_loop_index).satr;     -- invConv change
9753              END IF;
9754              IF l_att > g_nodes(l_loop_index).atr THEN
9755                 l_att := g_nodes(l_loop_index).atr;
9756                 l_satt := g_nodes(l_loop_index).satr;     -- invConv change
9757              END IF;
9758              l_loop_index :=  g_nodes(l_loop_index).parent_index;
9759           END LOOP;
9760       --From Sub = To Sub
9761       ELSIF (p_transfer_subinventory_code IS NOT NULL AND p_transfer_subinventory_code = p_subinventory_code) THEN
9762           l_atr := g_nodes(l_node_index).atr;
9763           l_att := g_nodes(l_node_index).att;
9764           l_satr := g_nodes(l_node_index).satr;     -- invConv change
9765           l_satt := g_nodes(l_node_index).satt;     -- invConv change
9766           l_loop_index := g_nodes(l_node_index).parent_index;
9767           LOOP
9768              EXIT WHEN g_nodes(l_loop_index).node_level <= g_sub_level;
9769              IF l_atr > g_nodes(l_loop_index).atr THEN
9770                 l_atr := g_nodes(l_loop_index).atr;
9771                 l_satr := g_nodes(l_loop_index).satr;     -- invConv change
9772              END IF;
9773              IF l_att > g_nodes(l_loop_index).atr THEN
9774                 l_att := g_nodes(l_loop_index).atr;
9775                 l_satt := g_nodes(l_loop_index).satr;     -- invConv change
9776              END IF;
9777              l_loop_index :=  g_nodes(l_loop_index).parent_index;
9778           END LOOP;
9779       -- To Sub is Reservable (FALSE if To Sub is NULL)
9780       ELSIF (l_is_reservable_transfer_sub) THEN
9781           l_atr := g_nodes(l_node_index).atr;
9782           l_att := g_nodes(l_node_index).att;
9783           l_satr := g_nodes(l_node_index).satr;     -- invConv change
9784           l_satt := g_nodes(l_node_index).satt;     -- invConv change
9785           l_loop_index := g_nodes(l_node_index).parent_index;
9786           LOOP
9787              EXIT WHEN g_nodes(l_loop_index).node_level < g_sub_level;
9788              IF l_atr > g_nodes(l_loop_index).atr THEN
9789                 l_atr := g_nodes(l_loop_index).atr;
9790                 l_satr := g_nodes(l_loop_index).satr;     -- invConv change
9791              END IF;
9792              IF l_att > g_nodes(l_loop_index).atr THEN
9793                 l_att := g_nodes(l_loop_index).atr;
9794                 l_satt := g_nodes(l_loop_index).satr;     -- invConv change
9795              END IF;
9796              l_loop_index :=  g_nodes(l_loop_index).parent_index;
9797           END LOOP;
9798 
9799       -- From Sub is reservable and To Sub is Null or Not Reservable
9800       ELSE
9801           l_atr := g_nodes(l_node_index).atr;
9802           l_att := g_nodes(l_node_index).att;
9803           l_satr := g_nodes(l_node_index).satr;     -- invConv change
9804           l_satt := g_nodes(l_node_index).satt;     -- invConv change
9805 
9806           l_loop_index := g_nodes(l_node_index).parent_index;
9807           LOOP
9808              -- invConv comment:
9809              IF (g_debug = 1) THEN
9810                IF g_nodes(l_loop_index).is_reservable_sub
9811                THEN
9812                   print_debug('QT, loop for sub='||g_nodes(l_loop_index).subinventory_code||', loct='||g_nodes(l_loop_index).locator_id||', lot='||substr(g_nodes(l_loop_index).lot_number,1,10)||', rsv=TRUE');
9813                ELSE
9814                   print_debug('QT, loop for sub='||g_nodes(l_loop_index).subinventory_code||', loct='||g_nodes(l_loop_index).locator_id||', lot='||substr(g_nodes(l_loop_index).lot_number,1,10)||', rsv=FALSE');
9815                END IF;
9816                print_debug('.... atr:'||l_atr||' > '||g_nodes(l_loop_index).atr||', and ATT='||l_att);
9817              END IF;
9818 
9819              IF l_atr > g_nodes(l_loop_index).atr THEN
9820                 l_atr := g_nodes(l_loop_index).atr;
9821                 l_satr := g_nodes(l_loop_index).satr;     -- invConv change
9822              END IF;
9823              -- invConv change begin : DEC-2004
9824              -- Only set the att in that new condition :
9825              /* Jalaj Srivastava Bug 5581810
9826                 att should always be set to atr if it is greater than atr
9827                 regardeless of the profile inv: material status support.
9828                 removed check for profile value */
9829              IF (l_att > g_nodes(l_loop_index).atr) THEN
9830                 l_att  := g_nodes(l_loop_index).atr;
9831                 l_satt := g_nodes(l_loop_index).satr;     -- invConv change
9832              ELSE
9833               print_debug('Dont re-set the att with atr(parent).... ');
9834              END IF;
9835 
9836              EXIT WHEN g_nodes(l_loop_index).node_level = g_item_level;
9837              l_loop_index :=  g_nodes(l_loop_index).parent_index;
9838           END LOOP;
9839       END IF;
9840    --Node level above sub level (Item, Revision, Lot)
9841    ELSE
9842       -- p_subinventory_code IS NULL:
9843       print_debug('QT, p_subinventory_code(null?)='||p_subinventory_code);
9844       l_atr := g_nodes(l_node_index).atr;
9845       l_att := g_nodes(l_node_index).att;
9846       l_satr := g_nodes(l_node_index).satr;     -- invConv change
9847       l_satt := g_nodes(l_node_index).satt;     -- invConv change
9848 
9849       --Bug 4294336
9850       IF g_nodes(l_node_index).node_level = g_item_level THEN
9851         l_atr := g_nodes(l_node_index).atr - g_nodes(l_node_index).qs_adj1 ;
9852         l_satr := g_nodes(l_node_index).satr - g_nodes(l_node_index).sqs_adj1 ;
9853       END IF;
9854 
9855       IF g_nodes(l_node_index).node_level <> g_item_level THEN
9856           l_loop_index := g_nodes(l_node_index).parent_index;
9857           LOOP
9858              --Bug 4294336
9859              l_atr2 := g_nodes(l_loop_index).atr - g_nodes(l_loop_index).qs_adj1 ;
9860              l_satr2 := g_nodes(l_loop_index).satr - g_nodes(l_loop_index).sqs_adj1 ;
9861 
9862              IF l_atr > l_atr2 THEN
9863                 l_atr := l_atr2 ;
9864                 l_satr := l_satr2;
9865              END IF;
9866 
9867              /*IF l_atr > g_nodes(l_loop_index).atr THEN
9868                 l_atr := g_nodes(l_loop_index).atr;
9869                 l_satr := g_nodes(l_loop_index).satr;     -- invConv change
9870              END IF;*/
9871              IF l_att > g_nodes(l_loop_index).att THEN
9872                 l_att := g_nodes(l_loop_index).att;
9873                 l_satt := g_nodes(l_loop_index).satt;     -- invConv change
9874              END IF;
9875              EXIT WHEN g_nodes(l_loop_index).node_level = g_item_level;
9876              l_loop_index :=  g_nodes(l_loop_index).parent_index;
9877           END LOOP;
9878       END IF;
9879    END IF;     -- p_subinventory_code
9880 
9881    --Bug 3424532 atr should be returned as 0 for non reservable items
9882    check_is_reservable_item
9883        (  x_return_status      => l_return_status
9884         , p_organization_id    => g_rootinfos(l_root_id).organization_id
9885         , p_inventory_item_id  => g_rootinfos(l_root_id).inventory_item_id
9886         , x_is_reservable_item => l_is_reservable_item
9887        );
9888    IF l_is_reservable_item THEN
9889       print_debug(' item_reservable = YES');
9890       x_atr := l_atr;
9891       x_satr := l_satr;     -- invConv change
9892    ELSE
9893       print_debug(' item_reservable = NO');
9894       x_atr := 0;
9895       x_satr := 0;          -- invConv change
9896    END IF;
9897    --Bug 3424532 atr should be returned as 0 for non reservable items
9898    x_att := l_att;
9899    x_satt := l_satt;        -- invConv change
9900 
9901    print_debug('>> qoh='||to_char(x_qoh)||', rqoh='||x_rqoh||', qr='||x_qr||', qs='||x_qs||', pqoh='||g_pqoh||', atr='||x_atr||', att='||x_att);
9902    print_debug('>> qoh2='||x_sqoh||', rqoh2='||x_srqoh||', qr2='||x_sqr||', qs2='||x_sqs||', pqoh2='||g_spqoh||', atr2='||x_satr||', att2='||x_satt);
9903 
9904    -- invConv changes begin:
9905    -- Check whether the item is DUOM
9906    IF (g_rootinfos(l_root_id).is_DUOM_control = FALSE)
9907    THEN
9908       print_debug(' root_id='||l_root_id||', DUOM_control=FALSE');
9909       x_sqoh  := NULL;
9910       x_srqoh := NULL;
9911       x_sqr   := NULL;
9912       x_sqs   := NULL;
9913       g_spqoh := NULL;
9914       x_satr  := NULL;
9915       x_satt  := NULL;
9916    ELSE
9917       print_debug(' root_id='||l_root_id||', DUOM_control=TRUE');
9918    END IF;
9919    -- invConv changes end
9920 
9921    x_return_status := l_return_status;
9922 
9923    IF g_debug = 1 THEN
9924       print_tree(p_tree_id);
9925       print_debug(l_api_name || ' Exited with status = '||l_return_status||', Qty : '
9926                     || LPad(x_qoh,8)||':'||LPad(x_rqoh,8)||':'||LPad(x_qr,8)||':'||LPad(x_qs,8)||':'
9927                     || LPad(x_att,8)||':'||LPad(x_atr, 8)||':'||LPad(g_pqoh,8),9);
9928       print_debug('>> qoh2='||x_sqoh||', rqoh2='||x_srqoh||', qr2='||x_sqr||', qs2='||x_sqs||', pqoh2='||g_spqoh||', atr2='||x_satr||', att2='||x_satt);
9929       print_debug(' ',9);
9930    END IF;
9931 EXCEPTION
9932 
9933     WHEN fnd_api.g_exc_error THEN
9934    print_debug('QT: ending... g_exc_error'||SQLERRM,9);
9935         x_return_status := fnd_api.g_ret_sts_error;
9936 
9937         --  Get message count and data
9938         fnd_msg_pub.count_and_get
9939           (  p_count => x_msg_count
9940            , p_data  => x_msg_data
9941            );
9942 
9943    WHEN fnd_api.g_exc_unexpected_error THEN
9944    print_debug('QT: ending... g_exc_unexpected_error '||SQLERRM,9);
9945         x_return_status := fnd_api.g_ret_sts_unexp_error ;
9946 
9947         --  Get message count and data
9948         fnd_msg_pub.count_and_get
9949           (  p_count  => x_msg_count
9950            , p_data   => x_msg_data
9951             );
9952 
9953     WHEN OTHERS THEN
9954    print_debug('QT: ending... OTHERS.'||SQLERRM,9);
9955         x_return_status := fnd_api.g_ret_sts_unexp_error ;
9956 
9957         IF fnd_msg_pub.check_msg_level(fnd_msg_pub.g_msg_lvl_unexp_error)
9958           THEN
9959            fnd_msg_pub.add_exc_msg
9960              (  g_pkg_name
9961               , l_api_name
9962               );
9963         END IF;
9964 
9965         --  Get message count and data
9966         fnd_msg_pub.count_and_get
9967           (  p_count  => x_msg_count
9968            , p_data   => x_msg_data
9969             );
9970 END query_tree;
9971 
9972 PROCEDURE query_tree
9973   (   p_api_version_number   IN  NUMBER
9974    ,  p_init_msg_lst         IN  VARCHAR2
9975    ,  x_return_status        OUT NOCOPY VARCHAR2
9976    ,  x_msg_count            OUT NOCOPY NUMBER
9977    ,  x_msg_data             OUT NOCOPY VARCHAR2
9978    ,  p_tree_id              IN  INTEGER
9979    ,  p_revision             IN  VARCHAR2
9980    ,  p_lot_number           IN  VARCHAR2
9981    ,  p_subinventory_code    IN  VARCHAR2
9982    ,  p_locator_id           IN  NUMBER
9983    ,  x_qoh                  OUT NOCOPY NUMBER
9984    ,  x_rqoh                 OUT NOCOPY NUMBER
9985    ,  x_pqoh                 OUT NOCOPY NUMBER
9986    ,  x_qr                   OUT NOCOPY NUMBER
9987    ,  x_qs                   OUT NOCOPY NUMBER
9988    ,  x_att                  OUT NOCOPY NUMBER
9989    ,  x_atr                  OUT NOCOPY NUMBER
9990    ,  p_transfer_subinventory_code IN  VARCHAR2
9991    ,  p_cost_group_id        IN  NUMBER
9992    ,  p_lpn_id               IN  NUMBER
9993    ,  p_transfer_locator_id  IN  NUMBER
9994    ) IS
9995 
9996 l_sqoh    NUMBER;     -- invConv change
9997 l_srqoh   NUMBER;     -- invConv change
9998 l_sqr     NUMBER;     -- invConv change
9999 l_sqs     NUMBER;     -- invConv change
10000 l_satt    NUMBER;     -- invConv change
10001 l_satr    NUMBER;     -- invConv change
10002 
10003 BEGIN
10004 -- invConv changes begin:
10005 -- calling the new signature API:
10006 query_tree(
10007       p_api_version_number  =>  p_api_version_number
10008    ,  p_init_msg_lst        =>  p_init_msg_lst
10009    ,  x_return_status       =>  x_return_status
10010    ,  x_msg_count           =>  x_msg_count
10011    ,  x_msg_data            =>  x_msg_data
10012    ,  p_tree_id             =>  p_tree_id
10013    ,  p_revision            =>  p_revision
10014    ,  p_lot_number          =>  p_lot_number
10015    ,  p_subinventory_code   =>  p_subinventory_code
10016    ,  p_locator_id          =>  p_locator_id
10017    ,  x_qoh                 =>  x_qoh
10018    ,  x_rqoh                =>  x_rqoh
10019    ,  x_qr                  =>  x_qr
10020    ,  x_qs                  =>  x_qs
10021    ,  x_att                 =>  x_att
10022    ,  x_atr                 =>  x_atr
10023    ,  x_sqoh                =>  l_sqoh           -- invConv change
10024    ,  x_srqoh               =>  l_srqoh          -- invConv change
10025    ,  x_sqr                 =>  l_sqr            -- invConv change
10026    ,  x_sqs                 =>  l_sqs            -- invConv change
10027    ,  x_satt                =>  l_satt           -- invConv change
10028    ,  x_satr                =>  l_satr           -- invConv change
10029    ,  p_transfer_subinventory_code => p_transfer_subinventory_code
10030    ,  p_cost_group_id       =>  p_cost_group_id
10031    ,  p_lpn_id              =>  p_lpn_id
10032    ,  p_transfer_locator_id =>  p_transfer_locator_id
10033 );
10034 
10035    x_pqoh := g_pqoh;
10036 
10037 END query_tree;
10038 
10039 -- invConv changes begin : overloaded(2)
10040 PROCEDURE query_tree
10041   (   p_api_version_number   IN  NUMBER
10042    ,  p_init_msg_lst         IN  VARCHAR2
10043    ,  x_return_status        OUT NOCOPY VARCHAR2
10044    ,  x_msg_count            OUT NOCOPY NUMBER
10045    ,  x_msg_data             OUT NOCOPY VARCHAR2
10046    ,  p_tree_id              IN  INTEGER
10047    ,  p_revision             IN  VARCHAR2
10048    ,  p_lot_number           IN  VARCHAR2
10049    ,  p_subinventory_code    IN  VARCHAR2
10050    ,  p_locator_id           IN  NUMBER
10051    ,  x_qoh                  OUT NOCOPY NUMBER
10052    ,  x_rqoh                 OUT NOCOPY NUMBER
10053    ,  x_pqoh                 OUT NOCOPY NUMBER
10054    ,  x_qr                   OUT NOCOPY NUMBER
10055    ,  x_qs                   OUT NOCOPY NUMBER
10056    ,  x_att                  OUT NOCOPY NUMBER
10057    ,  x_atr                  OUT NOCOPY NUMBER
10058    ,  x_sqoh                 OUT NOCOPY NUMBER           -- invConv change
10059    ,  x_srqoh                OUT NOCOPY NUMBER           -- invConv change
10060    ,  x_spqoh                OUT NOCOPY NUMBER           -- invConv change
10061    ,  x_sqr                  OUT NOCOPY NUMBER           -- invConv change
10062    ,  x_sqs                  OUT NOCOPY NUMBER           -- invConv change
10063    ,  x_satt                 OUT NOCOPY NUMBER           -- invConv change
10064    ,  x_satr                 OUT NOCOPY NUMBER           -- invConv change
10065    ,  p_transfer_subinventory_code IN  VARCHAR2
10066    ,  p_cost_group_id        IN  NUMBER
10067    ,  p_lpn_id               IN  NUMBER
10068    ,  p_transfer_locator_id  IN  NUMBER
10069    ) IS
10070 
10071       l_api_name             CONSTANT VARCHAR2(30) := 'Query_Tree';
10072 
10073 
10074 BEGIN
10075 
10076 print_debug('  >>>>>>>>>  In query_tree2');
10077 
10078 query_tree(
10079       p_api_version_number  =>  p_api_version_number
10080    ,  p_init_msg_lst        =>  p_init_msg_lst
10081    ,  x_return_status       =>  x_return_status
10082    ,  x_msg_count           =>  x_msg_count
10083    ,  x_msg_data            =>  x_msg_data
10084    ,  p_tree_id             =>  p_tree_id
10085    ,  p_revision            =>  p_revision
10086    ,  p_lot_number          =>  p_lot_number
10087    ,  p_subinventory_code   =>  p_subinventory_code
10088    ,  p_locator_id          =>  p_locator_id
10089    ,  x_qoh                 =>  x_qoh
10090    ,  x_rqoh                =>  x_rqoh
10091    ,  x_qr                  =>  x_qr
10092    ,  x_qs                  =>  x_qs
10093    ,  x_att                 =>  x_att
10094    ,  x_atr                 =>  x_atr
10095    ,  x_sqoh                =>  x_sqoh           -- invConv change
10096    ,  x_srqoh               =>  x_srqoh          -- invConv change
10097    ,  x_sqr                 =>  x_sqr            -- invConv change
10098    ,  x_sqs                 =>  x_sqs            -- invConv change
10099    ,  x_satt                =>  x_satt           -- invConv change
10100    ,  x_satr                =>  x_satr           -- invConv change
10101    ,  p_transfer_subinventory_code => p_transfer_subinventory_code
10102    ,  p_cost_group_id       =>  p_cost_group_id
10103    ,  p_lpn_id              =>  p_lpn_id
10104    ,  p_transfer_locator_id =>  p_transfer_locator_id
10105 );
10106 
10107    x_pqoh := g_pqoh;
10108    x_spqoh := g_spqoh;       -- invConv change
10109 
10110 print_debug('  End of  query_tree2');
10111 
10112 EXCEPTION
10113     WHEN fnd_api.g_exc_error THEN
10114         x_return_status := fnd_api.g_ret_sts_error;
10115         --  Get message count and data
10116         fnd_msg_pub.count_and_get
10117           (  p_count => x_msg_count
10118            , p_data  => x_msg_data
10119            );
10120    WHEN fnd_api.g_exc_unexpected_error THEN
10121         x_return_status := fnd_api.g_ret_sts_unexp_error ;
10122 
10123         --  Get message count and data
10124         fnd_msg_pub.count_and_get
10125           (  p_count  => x_msg_count
10126            , p_data   => x_msg_data
10127             );
10128     WHEN OTHERS THEN
10129         x_return_status := fnd_api.g_ret_sts_unexp_error ;
10130         IF fnd_msg_pub.check_msg_level(fnd_msg_pub.g_msg_lvl_unexp_error)
10131           THEN
10132            fnd_msg_pub.add_exc_msg
10133              (  g_pkg_name
10134               , l_api_name
10135               );
10136         END IF;
10137         --  Get message count and data
10138         fnd_msg_pub.count_and_get
10139           (  p_count  => x_msg_count
10140            , p_data   => x_msg_data
10141             );
10142 END query_tree;
10143 -- invConv changes end.
10144 
10145 --
10146 -- Procedure
10147 --   create_tree
10148 -- Description
10149 --   Create a quantity tree
10150 --
10151 --  Version
10152 --   Current version           1.0
10153 --   Initial version           1.0
10154 --
10155 -- Input parameters:
10156 --   p_api_version_number      standard input parameter
10157 --   p_init_msg_lst            standard input parameter
10158 --   p_organization_id         organzation id
10159 --   p_inventory_item_id       inventory_item_id
10160 --   p_tree_mode               tree mode, either g_reservation_mode
10161 --                             or g_transaction_mode
10162 --   p_is_revision_control
10163 --   p_is_lot_control
10164 --   p_is_serial_control
10165 --   p_asset_sub_only
10166 --   p_include_suggestion      should be true only for pick/put engine
10167 --   p_demand_source_type_id   demand_source_type_id
10168 --   p_demand_source_header_id demand_source_header_id
10169 --   p_demand_source_line_id   demand_source_line_id
10170 --   p_demand_source_name      demand_source_name
10171 --   p_demand_source_delivery  demand_source_delivery
10172 --   p_pick_release            whether qty tree called from pick release
10173 --                             process or not
10174 --
10175 -- Output parameters:
10176 --   x_return_status           standard output parameter
10177 --   x_msg_count               standard output parameter
10178 --   x_msg_data                standard output parameter
10179 --   x_tree_id                 used later to refer to the same tree
10180 --
10181 PROCEDURE create_tree
10182   (   p_api_version_number       IN  NUMBER
10183    ,  p_init_msg_lst             IN  VARCHAR2
10184    ,  x_return_status            OUT NOCOPY VARCHAR2
10185    ,  x_msg_count                OUT NOCOPY NUMBER
10186    ,  x_msg_data                 OUT NOCOPY VARCHAR2
10187    ,  p_organization_id          IN  NUMBER
10188    ,  p_inventory_item_id        IN  NUMBER
10189    ,  p_tree_mode                IN  INTEGER
10190    ,  p_is_revision_control      IN  BOOLEAN
10191    ,  p_is_lot_control           IN  BOOLEAN
10192    ,  p_is_serial_control        IN  BOOLEAN
10193    ,  p_asset_sub_only           IN  BOOLEAN
10194    ,  p_include_suggestion       IN  BOOLEAN
10195    ,  p_demand_source_type_id    IN  NUMBER
10196    ,  p_demand_source_header_id  IN  NUMBER
10197    ,  p_demand_source_line_id    IN  NUMBER
10198    ,  p_demand_source_name       IN  VARCHAR2
10199    ,  p_demand_source_delivery   IN  NUMBER
10200    ,  p_lot_expiration_date      IN  DATE
10201    ,  x_tree_id                  OUT NOCOPY INTEGER
10202    ,  p_onhand_source            IN  NUMBER
10203    ,  p_exclusive                IN  NUMBER
10204    ,  p_pick_release             IN  NUMBER
10205 
10206   ) IS
10207 
10208 l_grade_code          VARCHAR2(150);
10209 
10210 BEGIN
10211 -- invConv changes begin
10212 -- Calling the new signature API:
10213 create_tree
10214   (   p_api_version_number       => p_api_version_number
10215    ,  p_init_msg_lst             => p_init_msg_lst
10216    ,  x_return_status            => x_return_status
10217    ,  x_msg_count                => x_msg_count
10218    ,  x_msg_data                 => x_msg_data
10219    ,  p_organization_id          => p_organization_id
10220    ,  p_inventory_item_id        => p_inventory_item_id
10221    ,  p_tree_mode                => p_tree_mode
10222    ,  p_is_revision_control      => p_is_revision_control
10223    ,  p_is_lot_control           => p_is_lot_control
10224    ,  p_is_serial_control        => p_is_serial_control
10225    ,  p_grade_code               => l_grade_code
10226    ,  p_asset_sub_only           => p_asset_sub_only
10227    ,  p_include_suggestion       => p_include_suggestion
10228    ,  p_demand_source_type_id    => p_demand_source_type_id
10229    ,  p_demand_source_header_id  => p_demand_source_header_id
10230    ,  p_demand_source_line_id    => p_demand_source_line_id
10231    ,  p_demand_source_name       => p_demand_source_name
10232    ,  p_demand_source_delivery   => p_demand_source_delivery
10233    ,  p_lot_expiration_date      => p_lot_expiration_date
10234    ,  x_tree_id                  => x_tree_id
10235    ,  p_onhand_source            => p_onhand_source
10236    ,  p_exclusive                => p_exclusive
10237    ,  p_pick_release             => p_pick_release
10238   );
10239 -- invConv changes end
10240 
10241 END create_tree;
10242 
10243 -- invConv changes begin : overload:
10244 PROCEDURE create_tree
10245   (   p_api_version_number       IN  NUMBER
10246    ,  p_init_msg_lst             IN  VARCHAR2
10247    ,  x_return_status            OUT NOCOPY VARCHAR2
10248    ,  x_msg_count                OUT NOCOPY NUMBER
10249    ,  x_msg_data                 OUT NOCOPY VARCHAR2
10250    ,  p_organization_id          IN  NUMBER
10251    ,  p_inventory_item_id        IN  NUMBER
10252    ,  p_tree_mode                IN  INTEGER
10253    ,  p_is_revision_control      IN  BOOLEAN
10254    ,  p_is_lot_control           IN  BOOLEAN
10255    ,  p_is_serial_control        IN  BOOLEAN
10256    ,  p_grade_code               IN  VARCHAR2                        -- invConv change
10257    ,  p_asset_sub_only           IN  BOOLEAN
10258    ,  p_include_suggestion       IN  BOOLEAN
10259    ,  p_demand_source_type_id    IN  NUMBER
10260    ,  p_demand_source_header_id  IN  NUMBER
10261    ,  p_demand_source_line_id    IN  NUMBER
10262    ,  p_demand_source_name       IN  VARCHAR2
10263    ,  p_demand_source_delivery   IN  NUMBER
10264    ,  p_lot_expiration_date      IN  DATE
10265    ,  x_tree_id                  OUT NOCOPY INTEGER
10266    ,  p_onhand_source            IN  NUMBER
10267    ,  p_exclusive                IN  NUMBER
10268    ,  p_pick_release             IN  NUMBER
10269 
10270   ) IS
10271       l_api_version_number       CONSTANT NUMBER       := 1.0;
10272       l_api_name                 CONSTANT VARCHAR2(30) := 'CREATE_TREE';
10273       l_return_status            VARCHAR2(1) := fnd_api.g_ret_sts_success;
10274       l_rootinfo_index           INTEGER;
10275       l_demand_source_type_id    NUMBER;
10276       l_demand_source_header_id  NUMBER;
10277       l_demand_source_line_id    NUMBER;
10278       l_demand_source_name       VARCHAR2(30);
10279       l_demand_source_delivery   NUMBER;
10280       l_tree_id                  INTEGER;
10281       l_lot_expiration_date      DATE;
10282 
10283 
10284       -- invConv changes begin
10285 
10286       l_lot_control            NUMBER;
10287       l_grade_control          VARCHAR2(1);
10288       l_grade_code             VARCHAR2(150);
10289       l_DUOM_control           VARCHAR2(3) := 'P';      -- Value = P for primary only
10290                                                         -- Value = PS for primary and secondary
10291       l_lot_status_enabled     VARCHAR2(2);
10292       l_debug_line             VARCHAR2(300);
10293 
10294       CURSOR get_item_details( org_id IN NUMBER, item_id IN NUMBER) IS
10295          SELECT  NVL(grade_control_flag, 'N')
10296                , NVL(lot_control_code, 1)
10297                , tracking_quantity_ind
10298                , lot_status_enabled
10299          FROM mtl_system_items
10300          WHERE inventory_item_id = item_id
10301          AND organization_id = org_id;
10302 
10303       -- invConv changes end
10304 
10305 BEGIN
10306    IF g_debug IS NULL THEN
10307       g_debug :=  NVL(FND_PROFILE.VALUE('INV_DEBUG_TRACE'),0);
10308    END IF;
10309 
10310    IF g_debug = 1 THEN
10311       print_debug(l_api_name || ' Entered',9);
10312 
10313       l_debug_line := '>>> In create_tree : mode='||p_tree_mode||':'||p_organization_id||':'||p_inventory_item_id||': item ctrl: ';
10314       if (p_is_revision_control = TRUE)
10315       THEN
10316          l_debug_line := l_debug_line||'TRUE ';
10317       else
10318          l_debug_line := l_debug_line||'FASLE';
10319       end if;
10320       if (p_is_lot_control = TRUE)
10321       then
10322          l_debug_line := l_debug_line||':TRUE ';
10323       else
10324          l_debug_line := l_debug_line||':FALSE';
10325       end if;
10326       if (p_is_serial_control = TRUE)
10327       then
10328          l_debug_line := l_debug_line||':TRUE ';
10329       else
10330          l_debug_line := l_debug_line||':FALSE';
10331       end if;
10332       print_debug(l_debug_line || ': demand: '||p_demand_source_type_id||':'||p_demand_source_header_id||':'||p_demand_source_line_id||'.',12);
10333    END IF;
10334 
10335    /* Jalaj Srivastava Bug 5590287.
10336         1. no need to initialize gmd debug log file
10337         2. init of g_is_mat_status_used is done in the package spec
10338         3. commented out the whole IF below */
10339 
10340    --IF p_pick_release = g_pick_release_no OR g_not_initialized THEN
10341    --  g_not_initialized := FALSE;
10342    --  gmd_debug.log_initialize('_QT');
10343 
10344      -- invConv changes begin : This profile option is giving the decision of the
10345      --                 material status usage :
10346      --                 INV_MATERIAL_STATUS == 1 == YES
10347      --                 INV_MATERIAL_STATUS == 2 == NO
10348 
10349    --  INV_QUANTITY_TREE_PVT.g_is_mat_status_used := NVL(FND_PROFILE.VALUE('INV_MATERIAL_STATUS'), 2);
10350    -- invConv changes end.
10351    --END IF;
10352    /* Jalaj Srivastava Bug 5590287
10353       set the value of global var g_is_mat_status_used only if it is null  */
10354    IF INV_QUANTITY_TREE_PVT.g_is_mat_status_used IS NULL THEN
10355      INV_QUANTITY_TREE_PVT.g_is_mat_status_used := NVL(FND_PROFILE.VALUE('INV_MATERIAL_STATUS'), 2);
10356    END IF;
10357 
10358    if (p_is_revision_control = TRUE)
10359    THEN
10360    print_debug('  >>>>>>>>>  In create_tree. mode='||p_tree_mode||', grade='||p_grade_code||', rev_ctl=TRUE. mat_stat='||INV_QUANTITY_TREE_PVT.g_is_mat_status_used);
10361    else
10362    print_debug('  >>>>>>>>>  In create_tree. mode='||p_tree_mode||', grade='||p_grade_code||', rev_ctl=FALSE. mat_stat='||INV_QUANTITY_TREE_PVT.g_is_mat_status_used);
10363    end if;
10364 
10365    if (p_is_lot_control = TRUE)
10366    then
10367               print_debug('In create_tree.   p_is_lot_control=TRUE');
10368    else
10369               print_debug('In create_tree.   p_is_lot_control=FALSE');
10370    end if;
10371 
10372    --  Standard call to check for call compatibility
10373    IF NOT fnd_api.compatible_api_call(l_api_version_number
10374                                       , p_api_version_number
10375                                       , l_api_name
10376                                       , G_PKG_NAME
10377                                       ) THEN
10378       RAISE fnd_api.g_exc_unexpected_error;
10379    END IF;
10380 
10381    --  Initialize message list.
10382    IF fnd_api.to_boolean(p_init_msg_lst) THEN
10383       fnd_msg_pub.initialize;
10384    END IF;
10385 
10386    g_is_pickrelease := nvl(inv_cache.is_pickrelease,FALSE);
10387 
10388    IF g_debug IS NULL THEN
10389       g_debug :=  NVL(FND_PROFILE.VALUE('INV_DEBUG_TRACE'),0);
10390    END IF;
10391 
10392    g_empty_root_index := NULL;
10393    g_hash_string := NULL;
10394 
10395    -- validate demand source info
10396    print_debug('In create_tree.  p_demand_source_type_id='||p_demand_source_type_id||', p_demand_source_header_id='||p_demand_source_header_id
10397        ||', p_demand_source_line_id='||p_demand_source_line_id);
10398    IF p_tree_mode IN (g_transaction_mode, g_loose_only_mode) THEN
10399       IF p_demand_source_type_id IS NULL THEN
10400          fnd_message.set_name('INV', 'INV-MISSING DEMAND SOURCE TYPE');
10401          fnd_msg_pub.ADD;
10402          RAISE fnd_api.g_exc_error;
10403       END IF;
10404 
10405       IF p_demand_source_header_id IS NULL THEN
10406          IF p_demand_source_name IS NULL THEN
10407             fnd_message.set_name('INV', 'INV-MISSING DEMAND SRC HEADER');
10408             fnd_msg_pub.ADD;
10409             RAISE fnd_api.g_exc_error;
10410          END IF;
10411       END IF;
10412 
10413       IF p_demand_source_header_id IS NULL
10414         AND p_demand_source_line_id IS NOT NULL THEN
10415          fnd_message.set_name('INV', 'INV-MISSING DEMAND SRC HEADER');
10416          fnd_msg_pub.ADD;
10417          RAISE fnd_api.g_exc_error;
10418       END IF;
10419    END IF;
10420 
10421    -- invConv changes begin:
10422    -- Material Status : Need to know whether the item is lot_control : MANDATORY.
10423    -- Get Item Details:
10424    OPEN get_item_details(p_organization_id, p_inventory_item_id);
10425    FETCH get_item_details
10426     INTO l_grade_control
10427        , l_lot_control
10428        , l_DUOM_control
10429        , l_lot_status_enabled;
10430 
10431    print_debug('DUOM control='||l_DUOM_control);
10432    IF (get_item_details%NOTFOUND)
10433    THEN
10434       print_debug(' get_item_details NOTFOUND for org='||p_organization_id||', item='||p_inventory_item_id);
10435       CLOSE get_item_details;
10436       -- The item doesn't exist under this organization.
10437       FND_MESSAGE.SET_NAME('INV', 'ITEM_NOTFOUND');
10438       FND_MESSAGE.SET_TOKEN('INVENTORY_ITEM_ID', p_inventory_item_id);
10439       FND_MESSAGE.SET_TOKEN('ORGANIZATION_ID', p_organization_id);
10440       FND_MSG_PUB.ADD;
10441       RAISE FND_API.G_EXC_ERROR;
10442    END IF;
10443    -- invConv comment : g_is_mat_status_used = 1 == Material Status is USED
10444    IF (inv_quantity_tree_pvt.g_is_mat_status_used = 1 AND l_lot_control = 2)
10445    THEN
10446       g_is_lot_control := TRUE;
10447    ELSE
10448       g_is_lot_control := FALSE;
10449    END IF;
10450    -- invConv note : the using of is_DUOM_control is made later in the procedure
10451    CLOSE get_item_details;
10452 
10453    -- invConv changes end.
10454 
10455    IF (p_exclusive = g_exclusive) THEN
10456       lock_tree(
10457               p_api_version_number  => 1.0
10458             , p_init_msg_lst        => fnd_api.g_false
10459             , x_return_status       => l_return_status
10460             , x_msg_count           => x_msg_count
10461             , x_msg_data            => x_msg_data
10462             , p_organization_id     => p_organization_id
10463             , p_inventory_item_id   => p_inventory_item_id
10464             );
10465 
10466       IF l_return_status = fnd_api.g_ret_sts_error THEN
10467          RAISE fnd_api.g_exc_error;
10468       END IF ;
10469 
10470       IF l_return_status = fnd_api.g_ret_sts_unexp_error THEN
10471          RAISE fnd_api.g_exc_unexpected_error;
10472       END IF;
10473    END IF;
10474 
10475    IF p_lot_expiration_date IS NOT NULL THEN
10476       l_lot_expiration_date := trunc(p_lot_expiration_date + 1) - 0.00001;
10477    END IF;
10478 
10479    -- find the rootinfo record
10480    l_rootinfo_index := find_rootinfo(
10481                      x_return_status           => l_return_status
10482                    , p_organization_id         => p_organization_id
10483                    , p_inventory_item_id       => p_inventory_item_id
10484                    , p_tree_mode               => p_tree_mode
10485                    , p_is_revision_control     => p_is_revision_control
10486                    , p_is_lot_control          => p_is_lot_control
10487                    , p_is_serial_control       => p_is_serial_control
10488                    , p_asset_sub_only          => p_asset_sub_only
10489                    , p_include_suggestion      => p_include_suggestion
10490                    , p_demand_source_type_id   => p_demand_source_type_id
10491                    , p_demand_source_header_id => p_demand_source_header_id
10492                    , p_demand_source_line_id   => p_demand_source_line_id
10493                    , p_demand_source_name      => p_demand_source_name
10494                    , p_demand_source_delivery  => p_demand_source_delivery
10495                    , p_lot_expiration_date     => l_lot_expiration_date
10496                    , p_onhand_source        => p_onhand_source
10497                    , p_pick_release         => p_pick_release
10498                    -- odab temp removed  , p_grade_code            => p_grade_code                 -- invConv change
10499                    );
10500 
10501    IF l_return_status = fnd_api.g_ret_sts_error THEN
10502       RAISE fnd_api.g_exc_error;
10503    End IF ;
10504 
10505    IF l_return_status = fnd_api.g_ret_sts_unexp_error THEN
10506       RAISE fnd_api.g_exc_unexpected_error;
10507    End IF;
10508    -- create the tree if the rootinfo can not be found
10509    IF (l_rootinfo_index = 0) THEN
10510       new_tree(
10511                  x_return_status           => l_return_status
10512                , p_organization_id         => p_organization_id
10513                , p_inventory_item_id       => p_inventory_item_id
10514                , p_tree_mode               => p_tree_mode
10515                , p_is_revision_control     => p_is_revision_control
10516                , p_is_lot_control          => p_is_lot_control
10517                , p_is_serial_control       => p_is_serial_control
10518                , p_asset_sub_only          => p_asset_sub_only
10519                , p_include_suggestion      => p_include_suggestion
10520                , p_demand_source_type_id   => p_demand_source_type_id
10521                , p_demand_source_header_id => p_demand_source_header_id
10522                , p_demand_source_line_id   => p_demand_source_line_id
10523                , p_demand_source_name      => p_demand_source_name
10524                , p_demand_source_delivery  => p_demand_source_delivery
10525                , p_lot_expiration_date     => l_lot_expiration_date
10526                , p_onhand_source           => p_onhand_source
10527                , p_pick_release            => p_pick_release
10528                , p_grade_code              => p_grade_code                                  -- invConv change
10529                , x_tree_id                 => l_rootinfo_index
10530                );
10531       IF l_return_status = fnd_api.g_ret_sts_error THEN
10532          RAISE fnd_api.g_exc_error;
10533       END IF ;
10534 
10535       IF l_return_status = fnd_api.g_ret_sts_unexp_error THEN
10536          RAISE fnd_api.g_exc_unexpected_error;
10537       END IF;
10538 
10539    END IF;
10540 
10541    print_debug(' l_tree_id='||l_rootinfo_index||', l_rootinfo_index='||g_demand_info(l_rootinfo_index).root_id);
10542    l_tree_id := l_rootinfo_index;
10543    l_rootinfo_index := g_demand_info(l_tree_id).root_id;
10544 
10545    -- invConv changes begin :
10546    -- set the DUOM indicator
10547    IF (l_DUOM_control = 'P')
10548    THEN
10549       print_debug('DUOM control='||l_DUOM_control||', then FALSE');
10550       g_rootinfos(l_rootinfo_index).is_DUOM_control := FALSE;
10551    ELSE
10552       print_debug('DUOM control='||l_DUOM_control||', then TRUE');
10553       g_rootinfos(l_rootinfo_index).is_DUOM_control := TRUE;
10554    END IF;
10555 
10556    IF (l_lot_status_enabled = 'Y')
10557    THEN
10558       g_rootinfos(l_rootinfo_index).is_lot_status_enabled := TRUE;
10559    ELSE
10560       g_rootinfos(l_rootinfo_index).is_lot_status_enabled := FALSE;
10561    END IF;
10562    -- invConv changes end
10563 
10564    -- (re)build the tree if necessary
10565    IF (g_rootinfos(l_rootinfo_index).need_refresh) THEN
10566       --made change so that invalidated trees are rebuilt if
10567       -- create_tree is called for the same tree
10568       IF g_rootinfos(l_rootinfo_index).inventory_item_id IS NULL THEN
10569          g_rootinfos(l_rootinfo_index).inventory_item_id := p_inventory_item_id;
10570          g_rootinfos(l_rootinfo_index).organization_id := p_organization_id;
10571       END IF;
10572       build_tree(l_return_status, l_rootinfo_index);
10573       IF (l_return_status = fnd_api.g_ret_sts_error OR l_return_status = fnd_api.g_ret_sts_unexp_error) THEN
10574          -- if build_tree failed
10575          -- invalidate the rootinfo record and the index to the record
10576          invalidate_tree(l_rootinfo_index);
10577          l_tree_id := 0;
10578       END IF;
10579 
10580       IF l_return_status = fnd_api.g_ret_sts_error THEN
10581          RAISE fnd_api.g_exc_error;
10582       End IF ;
10583 
10584       IF l_return_status = fnd_api.g_ret_sts_unexp_error THEN
10585          RAISE fnd_api.g_exc_unexpected_error;
10586       End IF;
10587 
10588    END IF;
10589 
10590    -- invConv changes begin :
10591    --  Bug 6332112 : Removed if l_debug
10592    check_tree( p_tree_id   => l_tree_id);
10593    -- invConv changes end.
10594 
10595    -- return the tree id
10596    x_tree_id := l_tree_id;
10597    x_return_status := l_return_status;
10598 
10599    IF g_debug = 1 THEN
10600       print_tree(l_tree_id);
10601       print_debug(l_api_name || ' Exited with status = '||l_return_status,9);
10602       print_debug(' ',9);
10603    END IF;
10604 
10605 EXCEPTION
10606 
10607     WHEN fnd_api.g_exc_error THEN
10608         print_debug(' CreateTree ending with g_exc_error.'||SQLERRM,9);
10609         x_return_status := fnd_api.g_ret_sts_error;
10610 
10611         --  Get message count and data
10612         fnd_msg_pub.count_and_get
10613           (  p_count => x_msg_count
10614            , p_data  => x_msg_data
10615            );
10616 
10617    WHEN fnd_api.g_exc_unexpected_error THEN
10618         print_debug(' CreateTree ending with g_exc_unexpected_error.'||SQLERRM,9);
10619         x_return_status := fnd_api.g_ret_sts_unexp_error ;
10620 
10621         --  Get message count and data
10622         fnd_msg_pub.count_and_get
10623           (  p_count  => x_msg_count
10624            , p_data   => x_msg_data
10625             );
10626 
10627     WHEN OTHERS THEN
10628         print_debug(' CreateTree ending with OTHERS.'||SQLERRM,9);
10629         x_return_status := fnd_api.g_ret_sts_unexp_error ;
10630 
10631         IF fnd_msg_pub.check_msg_level(fnd_msg_pub.g_msg_lvl_unexp_error)
10632           THEN
10633            fnd_msg_pub.add_exc_msg
10634              (  g_pkg_name
10635               , l_api_name
10636               );
10637         END IF;
10638 
10639         --  Get message count and data
10640         fnd_msg_pub.count_and_get
10641           (  p_count  => x_msg_count
10642            , p_data   => x_msg_data
10643             );
10644 
10645 END create_tree;
10646 
10647 --Traverse
10648 --  Used by prepare_reservation_quantities to
10649 -- quickly traverse the trees and copy all the node information
10650 -- into the tables to be later used for bulk insert.
10651 -- For quantity calculations in reservations mode, the ATR of a node
10652 -- is the smallest ATR for that node and all of that node's ancestors.
10653 -- Instead of looking at every ancestor for every node to determine
10654 -- ATR, this procedure takes advantage of its recursive, downward working
10655 -- nature.  By taking in the ATR of the parent node, the procedure
10656 -- no longer needs to look at every ancestor. It can just compare the
10657 -- current node's value to that of its parent, which had already been
10658 -- compared to its parent's ATR, and so on.
10659 -- A parent node calls traverse only on its first child node. That child
10660 -- will call traverse on each of its siblings, and also on its own children.
10661 
10662 PROCEDURE traverse(
10663          p_node_index      INTEGER
10664        , p_parent_atr      NUMBER
10665        , p_parent_satr     NUMBER       -- invConv change
10666    ) IS
10667 
10668    l_atr  NUMBER;
10669    l_satr NUMBER;       -- invConv change
10670 BEGIN
10671    IF p_node_index = 0 THEN
10672       return;
10673    END IF;
10674    -- ATR = min(current node's ATR, parent node's ATR)
10675    IF p_parent_atr IS NOT NULL AND p_parent_atr < g_nodes(p_node_index).atr THEN
10676      l_atr   := p_parent_atr;
10677       l_satr  := p_parent_satr;                     -- invConv change
10678    ELSE
10679       l_atr   := g_nodes(p_node_index).atr;
10680       l_satr  := g_nodes(p_node_index).satr;        -- invConv change
10681    END IF;
10682 
10683    -- nodes with ATR <= 0 are not inserted into the table
10684    -- bug 1643186: We should insert records with ATR = 0
10685    --   if there is onhand qty
10686    -- bug 1990180 - we should always call traverse on the sibling nodes;
10687    --     before, we were only calling traverse on sibling node if
10688    --     qoh was greater than 0
10689    -- bug 2206138 - the onhand quantity should be the reservable quantity onhand
10690    print_debug('in traverse, ATR='||l_atr||', rqoh='||g_nodes(p_node_index).rqoh,9);
10691    IF g_nodes(p_node_index).is_reservable_sub
10692    THEN
10693       print_debug('in traverse, sub='||g_nodes(p_node_index).subinventory_code||', loct='||g_nodes(p_node_index).locator_id||', lot='||substr(g_nodes(p_node_index).lot_number,1,10)||', rsv=TRUE');
10694    ELSE
10695       print_debug('in traverse, sub='||g_nodes(p_node_index).subinventory_code||', loct='||g_nodes(p_node_index).locator_id||', lot='||substr(g_nodes(p_node_index).lot_number,1,10)||', rsv=FALSE');
10696    END IF;
10697 
10698 
10699    IF l_atr > 0 OR g_nodes(p_node_index).rqoh >0 THEN
10700 
10701       -- invConv changes begin
10702       IF (g_nodes(p_node_index).is_reservable_sub = TRUE)
10703       THEN
10704          -- invConv changes end
10705          g_rsv_qty_counter := g_rsv_qty_counter +1;
10706          g_rsv_qty_revision(g_rsv_qty_counter)           := g_nodes(p_node_index).revision;
10707          g_rsv_qty_lot_number(g_rsv_qty_counter)         := g_nodes(p_node_index).lot_number;
10708          g_rsv_qty_subinventory_code(g_rsv_qty_counter)  := g_nodes(p_node_index).subinventory_code;
10709          g_rsv_qty_locator_id(g_rsv_qty_counter)         := g_nodes(p_node_index).locator_id;
10710          g_rsv_qty_cost_group_id(g_rsv_qty_counter)      := g_nodes(p_node_index).cost_group_id;
10711          g_rsv_qty_lpn_id(g_rsv_qty_counter)             := g_nodes(p_node_index).lpn_id;
10712          g_rsv_qty_node_level(g_rsv_qty_counter)         := g_nodes(p_node_index).node_level;
10713          g_rsv_qty_qoh(g_rsv_qty_counter)                := g_nodes(p_node_index).rqoh;
10714          g_rsv_qty_sqoh(g_rsv_qty_counter)               := g_nodes(p_node_index).srqoh;       -- invConv change
10715          g_rsv_qty_atr(g_rsv_qty_counter)                := l_atr;
10716          g_rsv_qty_satr(g_rsv_qty_counter)               := l_satr;                            -- invConv change
10717          -- invConv change : note that grade_code is hold under rootinfo
10718       END IF;                      -- invConv change
10719 
10720       -- call traverse on children
10721       -- invConv change : added 3rd parameter
10722       traverse (g_nodes(p_node_index).first_child_index, l_atr, l_satr);
10723    END IF;
10724 
10725    --call traverse on siblings
10726    -- invConv change : added 3rd parameter
10727    traverse (g_nodes(p_node_index).next_sibling_index, p_parent_atr, p_parent_satr);
10728 
10729 END traverse;
10730 
10731 
10732 -- Procedure
10733 --   prepare_reservation_quantities
10734 -- Description
10735 --      This procedure is called from the reservation form to
10736 -- initialize the table used for the LOVs in that form.
10737 --
10738 -- This procedure inserts one record for every node in the tree
10739 -- which has ATR > 0.  The table mtl_rsv_quantities_temp
10740 -- is a session specific global temp table which serves as the
10741 -- basis for the LOVs in the Reservations form.
10742 --
10743 PROCEDURE prepare_reservation_quantities(
10744      x_return_status        OUT NOCOPY VARCHAR2
10745    , p_tree_id              IN  NUMBER
10746 )
10747 IS
10748 
10749    l_root_id      INTEGER;
10750    l_item_node    INTEGER;
10751    i              INTEGER;
10752    l_grade_code   VARCHAR2(150) := NULL;     -- invConv change
10753 
10754    CURSOR Get_Grade_From_Lot( org_id  IN NUMBER
10755                             , item_id IN NUMBER
10756                             , lot     IN VARCHAR2) IS
10757       SELECT grade_code
10758       FROM mtl_lot_numbers
10759       WHERE organization_id = org_id
10760       AND inventory_item_id = item_id
10761       AND lot_number = lot;
10762 
10763    l_api_name             CONSTANT VARCHAR2(60) := 'PREPARE_RESERVATION_QUANTITIES';
10764 BEGIN
10765 
10766    IF g_debug = 1 THEN
10767       print_debug(l_api_name || ' Entered',9);
10768    END IF;
10769 
10770    -- clear out temp table
10771    DELETE FROM MTL_RSV_QUANTITIES_TEMP;
10772 
10773    -- find root node
10774    l_root_id := g_demand_info(p_tree_id).root_id;
10775 
10776    -- find appropriate child node
10777    l_item_node := g_rootinfos(l_root_id).item_node_index;
10778 
10779    -- initialize table for bulk insert
10780    g_rsv_qty_node_level.delete;
10781    g_rsv_qty_revision.delete;
10782    g_rsv_qty_lot_number.delete;
10783    g_rsv_qty_subinventory_code.delete;
10784    g_rsv_qty_locator_id.delete;
10785    g_rsv_qty_cost_group_id.delete;
10786    g_rsv_qty_lpn_id.delete;
10787    g_rsv_qty_qoh.delete;
10788    g_rsv_qty_atr.delete;
10789    g_rsv_qty_sqoh.delete;          -- invConv change
10790    g_rsv_qty_satr.delete;          -- invConv change
10791    g_rsv_qty_counter := 0;
10792    -- call recursive function on current node
10793    -- invConv change : added 3rd parameter
10794    traverse(l_item_node, NULL, NULL);
10795 
10796    --insert into table
10797    FOR i in 1..g_rsv_qty_counter
10798    LOOP
10799       IF (g_rsv_qty_lot_number(i) IS NOT NULL)
10800       THEN
10801          OPEN Get_Grade_From_Lot( g_rootinfos(l_root_id).organization_id
10802                                 , g_rootinfos(l_root_id).inventory_item_id
10803                                 , g_rsv_qty_lot_number(i));
10804          FETCH Get_Grade_From_Lot
10805           INTO g_rootinfos(l_root_id).grade_code;
10806           --INTO l_grade_code;
10807          CLOSE Get_Grade_From_Lot;
10808       END IF;
10809 
10810       print_debug(' insert into mtl_rsv_quantities_temp, item='||g_rootinfos(l_root_id).inventory_item_id||', revision='||g_rsv_qty_revision(i)||'...');
10811       INSERT INTO MTL_RSV_QUANTITIES_TEMP (
10812           organization_id
10813          ,inventory_item_id
10814          ,node_level
10815          ,revision
10816          ,lot_number
10817          ,subinventory_code
10818          ,locator_id
10819          ,grade_code                 -- invConv change
10820          ,cost_group_id
10821          ,lpn_id
10822          ,qoh
10823          ,atr
10824          ,sqoh                      -- invConv change
10825          ,satr                      -- invConv change
10826       ) VALUES (
10827           g_rootinfos(l_root_id).organization_id
10828          ,g_rootinfos(l_root_id).inventory_item_id
10829          ,g_rsv_qty_node_level(i)
10830          ,g_rsv_qty_revision(i)
10831          ,g_rsv_qty_lot_number(i)
10832          ,g_rsv_qty_subinventory_code(i)
10833          ,g_rsv_qty_locator_id(i)
10834          ,g_rootinfos(l_root_id).grade_code         -- invConv change
10835          ,g_rsv_qty_cost_group_id(i)
10836          ,g_rsv_qty_lpn_id(i)
10837          ,g_rsv_qty_qoh(i)
10838          ,g_rsv_qty_atr(i)
10839          ,g_rsv_qty_sqoh(i)         -- invConv change
10840          ,g_rsv_qty_satr(i)         -- invConv change
10841       );
10842    END LOOP;
10843 
10844    -- return status
10845    x_return_status := fnd_api.g_ret_sts_success;
10846 EXCEPTION
10847    WHEN OTHERS THEN
10848       x_return_status := fnd_api.g_ret_sts_unexp_error;
10849 
10850 END prepare_reservation_quantities;
10851 
10852 -- Get_Total_QOH
10853 --   This API returns the TQOH, or total quantity on hand.
10854 --   This value reflects any negative balances for this
10855 --   item in the organization.  The Total QOH is the minimum
10856 --   of the current node's QOH and all ancestor nodes' QOH.
10857 --   For example,
10858 --   Consider 2 locators in the EACH subinventory:
10859 --   E.1.1 has 10 onhand
10860 --   E.1.2 has -20 onhand
10861 --   Thus, the subinventory Each has -10 onhand.
10862 --
10863 --   Where calling query_tree, qoh for E.1.1 = 10.
10864 --   However, when calling get_total_qoh, the TQOH
10865 --   for E.1.1 = -10, reflecting the value at the subinventory level.
10866 --
10867 --   This procedure is used by the inventory transaction forms.
10868 
10869 PROCEDURE get_total_qoh
10870    (  x_return_status        OUT NOCOPY VARCHAR2
10871    ,  x_msg_count            OUT NOCOPY NUMBER
10872    ,  x_msg_data             OUT NOCOPY VARCHAR2
10873    ,  p_tree_id              IN  INTEGER
10874    ,  p_revision             IN  VARCHAR2
10875    ,  p_lot_number           IN  VARCHAR2
10876    ,  p_subinventory_code    IN  VARCHAR2
10877    ,  p_locator_id           IN  NUMBER
10878    ,  p_cost_group_id        IN  NUMBER
10879    ,  x_tqoh                 OUT NOCOPY NUMBER
10880    ,  p_lpn_id               IN  NUMBER
10881    ) IS
10882 
10883 l_stqoh NUMBER;
10884 
10885 BEGIN
10886 -- invConv changes begin:
10887 -- calling the new signature API:
10888 
10889 inv_quantity_tree_pvt.get_total_qoh
10890            ( x_return_status     => x_return_status
10891            , x_msg_count         => x_msg_count
10892            , x_msg_data          => x_msg_data
10893            , p_tree_id           => p_tree_id
10894            , p_revision          => p_revision
10895            , p_lot_number        => p_lot_number
10896            , p_subinventory_code => p_subinventory_code
10897            , p_locator_id        => p_locator_id
10898            , p_cost_group_id     => p_cost_group_id
10899            , x_tqoh              => x_tqoh
10900            , x_stqoh             => l_stqoh
10901            , p_lpn_id            => p_lpn_id) ;
10902 
10903 END get_total_qoh;
10904 
10905 -- invConv changes begin
10906 PROCEDURE get_total_qoh
10907    (  x_return_status        OUT NOCOPY VARCHAR2
10908    ,  x_msg_count            OUT NOCOPY NUMBER
10909    ,  x_msg_data             OUT NOCOPY VARCHAR2
10910    ,  p_tree_id              IN  INTEGER
10911    ,  p_revision             IN  VARCHAR2
10912    ,  p_lot_number           IN  VARCHAR2
10913    ,  p_subinventory_code    IN  VARCHAR2
10914    ,  p_locator_id           IN  NUMBER
10915    ,  p_cost_group_id        IN  NUMBER
10916    ,  x_tqoh                 OUT NOCOPY NUMBER
10917    ,  x_stqoh                OUT NOCOPY NUMBER      -- invConv change
10918    ,  p_lpn_id               IN  NUMBER
10919    ) IS
10920 
10921    l_found BOOLEAN;
10922    l_return_status VARCHAR2(1) := fnd_api.g_ret_sts_success;
10923    l_node_index NUMBER;
10924    l_tqoh NUMBER;
10925    l_stqoh NUMBER;
10926    l_loop_index NUMBER;
10927    l_root_id NUMBER;
10928    l_is_reservable_sub BOOLEAN;
10929    l_lpn_id NUMBER;
10930    l_sub_index NUMBER := NULL;
10931    l_api_name VARCHAR2(30) := 'GET_TOTAL_QOH';
10932 
10933 BEGIN
10934 
10935    IF g_debug = 1 THEN
10936       print_debug(l_api_name || ' Entered',9);
10937    END IF;
10938 
10939    l_root_id := g_demand_info(p_tree_id).root_id;
10940    print_debug(' in get_total_qoh, tree='||p_tree_id||', root_id='||l_root_id);
10941    print_debug(' ... org_id='||g_rootinfos(l_root_id).organization_id||', item_id='||g_rootinfos(l_root_id).inventory_item_id||'.');
10942    print_debug(' ... lot='||substr(p_lot_number,1,10)||', subInv='||p_subinventory_code||', loct='||p_locator_id||'.');
10943    -- Must handle case where cost group is populated but material is not packed
10944    -- With removal of Cost Group from quantity tree, this is no longer necessary
10945   /*
10946    *IF p_cost_group_id IS NOT NULL AND
10947    *   p_lpn_id IS NULL THEN
10948    *    l_lpn_id := g_loose_lpn_id;
10949    *ELSE
10950    *    l_lpn_id := p_lpn_id;
10951    *END IF;
10952    */
10953 
10954    -- find the node indicated by the parameters
10955    l_found := find_tree_node(
10956                       x_return_status      => l_return_status
10957                     , p_tree_id            => l_root_id
10958                     , p_revision           => p_revision
10959                     , p_lot_number         => p_lot_number
10960                     , p_subinventory_code  => p_subinventory_code
10961                     , p_is_reservable_sub  => NULL
10962                     , p_locator_id         => p_locator_id
10963                     , x_node_index         => l_node_index
10964                     , p_cost_group_id      => p_cost_group_id
10965                     , p_lpn_id             => p_lpn_id
10966                     );
10967 
10968    IF l_return_status = fnd_api.g_ret_sts_error THEN
10969       RAISE fnd_api.g_exc_error;
10970    End IF ;
10971 
10972 
10973    IF l_return_status = fnd_api.g_ret_sts_unexp_error THEN
10974       RAISE fnd_api.g_exc_unexpected_error;
10975    End IF;
10976 
10977 
10978    IF l_found = FALSE THEN
10979       fnd_message.set_name('INV','INV-Cannot find node');
10980       fnd_message.set_token('ROUTINE', 'Find_Tree_Node');
10981       fnd_msg_pub.ADD;
10982       RAISE fnd_api.g_exc_unexpected_error;
10983    End IF;
10984 
10985    print_debug('get_total_qoh: node found... node_index='||l_node_index||' level='||g_nodes(l_node_index).node_level||'<>'||g_item_level);
10986 
10987    --Bug 3943215.
10988    --   The logic added here is synchronous with computation logic of runtine att in query_tree.
10989    --   The value returned by this procedure is compared to the runtime att in INVMTXFH.pld
10990 
10991    /*********************************************************************
10992    * Logic for finding TQOH:
10993    *
10994    * If Node is at Sub level or below
10995    *    Get reservable for Sub
10996    *    If Sub is not reservable
10997    *       TQOH = QOH of node;
10998    *    else
10999    *       TQOH = min(QOH of node, RQOH of ancestor nodes)
11000    * Else (node above sub level)
11001    *    TQOH = min(QOH of node, QOH of ancestor nodes)
11002    *********************************************************************/
11003 
11004    IF g_nodes(l_node_index).node_level IN (g_sub_level, g_locator_level,g_lpn_level, g_cost_group_level)
11005      AND (p_subinventory_code IS NOT NULL) THEN
11006 
11007       l_sub_index := get_ancestor_sub(l_node_index);
11008       l_is_reservable_sub := g_nodes(l_sub_index).is_reservable_sub;
11009 
11010       IF NOT l_is_reservable_sub THEN
11011          l_tqoh :=  g_nodes(l_node_index).qoh;
11012          l_stqoh :=  g_nodes(l_node_index).sqoh;                    -- invConv change
11013       ELSE
11014          -- loop through all ancestors, setting l_tqoh to the minimum rqoh
11015          l_tqoh := g_nodes(l_node_index).qoh;
11016          l_stqoh :=  g_nodes(l_node_index).sqoh;                    -- invConv change
11017          IF g_nodes(l_node_index).node_level <> g_item_level THEN
11018             l_loop_index := g_nodes(l_node_index).parent_index;
11019             LOOP
11020                IF l_tqoh > g_nodes(l_loop_index).rqoh Then
11021                   l_tqoh := g_nodes(l_loop_index).rqoh;
11022                   l_stqoh := g_nodes(l_loop_index).srqoh;           -- invConv change
11023                END IF;
11024                EXIT WHEN g_nodes(l_loop_index).node_level = g_item_level;
11025                l_loop_index :=  g_nodes(l_loop_index).parent_index;
11026             END LOOP;
11027          END IF;
11028       END IF;
11029    ELSE
11030       --org, item or lot level
11031       l_tqoh := g_nodes(l_node_index).qoh;
11032       l_stqoh := g_nodes(l_node_index).sqoh;                    -- invConv change
11033       IF g_nodes(l_node_index).node_level <> g_item_level THEN
11034          l_loop_index := g_nodes(l_node_index).parent_index;
11035          LOOP
11036             IF l_tqoh > g_nodes(l_loop_index).qoh Then
11037                l_tqoh := g_nodes(l_loop_index).qoh;
11038                l_stqoh := g_nodes(l_node_index).sqoh;                    -- invConv change
11039             END IF;
11040             EXIT WHEN g_nodes(l_loop_index).node_level = g_item_level;
11041             l_loop_index :=  g_nodes(l_loop_index).parent_index;
11042          END LOOP;
11043       END IF;
11044    END IF;
11045 
11046    x_tqoh  := l_tqoh;
11047 
11048    -- invConv changes begin:
11049    -- check whether the item is DUOM
11050    IF (g_rootinfos(l_root_id).is_DUOM_control = FALSE)
11051    THEN
11052       print_debug(' root_id='||l_root_id||', tree_id='||p_tree_id||', DUOM_control=FALSE tqoh='||x_tqoh);
11053       x_stqoh := NULL;
11054    ELSE
11055       print_debug(' root_id='||l_root_id||', tree_id='||p_tree_id||', DUOM_control=TRUE tqoh='||x_tqoh||', stqoh='||l_stqoh);
11056       x_stqoh := l_stqoh;       -- invConv change
11057    END IF;
11058    -- invConv changes end
11059 
11060    x_return_status := l_return_status;
11061 
11062    IF g_debug = 1 THEN
11063       print_debug(l_api_name || ' Exited with status = '||l_return_status||' tqoh='||l_tqoh,9);
11064       print_debug(' ',9);
11065    END IF;
11066 
11067 EXCEPTION
11068 
11069    WHEN fnd_api.g_exc_error THEN
11070       x_return_status := fnd_api.g_ret_sts_error;
11071 
11072       --  Get message count and data
11073       fnd_msg_pub.count_and_get
11074          ( p_count => x_msg_count
11075          , p_data  => x_msg_data);
11076 
11077    WHEN fnd_api.g_exc_unexpected_error THEN
11078       x_return_status := fnd_api.g_ret_sts_unexp_error ;
11079 
11080       --  Get message count and data
11081       fnd_msg_pub.count_and_get
11082          ( p_count  => x_msg_count
11083          , p_data   => x_msg_data);
11084 
11085    WHEN OTHERS THEN
11086       x_return_status := fnd_api.g_ret_sts_unexp_error ;
11087 
11088 
11089       IF fnd_msg_pub.check_msg_level(fnd_msg_pub.g_msg_lvl_unexp_error)
11090         THEN
11091          fnd_msg_pub.add_exc_msg
11092            ( g_pkg_name
11093            , 'get_total_qoh');
11094       END IF;
11095       --  Get message count and data
11096       fnd_msg_pub.count_and_get
11097           (  p_count  => x_msg_count
11098            , p_data   => x_msg_data);
11099 END get_total_qoh;
11100 
11101 --
11102 -- Procedure
11103 --   do_check_pvt
11104 -- Description
11105 --   Check quantity violation for a given base tree
11106 --
11107 --  Version
11108 --   Current version           1.0
11109 --   Initial version           1.0
11110 --
11111 -- Input parameters:
11112 --   p_api_version_number      standard input parameter
11113 --   p_init_msg_lst            standard input parameter
11114 --   p_tree_id                 tree id
11115 --
11116 -- Output parameters:
11117 --   x_return_status           standard output parameter
11118 --   x_msg_count               standard output parameter
11119 --   x_msg_data                standard output parameter
11120 --   x_no_violation            true if no violation, false otherwise
11121 --
11122 PROCEDURE do_check_pvt
11123   (    p_api_version_number  IN  NUMBER
11124      , p_init_msg_lst        IN  VARCHAR2 DEFAULT fnd_api.g_false
11125      , x_return_status       OUT NOCOPY VARCHAR2
11126      , x_msg_count           OUT NOCOPY NUMBER
11127      , x_msg_data            OUT NOCOPY VARCHAR2
11128      , p_tree_id             IN  INTEGER
11129      , x_no_violation        OUT NOCOPY BOOLEAN
11130      ) IS
11131    l_api_version_number    CONSTANT NUMBER       := 1.0;
11132    l_api_name              CONSTANT VARCHAR2(30) := 'Do_Check_Pvt';
11133    l_return_status         VARCHAR2(1) := fnd_api.g_ret_sts_success;
11134    l_no_violation          BOOLEAN;
11135 BEGIN
11136   print_debug('Entering do_check_pvt. tree_id='||p_tree_id);
11137 
11138   --  Standard call to check for call compatibility
11139    IF NOT fnd_api.compatible_api_call(l_api_version_number
11140                                       , p_api_version_number
11141                                       , l_api_name
11142                                       , G_PKG_NAME
11143                                       ) THEN
11144       RAISE fnd_api.g_exc_unexpected_error;
11145    END IF;
11146 
11147    --  Initialize message list.
11148    IF fnd_api.to_boolean(p_init_msg_lst) THEN
11149       fnd_msg_pub.initialize;
11150    END IF;
11151 
11152    -- check if tree id is valid
11153    IF is_tree_valid(p_tree_id) = FALSE THEN
11154       fnd_message.set_name('INV', 'INV-Qtyroot not found');
11155       fnd_message.set_token('ROUTINE', 'Do_Check');
11156       fnd_msg_pub.ADD;
11157       RAISE fnd_api.g_exc_unexpected_error;
11158    END IF;
11159 
11160 
11161    zero_tree_node(l_return_status, g_rootinfos(p_tree_id).item_node_index);
11162    IF l_return_status = fnd_api.g_ret_sts_error THEN
11163       RAISE fnd_api.g_exc_error;
11164    End IF ;
11165 
11166    IF l_return_status = fnd_api.g_ret_sts_unexp_error THEN
11167       RAISE fnd_api.g_exc_unexpected_error;
11168    End IF;
11169 
11170    --lock the tree - do_check must acquire tree lock before building tree
11171    print_debug('in do_check_pvt, calling lock_tree ');
11172    lock_tree(
11173               p_api_version_number  => 1.0
11174             , p_init_msg_lst        => fnd_api.g_false
11175             , x_return_status       => l_return_status
11176             , x_msg_count           => x_msg_count
11177             , x_msg_data            => x_msg_data
11178        , p_organization_id     => g_rootinfos(p_tree_id).organization_id
11179        , p_inventory_item_id   => g_rootinfos(p_tree_id).inventory_item_id
11180      );
11181 
11182    IF l_return_status = fnd_api.g_ret_sts_error THEN
11183       RAISE fnd_api.g_exc_error;
11184    END IF ;
11185 
11186    IF l_return_status = fnd_api.g_ret_sts_unexp_error THEN
11187       RAISE fnd_api.g_exc_unexpected_error;
11188    END IF;
11189 
11190    print_debug('in do_check_pvt, calling build_tree for tree_id='||p_tree_id);
11191    build_tree(l_return_status, p_tree_id);
11192    print_debug('in do_check_pvt, after build_tree... return='||l_return_status);
11193    IF l_return_status = fnd_api.g_ret_sts_error THEN
11194       RAISE fnd_api.g_exc_error;
11195    End IF ;
11196 
11197    IF l_return_status = fnd_api.g_ret_sts_unexp_error THEN
11198       RAISE fnd_api.g_exc_unexpected_error;
11199    End IF;
11200 
11201    if g_rootinfos(p_tree_id).neg_inv_allowed
11202    then
11203       print_debug('in do_check_pvt, calling check_node_violation for item_node_index='||g_rootinfos(p_tree_id).item_node_index
11204          ||', tree_mode='||g_rootinfos(p_tree_id).tree_mode||', neg_inv_allowed=TRUE');
11205    else
11206       print_debug('in do_check_pvt, calling check_node_violation for item_node_index='||g_rootinfos(p_tree_id).item_node_index
11207          ||', tree_mode='||g_rootinfos(p_tree_id).tree_mode||', neg_inv_allowed=FALSE');
11208    end if;
11209 
11210    l_no_violation :=check_node_violation(
11211        x_return_status     => l_return_status
11212       , p_node_index       => g_rootinfos(p_tree_id).item_node_index
11213       , p_tree_mode        => g_rootinfos(p_tree_id).tree_mode
11214       , p_negative_allowed => g_rootinfos(p_tree_id).neg_inv_allowed
11215       , p_item_node_index  => g_rootinfos(p_tree_id).item_node_index
11216       );
11217 
11218    print_debug('in do_check_pvt, after check_node_violation... return='||l_return_status);
11219    IF l_return_status = fnd_api.g_ret_sts_error THEN
11220       RAISE fnd_api.g_exc_error;
11221    END IF ;
11222 
11223    IF l_return_status = fnd_api.g_ret_sts_unexp_error THEN
11224       RAISE fnd_api.g_exc_unexpected_error;
11225    END IF;
11226 
11227    x_no_violation := l_no_violation;
11228    x_return_status := l_return_status;
11229 
11230    print_debug('Normal end of do_check_pvt');
11231 EXCEPTION
11232 
11233     WHEN fnd_api.g_exc_error THEN
11234         x_return_status := fnd_api.g_ret_sts_error;
11235 
11236         --  Get message count and data
11237         fnd_msg_pub.count_and_get
11238           (  p_count => x_msg_count
11239            , p_data  => x_msg_data
11240            );
11241 
11242    WHEN fnd_api.g_exc_unexpected_error THEN
11243         x_return_status := fnd_api.g_ret_sts_unexp_error ;
11244 
11245         --  Get message count and data
11246         fnd_msg_pub.count_and_get
11247           (  p_count  => x_msg_count
11248            , p_data   => x_msg_data
11249             );
11250 
11251     WHEN OTHERS THEN
11252         x_return_status := fnd_api.g_ret_sts_unexp_error ;
11253 
11254         IF fnd_msg_pub.check_msg_level(fnd_msg_pub.g_msg_lvl_unexp_error)
11255           THEN
11256            fnd_msg_pub.add_exc_msg
11257              (  g_pkg_name
11258               , l_api_name
11259               );
11260         END IF;
11261 
11262         --  Get message count and data
11263         fnd_msg_pub.count_and_get
11264           (  p_count  => x_msg_count
11265            , p_data   => x_msg_data
11266             );
11267 
11268 END do_check_pvt;
11269 
11270 
11271 --
11272 -- Procedure
11273 --   do_check
11274 -- Description
11275 --   Check quantity violation
11276 --
11277 --  Version
11278 --   Current version           1.0
11279 --   Initial version           1.0
11280 --
11281 -- Input parameters:
11282 --   p_api_version_number      standard input parameter
11283 --   p_init_msg_lst            standard input parameter
11284 --
11285 -- Output parameters:
11286 --   x_return_status           standard output parameter
11287 --   x_msg_count               standard output parameter
11288 --   x_msg_data                standard output parameter
11289 --   x_no_violation            true if no violation, false otherwise
11290 --
11291 PROCEDURE do_check
11292   (    p_api_version_number  IN  NUMBER
11293      , p_init_msg_lst        IN  VARCHAR2 DEFAULT fnd_api.g_false
11294      , x_return_status       OUT NOCOPY VARCHAR2
11295      , x_msg_count           OUT NOCOPY NUMBER
11296      , x_msg_data            OUT NOCOPY VARCHAR2
11297      , p_tree_id             IN  INTEGER
11298      , x_no_violation        OUT NOCOPY BOOLEAN
11299      ) IS
11300    l_api_version_number    CONSTANT NUMBER       := 1.0;
11301    l_api_name              CONSTANT VARCHAR2(30) := 'DO_CHECK';
11302    l_return_status         VARCHAR2(1) := fnd_api.g_ret_sts_success;
11303    l_no_violation          BOOLEAN;
11304    l_root_id         INTEGER;
11305 BEGIN
11306    IF g_debug = 1 THEN
11307       print_debug(l_api_name || ' Entered',9);
11308    END IF;
11309 
11310    print_debug('Entering do_check, tree_id='||p_tree_id, 9);
11311 
11312   --  Standard call to check for call compatibility
11313    IF NOT fnd_api.compatible_api_call(l_api_version_number
11314                                       , p_api_version_number
11315                                       , l_api_name
11316                                       , G_PKG_NAME
11317                                       ) THEN
11318       RAISE fnd_api.g_exc_unexpected_error;
11319    END IF;
11320 
11321    --  Initialize message list.
11322    IF fnd_api.to_boolean(p_init_msg_lst) THEN
11323       fnd_msg_pub.initialize;
11324    END IF;
11325 
11326    --call do_check on the base tree
11327    l_root_id := g_demand_info(p_tree_id).root_id;
11328 
11329    do_check_pvt(
11330               p_api_version_number  => 1.0
11331             , p_init_msg_lst        => fnd_api.g_false
11332             , x_return_status       => l_return_status
11333             , x_msg_count           => x_msg_count
11334             , x_msg_data            => x_msg_data
11335             , p_tree_id             => l_root_id
11336             , x_no_violation        => l_no_violation
11337             );
11338    print_debug('In do_check, after do_check_pvt, return='||l_return_status);
11339    IF l_return_status = fnd_api.g_ret_sts_error THEN
11340             RAISE fnd_api.g_exc_error;
11341    END IF ;
11342 
11343    IF l_return_status = fnd_api.g_ret_sts_unexp_error THEN
11344             RAISE fnd_api.g_exc_unexpected_error;
11345    END IF;
11346 
11347    -- Bug 7340567, printing the tree to verify node violation
11348    print_tree(p_tree_id);
11349 
11350    x_no_violation := l_no_violation;
11351    x_return_status := l_return_status;
11352 
11353    IF g_debug = 1 THEN
11354      if l_no_violation then
11355        print_debug(l_api_name || ' Exited with no violation detected',9);
11356      else
11357        print_debug(l_api_name || ' Exited with violation detected',9);
11358      end if;
11359      print_debug(' ',9);
11360    END IF;
11361 EXCEPTION
11362 
11363     WHEN fnd_api.g_exc_error THEN
11364         x_return_status := fnd_api.g_ret_sts_error;
11365 
11366         --  Get message count and data
11367         fnd_msg_pub.count_and_get
11368           (  p_count => x_msg_count
11369            , p_data  => x_msg_data
11370            );
11371 
11372    WHEN fnd_api.g_exc_unexpected_error THEN
11373         x_return_status := fnd_api.g_ret_sts_unexp_error ;
11374 
11375         --  Get message count and data
11376         fnd_msg_pub.count_and_get
11377           (  p_count  => x_msg_count
11378            , p_data   => x_msg_data
11379             );
11380 
11381     WHEN OTHERS THEN
11382         x_return_status := fnd_api.g_ret_sts_unexp_error ;
11383 
11384         IF fnd_msg_pub.check_msg_level(fnd_msg_pub.g_msg_lvl_unexp_error)
11385           THEN
11386            fnd_msg_pub.add_exc_msg
11387              (  g_pkg_name
11388               , l_api_name
11389               );
11390         END IF;
11391 
11392         --  Get message count and data
11393         fnd_msg_pub.count_and_get
11394           (  p_count  => x_msg_count
11395            , p_data   => x_msg_data
11396             );
11397 
11398 END do_check;
11399 
11400 
11401 --
11402 -- Procedure
11403 --   do_check
11404 -- Description
11405 --   Check quantity violation
11406 --
11407 --  Version
11408 --   Current version           1.0
11409 --   Initial version           1.0
11410 --
11411 -- Input parameters:
11412 --   p_api_version_number      standard input parameter
11413 --   p_init_msg_lst            standard input parameter
11414 --
11415 -- Output parameters:
11416 --   x_return_status           standard output parameter
11417 --   x_msg_count               standard output parameter
11418 --   x_msg_data                standard output parameter
11419 --   x_no_violation            true if no violation, false otherwise
11420 --
11421 PROCEDURE do_check
11422   (    p_api_version_number  IN  NUMBER
11423      , p_init_msg_lst        IN  VARCHAR2
11424      , x_return_status       OUT NOCOPY VARCHAR2
11425      , x_msg_count           OUT NOCOPY NUMBER
11426      , x_msg_data            OUT NOCOPY VARCHAR2
11427      , x_no_violation        OUT NOCOPY BOOLEAN
11428      ) IS
11429    l_api_version_number    CONSTANT NUMBER       := 1.0;
11430    l_api_name              CONSTANT VARCHAR2(30) := 'DO_CHECK_ALL';
11431    l_return_status         VARCHAR2(1) := fnd_api.g_ret_sts_success;
11432    l_no_violation          BOOLEAN;
11433    l_root_id         NUMBER;
11434    l_org_id       NUMBER;
11435    l_item_id         NUMBER;
11436    l_lot_ctrl        NUMBER;
11437    l_line_id         NUMBER;
11438    l_root_id_tmp           NUMBER;
11439 
11440    CURSOR C1 is
11441    SELECT root_id
11442    FROM   mtl_do_check_temp
11443    ORDER BY organization_id, inventory_item_id;
11444 BEGIN
11445 
11446    IF g_debug = 1 THEN
11447       print_debug(l_api_name || ' Entered',9);
11448    END IF;
11449 
11450    --  Standard call to check for call compatibility
11451    IF NOT fnd_api.compatible_api_call(l_api_version_number
11452                                       , p_api_version_number
11453                                       , l_api_name
11454                                       , G_PKG_NAME
11455                                       ) THEN
11456       RAISE fnd_api.g_exc_unexpected_error;
11457    END IF;
11458 
11459    --  Initialize message list.
11460    IF fnd_api.to_boolean(p_init_msg_lst) THEN
11461       fnd_msg_pub.initialize;
11462    END IF;
11463 
11464    for l_loop_index IN 1..g_all_roots_counter LOOP
11465       l_root_id := g_all_roots(l_loop_index).root_id;
11466       l_org_id := g_rootinfos(l_root_id).organization_id;
11467       l_item_id := g_rootinfos(l_root_id).inventory_item_id;
11468       if (g_rootinfos(l_root_id).is_lot_control) THEN
11469          l_lot_ctrl := 2;
11470       else
11471          l_lot_ctrl := 1;
11472       end if;
11473       l_line_id := g_rootinfos(l_root_id).demand_source_line_id;
11474 
11475       --Now insert into temp table;
11476       insert into mtl_do_check_temp
11477          (   ROOT_ID
11478             ,ORGANIZATION_ID
11479             ,INVENTORY_ITEM_ID
11480             ,LOT_CONTROL
11481             ,LINE_ID)
11482          values
11483          (   l_root_id
11484             ,l_org_id
11485             ,l_item_id
11486             ,l_lot_ctrl
11487             ,l_line_id);
11488    end loop;
11489 
11490    open c1;
11491    loop
11492       fetch c1 into l_root_id_tmp;
11493       EXIT WHEN c1%NOTFOUND;
11494 
11495       IF is_tree_valid(l_root_id_tmp) THEN
11496          do_check_pvt( p_api_version_number  => 1.0
11497                       ,p_init_msg_lst        => fnd_api.g_false
11498                       ,x_return_status       => l_return_status
11499                       ,x_msg_count           => x_msg_count
11500                       ,x_msg_data            => x_msg_data
11501                       ,p_tree_id             => l_root_id_tmp
11502                       ,x_no_violation        => l_no_violation);
11503          IF l_return_status = fnd_api.g_ret_sts_error THEN
11504             RAISE fnd_api.g_exc_error;
11505          END IF ;
11506 
11507          IF l_return_status = fnd_api.g_ret_sts_unexp_error THEN
11508             RAISE fnd_api.g_exc_unexpected_error;
11509          END IF;
11510 
11511          IF l_no_violation = FALSE THEN
11512             --utl_debug1('do_check_pvt returns false to do_check');
11513             EXIT;
11514          END IF;
11515       END IF;
11516    END LOOP;
11517 
11518 
11519 
11520 -- find all valid base trees and do_check them
11521 --   FOR l_loop_index IN 1..g_all_roots_counter LOOP
11522 --      l_root_id := g_all_roots(l_loop_index).root_id;
11523 --      IF is_tree_valid(l_root_id) THEN
11524 --         do_check_pvt
11525 --           (
11526 --              p_api_version_number  => 1.0
11527 --            , p_init_msg_lst        => fnd_api.g_false
11528 --            , x_return_status       => l_return_status
11529 --            , x_msg_count           => x_msg_count
11530 --            , x_msg_data            => x_msg_data
11531 --            , p_tree_id             => l_root_id
11532 --            , x_no_violation        => l_no_violation
11533 --            );
11534 --         IF l_return_status = fnd_api.g_ret_sts_error THEN
11535 --            RAISE fnd_api.g_exc_error;
11536 --         END IF ;
11537 --
11538 --         IF l_return_status = fnd_api.g_ret_sts_unexp_error THEN
11539 --            RAISE fnd_api.g_exc_unexpected_error;
11540 --         END IF;
11541 --
11542 --   IF l_no_violation = FALSE THEN
11543 --    utl_debug1('do_check_pvt returns false to do_check');
11544 --    EXIT;
11545 --   END IF;
11546 
11547 --     END IF;
11548 --   END LOOP;
11549 
11550    x_no_violation := l_no_violation;
11551    x_return_status := l_return_status;
11552 
11553    IF g_debug = 1 THEN
11554      IF l_no_violation THEN
11555        print_debug(l_api_name || ' Exited with no violation detected',9);
11556      ELSE
11557        print_debug(l_api_name || ' Exited with violation detected',9);
11558      END IF;
11559      print_debug(' ',9);
11560    END IF;
11561 
11562 EXCEPTION
11563 
11564     WHEN fnd_api.g_exc_error THEN
11565         x_return_status := fnd_api.g_ret_sts_error;
11566 
11567         --  Get message count and data
11568         fnd_msg_pub.count_and_get
11569           (  p_count => x_msg_count
11570            , p_data  => x_msg_data
11571            );
11572 
11573    WHEN fnd_api.g_exc_unexpected_error THEN
11574         x_return_status := fnd_api.g_ret_sts_unexp_error ;
11575 
11576         --  Get message count and data
11577         fnd_msg_pub.count_and_get
11578           (  p_count  => x_msg_count
11579            , p_data   => x_msg_data
11580             );
11581 
11582     WHEN OTHERS THEN
11583         x_return_status := fnd_api.g_ret_sts_unexp_error ;
11584 
11585         IF fnd_msg_pub.check_msg_level(fnd_msg_pub.g_msg_lvl_unexp_error)
11586           THEN
11587            fnd_msg_pub.add_exc_msg
11588              (  g_pkg_name
11589               , l_api_name
11590               );
11591         END IF;
11592 
11593         --  Get message count and data
11594         fnd_msg_pub.count_and_get
11595           (  p_count  => x_msg_count
11596            , p_data   => x_msg_data
11597             );
11598 
11599 END do_check;
11600 
11601 --
11602 -- Procedure
11603 --   free_tree_pvt
11604 -- Description
11605 --   free the tree when it is no longer needed
11606 --   This takes the base tree id
11607 --
11608 --  Version
11609 --   Current version           1.0
11610 --   Initial version           1.0
11611 --
11612 -- Input parameters:
11613 --   p_api_version_number      standard input parameter
11614 --   p_init_msg_lst            standard input parameter
11615 --   p_tree_id                 tree id
11616 --
11617 -- Output parameters:
11618 --   x_return_status           standard output parameter
11619 --   x_msg_count               standard output parameter
11620 --   x_msg_data                standard output parameter
11621 --
11622 PROCEDURE free_tree_pvt
11623   (    p_api_version_number  IN  NUMBER
11624      , p_init_msg_lst        IN  VARCHAR2 DEFAULT fnd_api.g_false
11625      , x_return_status       OUT NOCOPY VARCHAR2
11626      , x_msg_count           OUT NOCOPY NUMBER
11627      , x_msg_data            OUT NOCOPY VARCHAR2
11628      , p_tree_id             IN  INTEGER
11629      ) IS
11630    l_api_version_number    CONSTANT NUMBER       := 1.0;
11631    l_api_name              CONSTANT VARCHAR2(30) := 'Free_Tree_Pvt';
11632    l_return_status         VARCHAR2(1) := fnd_api.g_ret_sts_success;
11633 BEGIN
11634 
11635   --  Standard call to check for call compatibility
11636    IF NOT fnd_api.compatible_api_call(l_api_version_number
11637                                       , p_api_version_number
11638                                       , l_api_name
11639                                       , G_PKG_NAME
11640                                       ) THEN
11641       RAISE fnd_api.g_exc_unexpected_error;
11642    END IF;
11643 
11644    --  Initialize message list.
11645    IF fnd_api.to_boolean(p_init_msg_lst) THEN
11646       fnd_msg_pub.initialize;
11647    END IF;
11648   /*  This code was causing bug.  As soon as one invalid tree
11649    *  was reached, no other trees were freed.
11650    *  Invalidate_tree checks this condition, but doesn't return error.
11651    *  There's no need for error.  So, commenting out code
11652    *-- check if tree id is valid
11653    *IF is_tree_valid(p_tree_id) = FALSE THEN
11654    *   fnd_message.set_name('INV', 'INV-Qtyroot not found');
11655    *   fnd_message.set_token('ROUTINE', 'Free_Tree');
11656    *   fnd_msg_pub.ADD;
11657    *   RAISE fnd_api.g_exc_unexpected_error;
11658    *END IF;
11659    */
11660    invalidate_tree(p_tree_id);
11661 
11662    x_return_status := l_return_status;
11663 
11664 EXCEPTION
11665 
11666     WHEN fnd_api.g_exc_error THEN
11667         x_return_status := fnd_api.g_ret_sts_error;
11668 
11669         --  Get message count and data
11670         fnd_msg_pub.count_and_get
11671           (  p_count => x_msg_count
11672            , p_data  => x_msg_data
11673            );
11674 
11675     WHEN fnd_api.g_exc_unexpected_error THEN
11676         x_return_status := fnd_api.g_ret_sts_unexp_error ;
11677 
11678         --  Get message count and data
11679         fnd_msg_pub.count_and_get
11680           (  p_count  => x_msg_count
11681            , p_data   => x_msg_data
11682             );
11683 
11684     WHEN OTHERS THEN
11685         x_return_status := fnd_api.g_ret_sts_unexp_error ;
11686 
11687         IF fnd_msg_pub.check_msg_level(fnd_msg_pub.g_msg_lvl_unexp_error)
11688           THEN
11689            fnd_msg_pub.add_exc_msg
11690              (  g_pkg_name
11691               , l_api_name
11692               );
11693         END IF;
11694 
11695         --  Get message count and data
11696         fnd_msg_pub.count_and_get
11697           (  p_count  => x_msg_count
11698            , p_data   => x_msg_data
11699             );
11700 
11701 END free_tree_pvt;
11702 
11703 
11704 --
11705 -- Procedure
11706 --   free_tree
11707 -- Description
11708 --   free all the trees
11709 --   This takes the demand info id
11710 --     (tree_id returned by create_tree)
11711 --
11712 --  Version
11713 --   Current version           1.0
11714 --   Initial version           1.0
11715 --
11716 -- Input parameters:
11717 --   p_api_version_number      standard input parameter
11718 --   p_init_msg_lst            standard input parameter
11719 --
11720 -- Output parameters:
11721 --   x_return_status           standard output parameter
11722 --   x_msg_count               standard output parameter
11723 --   x_msg_data                standard output parameter
11724 --
11725 PROCEDURE free_tree
11726   (  p_api_version_number  IN  NUMBER
11727    , p_init_msg_lst        IN  VARCHAR2
11728    , x_return_status       OUT NOCOPY VARCHAR2
11729    , x_msg_count           OUT NOCOPY NUMBER
11730    , x_msg_data            OUT NOCOPY VARCHAR2
11731    , p_tree_id             IN  INTEGER
11732    )
11733 IS
11734 
11735    l_api_version_number    CONSTANT NUMBER       := 1.0;
11736    l_api_name              CONSTANT VARCHAR2(30) := 'FREE_TREE';
11737    l_return_status         VARCHAR2(1) := fnd_api.g_ret_sts_success;
11738    l_root_id               INTEGER;
11739 
11740 BEGIN
11741 
11742    IF g_debug = 1 THEN
11743       print_debug(l_api_name || ' Entered',9);
11744    END IF;
11745 
11746    --  Standard call to check for call compatibility
11747    IF NOT fnd_api.compatible_api_call(l_api_version_number
11748                                       , p_api_version_number
11749                                       , l_api_name
11750                                       , G_PKG_NAME
11751                                       ) THEN
11752       RAISE fnd_api.g_exc_unexpected_error;
11753    END IF;
11754 
11755    --  Initialize message list.
11756    IF fnd_api.to_boolean(p_init_msg_lst) THEN
11757       fnd_msg_pub.initialize;
11758    END IF;
11759 
11760    --call free_tree on base_tree
11761    l_root_id := g_demand_info(p_tree_id).root_id;
11762 
11763    free_tree_pvt(
11764             p_api_version_number => l_api_version_number
11765           , p_init_msg_lst       => fnd_api.g_false
11766           , x_return_status      => l_return_status
11767           , x_msg_count          => x_msg_count
11768           , x_msg_data           => x_msg_data
11769           , p_tree_id            => l_root_id
11770       );
11771 
11772    IF l_return_status = fnd_api.g_ret_sts_error THEN
11773       RAISE fnd_api.g_exc_error;
11774    End IF ;
11775 
11776    IF l_return_status = fnd_api.g_ret_sts_unexp_error THEN
11777       RAISE fnd_api.g_exc_unexpected_error;
11778    End IF;
11779 
11780 
11781    x_return_status := l_return_status;
11782 
11783 EXCEPTION
11784 
11785     WHEN fnd_api.g_exc_error THEN
11786         x_return_status := fnd_api.g_ret_sts_error;
11787 
11788         --  Get message count and data
11789         fnd_msg_pub.count_and_get
11790           (  p_count => x_msg_count
11791            , p_data  => x_msg_data
11792            );
11793 
11794     WHEN fnd_api.g_exc_unexpected_error THEN
11795         x_return_status := fnd_api.g_ret_sts_unexp_error ;
11796 
11797         --  Get message count and data
11798         fnd_msg_pub.count_and_get
11799           (  p_count  => x_msg_count
11800            , p_data   => x_msg_data
11801             );
11802 
11803     WHEN OTHERS THEN
11804         x_return_status := fnd_api.g_ret_sts_unexp_error ;
11805 
11806         IF fnd_msg_pub.check_msg_level(fnd_msg_pub.g_msg_lvl_unexp_error)
11807           THEN
11808            fnd_msg_pub.add_exc_msg
11809              (  g_pkg_name
11810               , l_api_name
11811               );
11812         END IF;
11813 
11814         --  Get message count and data
11815         fnd_msg_pub.count_and_get
11816           (  p_count  => x_msg_count
11817            , p_data   => x_msg_data
11818             );
11819 
11820 END free_tree;
11821 
11822 
11823 --
11824 -- Procedure
11825 --   free_all
11826 -- Description
11827 --   free all the trees
11828 --
11829 --  Version
11830 --   Current version           1.0
11831 --   Initial version           1.0
11832 --
11833 -- Input parameters:
11834 --   p_api_version_number      standard input parameter
11835 --   p_init_msg_lst            standard input parameter
11836 --
11837 -- Output parameters:
11838 --   x_return_status           standard output parameter
11839 --   x_msg_count               standard output parameter
11840 --   x_msg_data                standard output parameter
11841 --
11842 PROCEDURE free_all
11843   (  p_api_version_number  IN  NUMBER
11844    , p_init_msg_lst        IN  VARCHAR2
11845    , x_return_status       OUT NOCOPY VARCHAR2
11846    , x_msg_count           OUT NOCOPY NUMBER
11847    , x_msg_data            OUT NOCOPY VARCHAR2
11848    )
11849 IS
11850 
11851    l_api_version_number    CONSTANT NUMBER       := 1.0;
11852    l_api_name              CONSTANT VARCHAR2(30) := 'Free_All';
11853    l_return_status         VARCHAR2(1) := fnd_api.g_ret_sts_success;
11854    l_root_id         NUMBER;
11855 
11856 BEGIN
11857 
11858    --  Standard call to check for call compatibility
11859    IF NOT fnd_api.compatible_api_call(l_api_version_number
11860                                       , p_api_version_number
11861                                       , l_api_name
11862                                       , G_PKG_NAME
11863                                       ) THEN
11864       RAISE fnd_api.g_exc_unexpected_error;
11865    END IF;
11866 
11867    --  Initialize message list.
11868    IF fnd_api.to_boolean(p_init_msg_lst) THEN
11869       fnd_msg_pub.initialize;
11870    END IF;
11871 
11872    FOR l_loop_index IN 1..g_all_roots_counter LOOP
11873       l_root_id := g_all_roots(l_loop_index).root_id;
11874       free_tree_pvt(
11875            p_api_version_number => l_api_version_number
11876           ,p_init_msg_lst      => fnd_api.g_false
11877           ,x_return_status => l_return_status
11878      ,x_msg_count    => x_msg_count
11879           ,x_msg_data      => x_msg_data
11880           ,p_tree_id    => l_root_id
11881       );
11882 
11883       IF l_return_status = fnd_api.g_ret_sts_error THEN
11884          RAISE fnd_api.g_exc_error;
11885       End IF ;
11886 
11887       IF l_return_status = fnd_api.g_ret_sts_unexp_error THEN
11888          RAISE fnd_api.g_exc_unexpected_error;
11889       End IF;
11890 
11891   END LOOP;
11892 
11893    x_return_status := l_return_status;
11894 
11895 EXCEPTION
11896 
11897     WHEN fnd_api.g_exc_error THEN
11898         x_return_status := fnd_api.g_ret_sts_error;
11899 
11900         --  Get message count and data
11901         fnd_msg_pub.count_and_get
11902           (  p_count => x_msg_count
11903            , p_data  => x_msg_data
11904            );
11905 
11906    WHEN fnd_api.g_exc_unexpected_error THEN
11907         x_return_status := fnd_api.g_ret_sts_unexp_error ;
11908 
11909         --  Get message count and data
11910         fnd_msg_pub.count_and_get
11911           (  p_count  => x_msg_count
11912            , p_data   => x_msg_data
11913             );
11914 
11915     WHEN OTHERS THEN
11916         x_return_status := fnd_api.g_ret_sts_unexp_error ;
11917 
11918         IF fnd_msg_pub.check_msg_level(fnd_msg_pub.g_msg_lvl_unexp_error)
11919           THEN
11920            fnd_msg_pub.add_exc_msg
11921              (  g_pkg_name
11922               , l_api_name
11923               );
11924         END IF;
11925 
11926         --  Get message count and data
11927         fnd_msg_pub.count_and_get
11928           (  p_count  => x_msg_count
11929            , p_data   => x_msg_data
11930             );
11931 
11932 END free_all;
11933 
11934 --
11935 -- Procedure
11936 --   mark_all_for_refresh
11937 -- Description
11938 --   marks all existing trees as needing to be rebuilt. Unlike
11939 --   free_tree and clear_quantity_cache, no quantity trees are deleted.
11940 --
11941 --   This API is needed so that the do_check_for_commit procedure in
11942 --   INVRSV3B.pls will still work.  That procedure stores tree_ids in a
11943 --   temp table. When clear_quantity_cache is called, these tree_ids are
11944 --   no longer valid. When this is called instead of clear_quantity_cache,
11945 --   the tree_ids are still valid to be passed to do_check.
11946 --
11947 --
11948 --  Version
11949 --   Current version           1.0
11950 --   Initial version           1.0
11951 --
11952 -- Input parameters:
11953 --   p_api_version_number      standard input parameter
11954 --   p_init_msg_lst            standard input parameter
11955 --
11956 -- Output parameters:
11957 --   x_return_status           standard output parameter
11958 --   x_msg_count               standard output parameter
11959 --   x_msg_data                standard output parameter
11960 --
11961 PROCEDURE mark_all_for_refresh
11962   (  p_api_version_number  IN  NUMBER
11963    , p_init_msg_lst        IN  VARCHAR2
11964    , x_return_status       OUT NOCOPY VARCHAR2
11965    , x_msg_count           OUT NOCOPY NUMBER
11966    , x_msg_data            OUT NOCOPY VARCHAR2
11967    ) IS
11968 
11969    l_api_version_number    CONSTANT NUMBER       := 1.0;
11970    l_api_name              CONSTANT VARCHAR2(30) := 'Mark_All_For_Refresh';
11971    l_return_status         VARCHAR2(1) := fnd_api.g_ret_sts_success;
11972    l_root_id               NUMBER;
11973 
11974 BEGIN
11975 
11976    --  Standard call to check for call compatibility
11977    IF NOT fnd_api.compatible_api_call(l_api_version_number
11978                                       , p_api_version_number
11979                                       , l_api_name
11980                                       , G_PKG_NAME
11981                                       ) THEN
11982       RAISE fnd_api.g_exc_unexpected_error;
11983    END IF;
11984 
11985    --  Initialize message list.
11986    IF fnd_api.to_boolean(p_init_msg_lst) THEN
11987       fnd_msg_pub.initialize;
11988    END IF;
11989 
11990    FOR l_loop_index IN 1..g_all_roots_counter LOOP
11991       l_root_id := g_all_roots(l_loop_index).root_id;
11992       If is_tree_valid(l_root_id) THEN
11993         g_rootinfos(l_root_id).need_refresh := TRUE;
11994       End If;
11995    END LOOP;
11996 
11997 
11998 EXCEPTION
11999 
12000     WHEN fnd_api.g_exc_error THEN
12001         x_return_status := fnd_api.g_ret_sts_error;
12002 
12003         --  Get message count and data
12004         fnd_msg_pub.count_and_get
12005           (  p_count => x_msg_count
12006            , p_data  => x_msg_data
12007            );
12008 
12009    WHEN fnd_api.g_exc_unexpected_error THEN
12010         x_return_status := fnd_api.g_ret_sts_unexp_error ;
12011 
12012         --  Get message count and data
12013         fnd_msg_pub.count_and_get
12014           (  p_count  => x_msg_count
12015            , p_data   => x_msg_data
12016             );
12017 
12018     WHEN OTHERS THEN
12019         x_return_status := fnd_api.g_ret_sts_unexp_error ;
12020 
12021         IF fnd_msg_pub.check_msg_level(fnd_msg_pub.g_msg_lvl_unexp_error)
12022           THEN
12023            fnd_msg_pub.add_exc_msg
12024              (  g_pkg_name
12025               , l_api_name
12026               );
12027         END IF;
12028 
12029         --  Get message count and data
12030         fnd_msg_pub.count_and_get
12031           (  p_count  => x_msg_count
12032            , p_data   => x_msg_data
12033             );
12034 
12035 END mark_all_for_refresh;
12036 
12037 -- Procedure
12038 --   update_quantities
12039 -- Description
12040 --   Create a quantity tree
12041 --
12042 --  Version
12043 --   Current version        1.0
12044 --   Initial version        1.0
12045 --
12046 -- Input parameters:
12047 --   p_api_version_number   standard input parameter
12048 --   p_init_msg_lst         standard input parameter
12049 --   p_tree_id              tree_id
12050 --   p_revision             revision
12051 --   p_lot_number           lot_number
12052 --   p_subinventory_code    subinventory_code
12053 --   p_locator_id           locator_id
12054 --   p_primary_quantity     primary_quantity
12055 --   p_quantity_type
12056 --
12057 -- Output parameters:
12058 --   x_return_status       standard output parameter
12059 --   x_msg_count           standard output parameter
12060 --   x_msg_data            standard output parameter
12061 --   x_tree_id             used later to refer to the same tree
12062 --   x_qoh                 qoh   after the update
12063 --   x_rqoh                rqoh  after the update
12064 --   x_qr                  qr    after the update
12065 --   x_qs                  qs    after the update
12066 --   x_att                 att   after the update
12067 --   x_atr                 atr   after the update
12068 PROCEDURE update_quantities
12069   (  p_api_version_number    IN  NUMBER
12070    , p_init_msg_lst          IN  VARCHAR2
12071    , x_return_status         OUT NOCOPY VARCHAR2
12072    , x_msg_count             OUT NOCOPY NUMBER
12073    , x_msg_data              OUT NOCOPY VARCHAR2
12074    , p_tree_id               IN  INTEGER
12075    , p_revision              IN  VARCHAR2
12076    , p_lot_number            IN  VARCHAR2
12077    , p_subinventory_code     IN  VARCHAR2
12078    , p_locator_id            IN  NUMBER
12079    , p_primary_quantity      IN  NUMBER
12080    , p_quantity_type         IN  INTEGER
12081    , x_qoh                   OUT NOCOPY NUMBER
12082    , x_rqoh                  OUT NOCOPY NUMBER
12083    , x_qr                    OUT NOCOPY NUMBER
12084    , x_qs                    OUT NOCOPY NUMBER
12085    , x_att                   OUT NOCOPY NUMBER
12086    , x_atr                   OUT NOCOPY NUMBER
12087    , p_transfer_subinventory_code IN  VARCHAR2
12088    , p_cost_group_id         IN  NUMBER
12089    , p_containerized         IN  NUMBER
12090    , p_lpn_id                IN  NUMBER
12091    , p_transfer_locator_id   IN  NUMBER
12092      ) IS
12093 
12094 l_secondary_quantity  NUMBER;    -- invConv change
12095 l_sqoh    NUMBER;     -- invConv change
12096 l_srqoh   NUMBER;     -- invConv change
12097 l_sqr     NUMBER;     -- invConv change
12098 l_sqs     NUMBER;     -- invConv change
12099 l_satt    NUMBER;     -- invConv change
12100 l_satr    NUMBER;     -- invConv change
12101 BEGIN
12102 
12103 -- invConv changes begin:
12104 -- Calling the new signature API
12105 inv_quantity_tree_pvt.update_quantities
12106   (  p_api_version_number    => p_api_version_number
12107    , p_init_msg_lst          => p_init_msg_lst
12108    , x_return_status         => x_return_status
12109    , x_msg_count             => x_msg_count
12110    , x_msg_data              => x_msg_data
12111    , p_tree_id               => p_tree_id
12112    , p_revision              => p_revision
12113    , p_lot_number            => p_lot_number
12114    , p_subinventory_code     => p_subinventory_code
12115    , p_locator_id            => p_locator_id
12116    , p_primary_quantity      => p_primary_quantity
12117    , p_secondary_quantity    => l_secondary_quantity        -- invConv change
12118    , p_quantity_type         => p_quantity_type
12119    , x_qoh                   => x_qoh
12120    , x_rqoh                  => x_rqoh
12121    , x_qr                    => x_qr
12122    , x_qs                    => x_qs
12123    , x_att                   => x_att
12124    , x_atr                   => x_atr
12125    , x_sqoh                  => l_sqoh                       -- invConv change
12126    , x_srqoh                 => l_srqoh                      -- invConv change
12127    , x_sqr                   => l_sqr                        -- invConv change
12128    , x_sqs                   => l_sqs                        -- invConv change
12129    , x_satt                  => l_satt                       -- invConv change
12130    , x_satr                  => l_satr                       -- invConv change
12131    , p_transfer_subinventory_code => p_transfer_subinventory_code
12132    , p_cost_group_id         => p_cost_group_id
12133    , p_containerized         => p_containerized
12134    , p_lpn_id                => p_lpn_id
12135    , p_transfer_locator_id   => p_transfer_locator_id);
12136 
12137 END update_quantities;
12138 
12139 -- invConv changes begin: overload
12140 PROCEDURE update_quantities
12141   (  p_api_version_number    IN  NUMBER
12142    , p_init_msg_lst          IN  VARCHAR2
12143    , x_return_status         OUT NOCOPY VARCHAR2
12144    , x_msg_count             OUT NOCOPY NUMBER
12145    , x_msg_data              OUT NOCOPY VARCHAR2
12146    , p_tree_id               IN  INTEGER
12147    , p_revision              IN  VARCHAR2
12148    , p_lot_number            IN  VARCHAR2
12149    , p_subinventory_code     IN  VARCHAR2
12150    , p_locator_id            IN  NUMBER
12151    , p_primary_quantity      IN  NUMBER
12152    , p_secondary_quantity    IN  NUMBER               -- invConv change
12153    , p_quantity_type         IN  INTEGER
12154    , x_qoh                   OUT NOCOPY NUMBER
12155    , x_rqoh                  OUT NOCOPY NUMBER
12156    , x_qr                    OUT NOCOPY NUMBER
12157    , x_qs                    OUT NOCOPY NUMBER
12158    , x_att                   OUT NOCOPY NUMBER
12159    , x_atr                   OUT NOCOPY NUMBER
12160    , x_sqoh                  OUT NOCOPY NUMBER               -- invConv change
12161    , x_srqoh                 OUT NOCOPY NUMBER               -- invConv change
12162    , x_sqr                   OUT NOCOPY NUMBER               -- invConv change
12163    , x_sqs                   OUT NOCOPY NUMBER               -- invConv change
12164    , x_satt                  OUT NOCOPY NUMBER               -- invConv change
12165    , x_satr                  OUT NOCOPY NUMBER               -- invConv change
12166    , p_transfer_subinventory_code IN  VARCHAR2
12167    , p_cost_group_id         IN  NUMBER
12168    , p_containerized         IN  NUMBER
12169    , p_lpn_id                IN  NUMBER
12170    , p_transfer_locator_id   IN  NUMBER
12171      ) IS
12172       l_api_version_number   CONSTANT NUMBER       := 1.0;
12173       l_api_name             CONSTANT VARCHAR2(30) := 'UPDATE_QUANTITIES';
12174       l_return_status        VARCHAR2(1) := fnd_api.g_ret_sts_success;
12175       l_root_id        INTEGER;
12176 BEGIN
12177    IF g_debug = 1 THEN
12178       print_debug(l_api_name || ' Entered',9);
12179    END IF;
12180 
12181    print_debug('Entering update_quantities. primQty='||p_primary_quantity||', secQty='||p_secondary_quantity);
12182 
12183    --  Standard call to check for call compatibility
12184    IF NOT fnd_api.compatible_api_call(l_api_version_number
12185                                       , p_api_version_number
12186                                       , l_api_name
12187                                       , G_PKG_NAME
12188                                       ) THEN
12189       RAISE fnd_api.g_exc_unexpected_error;
12190    END IF;
12191 
12192    --  Initialize message list.
12193    IF fnd_api.to_boolean(p_init_msg_lst) THEN
12194       fnd_msg_pub.initialize;
12195    END IF;
12196 
12197    l_root_id := g_demand_info(p_tree_id).root_id;
12198    -- check if tree id is valid
12199    IF is_tree_valid(l_root_id) = FALSE THEN
12200       fnd_message.set_name('INV', 'INV-Qtyroot not found');
12201       fnd_message.set_token('ROUTINE', 'Update_Quantities');
12202       fnd_msg_pub.ADD;
12203       RAISE fnd_api.g_exc_unexpected_error;
12204    END IF;
12205 
12206    print_debug('in update_quantities, calling add_quantities qty1='||p_primary_quantity||', qty2='||p_secondary_quantity||'.');
12207    add_quantities(
12208         x_return_status     => l_return_status
12209       , p_tree_id           => l_root_id
12210       , p_revision          => p_revision
12211       , p_lot_number        => p_lot_number
12212       , p_subinventory_code => p_subinventory_code
12213       , p_is_reservable_sub => NULL
12214       , p_locator_id        => p_locator_id
12215       , p_primary_quantity  => p_primary_quantity
12216       , p_secondary_quantity=> p_secondary_quantity       -- invConv change
12217       , p_quantity_type     => p_quantity_type
12218       , p_set_check_mark    => TRUE
12219       , p_cost_group_id     => p_cost_group_id
12220       , p_lpn_id            => p_lpn_id
12221       );
12222 
12223    IF l_return_status = fnd_api.g_ret_sts_error THEN
12224       RAISE fnd_api.g_exc_error;
12225    End IF ;
12226 
12227    IF l_return_status = fnd_api.g_ret_sts_unexp_error THEN
12228       RAISE fnd_api.g_exc_unexpected_error;
12229    End IF;
12230 
12231    -- query the quantities after the update
12232    query_tree
12233      (
12234         p_api_version_number => 1.0
12235       , p_init_msg_lst       => fnd_api.g_false
12236       , x_return_status      => l_return_status
12237       , x_msg_count          => x_msg_count
12238       , x_msg_data           => x_msg_data
12239       , p_tree_id            => p_tree_id
12240       , p_revision           => p_revision
12241       , p_lot_number         => p_lot_number
12242       , p_subinventory_code  => p_subinventory_code
12243       , p_locator_id         => p_locator_id
12244       , x_qoh                => x_qoh
12245       , x_rqoh               => x_rqoh
12246       , x_qr                 => x_qr
12247       , x_qs                 => x_qs
12248       , x_att                => x_att
12249       , x_atr                => x_atr
12250       , x_sqoh               => x_sqoh              -- invConv change
12251       , x_srqoh              => x_srqoh             -- invConv change
12252       , x_sqr                => x_sqr               -- invConv change
12253       , x_sqs                => x_sqs               -- invConv change
12254       , x_satt               => x_satt              -- invConv change
12255       , x_satr               => x_satr              -- invConv change
12256       , p_transfer_subinventory_code => p_transfer_subinventory_code
12257       , p_cost_group_id      => p_cost_group_id
12258       , p_lpn_id             => p_lpn_id
12259       , p_transfer_locator_id => p_transfer_locator_id
12260       );
12261 
12262    IF l_return_status = fnd_api.g_ret_sts_error THEN
12263       RAISE fnd_api.g_exc_error;
12264    End IF ;
12265 
12266    IF l_return_status = fnd_api.g_ret_sts_unexp_error THEN
12267       RAISE fnd_api.g_exc_unexpected_error;
12268    End IF;
12269 
12270    x_return_status := l_return_status;
12271 
12272    IF g_debug = 1 THEN
12273       print_debug(l_api_name || ' Exited with status = '||l_return_status,9);
12274       print_debug(' ',9);
12275    END IF;
12276 
12277 EXCEPTION
12278 
12279     WHEN fnd_api.g_exc_error THEN
12280         x_return_status := fnd_api.g_ret_sts_error;
12281 
12282         --  Get message count and data
12283         fnd_msg_pub.count_and_get
12284           (  p_count => x_msg_count
12285            , p_data  => x_msg_data
12286            );
12287 
12288    WHEN fnd_api.g_exc_unexpected_error THEN
12289         x_return_status := fnd_api.g_ret_sts_unexp_error ;
12290 
12291         --  Get message count and data
12292         fnd_msg_pub.count_and_get
12293           (  p_count  => x_msg_count
12294            , p_data   => x_msg_data
12295             );
12296 
12297     WHEN OTHERS THEN
12298         x_return_status := fnd_api.g_ret_sts_unexp_error ;
12299 
12300         IF fnd_msg_pub.check_msg_level(fnd_msg_pub.g_msg_lvl_unexp_error)
12301           THEN
12302            fnd_msg_pub.add_exc_msg
12303              (  g_pkg_name
12304               , l_api_name
12305               );
12306         END IF;
12307 
12308         --  Get message count and data
12309         fnd_msg_pub.count_and_get
12310           (  p_count  => x_msg_count
12311            , p_data   => x_msg_data
12312             );
12313 
12314 END update_quantities;
12315 
12316 
12317 -- Bug 2486318. The do check does not work. Trasactions get committed
12318 -- even if there is a node violation. Added p_check_mark_node_only to mark
12319 -- the nodes. A new procedure update quantities for form was added and
12320 -- called from inldqc.ppc
12321 
12322 --
12323 -- Procedure
12324 --   update_quantities_for_form
12325 -- Description
12326 --   Create a quantity tree
12327 --
12328 --  Version
12329 --   Current version        1.0
12330 --   Initial version        1.0
12331 --
12332 -- Input parameters:
12333 --   p_api_version_number   standard input parameter
12334 --   p_init_msg_lst         standard input parameter
12335 --   p_tree_id              tree_id
12336 --   p_revision             revision
12337 --   p_lot_number           lot_number
12338 --   p_subinventory_code    subinventory_code
12339 --   p_locator_id           locator_id
12340 --   p_primary_quantity     primary_quantity
12341 --   p_quantity_type
12342 --   p_call_for_form        to check if the call is from form
12343 --
12344 -- Output parameters:
12345 --   x_return_status       standard output parameter
12346 --   x_msg_count           standard output parameter
12347 --   x_msg_data            standard output parameter
12348 --   x_tree_id             used later to refer to the same tree
12349 --   x_qoh                 qoh   after the update
12350 --   x_rqoh                rqoh  after the update
12351 --   x_qr                  qr    after the update
12352 --   x_qs                  qs    after the update
12353 --   x_att                 att   after the update
12354 --   x_atr                 atr   after the update
12355 PROCEDURE update_quantities_for_form
12356   (  p_api_version_number    IN  NUMBER
12357    , p_init_msg_lst          IN  VARCHAR2
12358    , x_return_status         OUT NOCOPY VARCHAR2
12359    , x_msg_count             OUT NOCOPY NUMBER
12360    , x_msg_data              OUT NOCOPY VARCHAR2
12361    , p_tree_id               IN  INTEGER
12362    , p_revision              IN  VARCHAR2
12363    , p_lot_number            IN  VARCHAR2
12364    , p_subinventory_code     IN  VARCHAR2
12365    , p_locator_id            IN  NUMBER
12366    , p_primary_quantity      IN  NUMBER
12367    , p_quantity_type         IN  INTEGER
12368    , x_qoh                   OUT NOCOPY NUMBER
12369    , x_rqoh                  OUT NOCOPY NUMBER
12370    , x_qr                    OUT NOCOPY NUMBER
12371    , x_qs                    OUT NOCOPY NUMBER
12372    , x_att                   OUT NOCOPY NUMBER
12373    , x_atr                   OUT NOCOPY NUMBER
12374    , p_transfer_subinventory_code IN VARCHAR2
12375    , p_cost_group_id         IN  NUMBER
12376    , p_containerized         IN  NUMBER
12377    , p_call_for_form         IN  VARCHAR2
12378      ) IS
12379 
12380 l_secondary_quantity  NUMBER := NULL;    -- invConv change
12381 l_sqoh    NUMBER;     -- invConv change
12382 l_srqoh   NUMBER;     -- invConv change
12383 l_sqr     NUMBER;     -- invConv change
12384 l_sqs     NUMBER;     -- invConv change
12385 l_satt    NUMBER;     -- invConv change
12386 l_satr    NUMBER;     -- invConv change
12387 
12388 BEGIN
12389 
12390 -- invConv change begin:-- Calling the new signature API
12391 inv_quantity_tree_pvt.update_quantities_for_form
12392   (  p_api_version_number    => p_api_version_number
12393    , p_init_msg_lst          => p_init_msg_lst
12394    , x_return_status         => x_return_status
12395    , x_msg_count             => x_msg_count
12396    , x_msg_data              => x_msg_data
12397    , p_tree_id               => p_tree_id
12398    , p_revision              => p_revision
12399    , p_lot_number            => p_lot_number
12400    , p_subinventory_code     => p_subinventory_code
12401    , p_locator_id            => p_locator_id
12402    , p_primary_quantity      => p_primary_quantity
12403    , p_secondary_quantity    => l_secondary_quantity        -- invConv change
12404    , p_quantity_type         => p_quantity_type
12405    , x_qoh                   => x_qoh
12406    , x_rqoh                  => x_rqoh
12407    , x_qr                    => x_qr
12408    , x_qs                    => x_qs
12409    , x_att                   => x_att
12410    , x_atr                   => x_atr
12411    , x_sqoh                  => l_sqoh                       -- invConv change
12412    , x_srqoh                 => l_srqoh                      -- invConv change
12413    , x_sqr                   => l_sqr                        -- invConv change
12414    , x_sqs                   => l_sqs                        -- invConv change
12415    , x_satt                  => l_satt                       -- invConv change
12416    , x_satr                  => l_satr                       -- invConv change
12417    , p_transfer_subinventory_code => p_transfer_subinventory_code
12418    , p_cost_group_id         => p_cost_group_id
12419    , p_containerized         => p_containerized
12420    , p_call_for_form         => p_call_for_form);
12421 
12422 
12423 END update_quantities_for_form;
12424 
12425 -- invConv changes begin: overload
12426 PROCEDURE update_quantities_for_form
12427   (  p_api_version_number    IN  NUMBER
12428    , p_init_msg_lst          IN  VARCHAR2
12429    , x_return_status         OUT NOCOPY VARCHAR2
12430    , x_msg_count             OUT NOCOPY NUMBER
12431    , x_msg_data              OUT NOCOPY VARCHAR2
12432    , p_tree_id               IN  INTEGER
12433    , p_revision              IN  VARCHAR2
12434    , p_lot_number            IN  VARCHAR2
12435    , p_subinventory_code     IN  VARCHAR2
12436    , p_locator_id            IN  NUMBER
12437    , p_primary_quantity      IN  NUMBER
12438    , p_secondary_quantity    IN  NUMBER                -- invConv change
12439    , p_quantity_type         IN  INTEGER
12440    , x_qoh                   OUT NOCOPY NUMBER
12441    , x_rqoh                  OUT NOCOPY NUMBER
12442    , x_qr                    OUT NOCOPY NUMBER
12443    , x_qs                    OUT NOCOPY NUMBER
12444    , x_att                   OUT NOCOPY NUMBER
12445    , x_atr                   OUT NOCOPY NUMBER
12446    , x_sqoh                  OUT NOCOPY NUMBER                -- invConv change
12447    , x_srqoh                 OUT NOCOPY NUMBER                -- invConv change
12448    , x_sqr                   OUT NOCOPY NUMBER                -- invConv change
12449    , x_sqs                   OUT NOCOPY NUMBER                -- invConv change
12450    , x_satt                  OUT NOCOPY NUMBER                -- invConv change
12451    , x_satr                  OUT NOCOPY NUMBER                -- invConv change
12452    , p_transfer_subinventory_code IN VARCHAR2
12453    , p_cost_group_id         IN  NUMBER
12454    , p_containerized         IN  NUMBER
12455    , p_call_for_form         IN  VARCHAR2
12456      ) IS
12457       l_api_version_number   CONSTANT NUMBER       := 1.0;
12458       l_api_name             CONSTANT VARCHAR2(30) := 'UPDATE_QUANTITIES_FOR_FORM';
12459       l_return_status        VARCHAR2(1) := fnd_api.g_ret_sts_success;
12460       l_root_id        INTEGER;
12461       l_is_for_form         BOOLEAN;
12462 BEGIN
12463 
12464    IF g_debug = 1 THEN
12465       print_debug(l_api_name || ' Entered',9);
12466    END IF;
12467 
12468    --  Standard call to check for call compatibility
12469    IF NOT fnd_api.compatible_api_call(l_api_version_number
12470                                       , p_api_version_number
12471                                       , l_api_name
12472                                       , G_PKG_NAME
12473                                       ) THEN
12474       RAISE fnd_api.g_exc_unexpected_error;
12475    END IF;
12476 
12477    --  Initialize message list.
12478    IF fnd_api.to_boolean(p_init_msg_lst) THEN
12479       fnd_msg_pub.initialize;
12480    END IF;
12481 
12482    l_root_id := g_demand_info(p_tree_id).root_id;
12483 
12484    -- check if tree id is valid
12485    IF is_tree_valid(l_root_id) = FALSE THEN
12486       fnd_message.set_name('INV', 'INV-Qtyroot not found');
12487       fnd_message.set_token('ROUTINE', 'Update_Quantities');
12488       fnd_msg_pub.ADD;
12489       RAISE fnd_api.g_exc_unexpected_error;
12490    END IF;
12491 
12492    IF p_call_for_form = fnd_api.g_true THEN
12493       l_is_for_form := FALSE;
12494    ELSE
12495       l_is_for_form := TRUE;
12496    END IF;
12497 
12498    print_debug('Before calling add_quantities. qty1='||p_primary_quantity||', qty2='||p_secondary_quantity||', qtyType='||p_quantity_type);
12499    add_quantities(
12500         x_return_status     => l_return_status
12501       , p_tree_id           => l_root_id
12502       , p_revision          => p_revision
12503       , p_lot_number        => p_lot_number
12504       , p_subinventory_code => p_subinventory_code
12505       , p_is_reservable_sub => NULL
12506       , p_locator_id        => p_locator_id
12507       , p_primary_quantity  => p_primary_quantity
12508       , p_secondary_quantity=> p_secondary_quantity             -- invConv change
12509       , p_quantity_type     => p_quantity_type
12510       , p_set_check_mark    => l_is_for_form
12511       , p_cost_group_id     => p_cost_group_id
12512       , p_lpn_id     => NULL
12513       , p_check_mark_node_only     => fnd_api.g_true
12514       );
12515       print_debug('After calling add_quantities. return_status='||l_return_status);
12516 
12517    IF l_return_status = fnd_api.g_ret_sts_error THEN
12518       RAISE fnd_api.g_exc_error;
12519    End IF ;
12520 
12521    IF l_return_status = fnd_api.g_ret_sts_unexp_error THEN
12522       RAISE fnd_api.g_exc_unexpected_error;
12523    End IF;
12524    print_debug('Before calling Query_Tree');
12525    -- query the quantities after the update
12526    query_tree(
12527         p_api_version_number => 1.0
12528       , p_init_msg_lst       => fnd_api.g_false
12529       , x_return_status      => l_return_status
12530       , x_msg_count          => x_msg_count
12531       , x_msg_data           => x_msg_data
12532       , p_tree_id            => p_tree_id
12533       , p_revision           => p_revision
12534       , p_lot_number         => p_lot_number
12535       , p_subinventory_code  => p_subinventory_code
12536       , p_locator_id         => p_locator_id
12537       , x_qoh                => x_qoh
12538       , x_rqoh               => x_rqoh
12539       , x_qr                 => x_qr
12540       , x_qs                 => x_qs
12541       , x_att                => x_att
12542       , x_atr                => x_atr
12543       , x_sqoh               => x_sqoh               -- invConv change
12544       , x_srqoh              => x_srqoh              -- invConv change
12545       , x_sqr                => x_sqr                -- invConv change
12546       , x_sqs                => x_sqs                -- invConv change
12547       , x_satt               => x_satt               -- invConv change
12548       , x_satr               => x_satr               -- invConv change
12549       , p_transfer_subinventory_code => p_transfer_subinventory_code
12550       , p_cost_group_id      => p_cost_group_id
12551       );
12552    print_debug('After calling Query_Tree return_status='||l_return_status);
12553 
12554    IF l_return_status = fnd_api.g_ret_sts_error THEN
12555       RAISE fnd_api.g_exc_error;
12556    End IF ;
12557 
12558    IF l_return_status = fnd_api.g_ret_sts_unexp_error THEN
12559       RAISE fnd_api.g_exc_unexpected_error;
12560    End IF;
12561 
12562    x_return_status := l_return_status;
12563 
12564    IF g_debug = 1 THEN
12565       print_debug(l_api_name || ' Exited with status = '||l_return_status,9);
12566       print_debug(' ',9);
12567    END IF;
12568 
12569 EXCEPTION
12570 
12571     WHEN fnd_api.g_exc_error THEN
12572         x_return_status := fnd_api.g_ret_sts_error;
12573 
12574         --  Get message count and data
12575         fnd_msg_pub.count_and_get
12576           (  p_count => x_msg_count
12577            , p_data  => x_msg_data
12578            );
12579 
12580    WHEN fnd_api.g_exc_unexpected_error THEN
12581         x_return_status := fnd_api.g_ret_sts_unexp_error ;
12582 
12583         --  Get message count and data
12584         fnd_msg_pub.count_and_get
12585           (  p_count  => x_msg_count
12586            , p_data   => x_msg_data
12587             );
12588 
12589     WHEN OTHERS THEN
12590         x_return_status := fnd_api.g_ret_sts_unexp_error ;
12591 
12592         IF fnd_msg_pub.check_msg_level(fnd_msg_pub.g_msg_lvl_unexp_error)
12593           THEN
12594            fnd_msg_pub.add_exc_msg
12595              (  g_pkg_name
12596               , l_api_name
12597               );
12598         END IF;
12599 
12600         --  Get message count and data
12601         fnd_msg_pub.count_and_get
12602           (  p_count  => x_msg_count
12603            , p_data   => x_msg_data
12604             );
12605 
12606 END update_quantities_for_form;
12607 
12608 -- save a node and its children into the backup tables
12609 PROCEDURE save_node
12610   (p_node_index IN INTEGER)
12611   IS
12612      l_node_index INTEGER;
12613 BEGIN
12614    g_savenodes(p_node_index) := g_nodes(p_node_index);
12615    l_node_index := g_nodes(p_node_index).first_child_index;
12616    WHILE l_node_index <> 0 LOOP
12617       save_node(l_node_index);
12618       l_node_index := g_nodes(l_node_index).next_sibling_index;
12619    END LOOP;
12620 END save_node;
12621 
12622 -- save a rootinfo and its tree nodes into the backup tables
12623 PROCEDURE save_rootinfo
12624   (p_tree_id IN INTEGER )
12625   IS
12626      l_item_index INTEGER;
12627 BEGIN
12628    g_saveroots(p_tree_id) := g_rootinfos(p_tree_id);
12629    l_item_index := g_rootinfos(p_tree_id).item_node_index;
12630    -- save the item node and all children nodes below
12631    save_node(l_item_index);
12632 END save_rootinfo;
12633 
12634 -- Procedure
12635 --   backup_tree
12636 -- Description
12637 --   backup the current state of a tree
12638 -- Note
12639 --   This is only a one level backup. Calling it twice will
12640 --   overwrite the previous backup
12641 PROCEDURE backup_tree
12642   (
12643      x_return_status OUT NOCOPY VARCHAR2
12644    , p_tree_id       IN  INTEGER
12645    ) IS
12646       l_return_status   VARCHAR2(1) := fnd_api.g_ret_sts_success;
12647       l_root_id INTEGER;
12648       l_api_name        VARCHAR2(30) := 'BACKUP_TREE';
12649 BEGIN
12650    IF g_debug = 1 THEN
12651       print_debug(l_api_name || ' Entered',9);
12652    END IF;
12653    l_root_id := g_demand_info(p_tree_id).root_id;
12654    IF is_tree_valid(l_root_id) = FALSE THEN
12655       fnd_message.set_name('INV', 'INV-Qtyroot not found');
12656       fnd_message.set_token('ROUTINE', 'Backup_Tree');
12657       fnd_msg_pub.ADD;
12658       RAISE fnd_api.g_exc_error;
12659    END IF;
12660 
12661    save_rootinfo(l_root_id);
12662    -- bug 6683013, backing up rsv_tree
12663    g_save_rsv_tree_id := g_rsv_tree_id;
12664     g_save_rsv_counter := g_rsv_counter;
12665     g_saversvnode.DELETE;
12666 
12667     print_debug('backup: rsv_tree_id = ' || g_rsv_tree_id || ' rsv_counter = ' || g_rsv_counter, 11);
12668 
12669     if g_save_rsv_tree_id <> 0 then
12670        --backup rsv_nodes into g_saversvnode.
12671        FOR counter in 1..g_rsv_counter LOOP
12672           g_saversvnode(counter) := g_rsv_info(counter);
12673        END LOOP;
12674     end if;
12675 
12676    x_return_status := l_return_status;
12677 
12678    IF g_debug = 1 THEN
12679       print_debug(l_api_name || ' Exited with status = '||l_return_status,9);
12680       print_debug(' ',9);
12681    END IF;
12682 
12683 EXCEPTION
12684 
12685    WHEN fnd_api.g_exc_error THEN
12686        x_return_status := fnd_api.g_ret_sts_error;
12687 
12688    WHEN fnd_api.g_exc_unexpected_error THEN
12689       x_return_status := fnd_api.g_ret_sts_unexp_error ;
12690 
12691 
12692    WHEN OTHERS THEN
12693       x_return_status := fnd_api.g_ret_sts_unexp_error ;
12694 
12695 END backup_tree;
12696 
12697 -- restore a node and its children using the backup tables
12698 PROCEDURE restore_node
12699   (p_node_index IN INTEGER)
12700   IS
12701      l_node_index INTEGER;
12702 BEGIN
12703    g_nodes(p_node_index) := g_savenodes(p_node_index);
12704    l_node_index := g_savenodes(p_node_index).first_child_index;
12705    WHILE l_node_index <> 0 LOOP
12706       restore_node(l_node_index);
12707       l_node_index := g_savenodes(l_node_index).next_sibling_index;
12708    END LOOP;
12709 END restore_node;
12710 
12711 -- restore a rootinfo and its tree nodes using the backup tables
12712 PROCEDURE restore_rootinfo
12713   (p_tree_id IN INTEGER )
12714   IS
12715      l_item_index INTEGER;
12716 BEGIN
12717    g_rootinfos(p_tree_id) := g_saveroots(p_tree_id);
12718    l_item_index := g_saveroots(p_tree_id).item_node_index;
12719    -- restore the item node and all children nodes below
12720    restore_node(l_item_index);
12721 END restore_rootinfo;
12722 
12723 -- Procedure
12724 --   restore_tree
12725 -- Description
12726 --   restore the current state of a tree to the state
12727 --   at the last time when savepoint_tree is called
12728 -- Note
12729 --   This is only a one level restore. Calling it more than once
12730 --   has the same effect as calling it once.
12731 PROCEDURE restore_tree
12732   (
12733      x_return_status OUT NOCOPY VARCHAR2
12734    , p_tree_id       IN  INTEGER
12735    ) IS
12736       l_return_status   VARCHAR2(1) := fnd_api.g_ret_sts_success;
12737       l_root_id      INTEGER;
12738       l_api_name        VARCHAR2(30) := 'RESTORE_TREE';
12739 BEGIN
12740    IF g_debug = 1 THEN
12741       print_debug(l_api_name || ' Entered',9);
12742    END IF;
12743 
12744    l_root_id := g_demand_info(p_tree_id).root_id;
12745    IF is_saved_tree_valid(l_root_id) = FALSE THEN
12746       fnd_message.set_name('INV', 'INV-Qtyroot not found');
12747       fnd_message.set_token('ROUTINE', 'Restore_Tree');
12748       fnd_msg_pub.ADD;
12749       RAISE fnd_api.g_exc_error;
12750    END IF;
12751 
12752    restore_rootinfo(l_root_id);
12753    -- bug 6683013, restoring back rsv_tree
12754     g_rsv_tree_id := g_save_rsv_tree_id;
12755     g_rsv_counter := g_save_rsv_counter;
12756     g_rsv_info.DELETE;
12757     print_debug('restore: rsv_tree_id = ' || g_rsv_tree_id || ' rsv_counter = ' || g_rsv_counter, 11);
12758 
12759     if g_save_rsv_tree_id <> 0 then
12760        --restore rsv_nodes from g_saversvnode.
12761        FOR counter in 1..g_rsv_counter LOOP
12762           g_rsv_info(counter) := g_saversvnode(counter);
12763        END LOOP;
12764     end if;
12765 
12766    x_return_status := l_return_status;
12767 
12768    IF g_debug = 1 THEN
12769       print_debug(l_api_name || ' Exited with status = '||l_return_status,9);
12770       print_debug(' ',9);
12771    END IF;
12772 
12773 EXCEPTION
12774 
12775    WHEN fnd_api.g_exc_error THEN
12776        x_return_status := fnd_api.g_ret_sts_error;
12777 
12778    WHEN fnd_api.g_exc_unexpected_error THEN
12779       x_return_status := fnd_api.g_ret_sts_unexp_error ;
12780 
12781 
12782    WHEN OTHERS THEN
12783       x_return_status := fnd_api.g_ret_sts_unexp_error ;
12784 
12785 END restore_tree;
12786 
12787 
12788 -- **NEW BACKUP/RESTORE PROCEDURES**
12789 -- Bug 2788807
12790 --    We now need to support multi-level backup and restore capability
12791 -- for the quantity tree.  We'll overload the existing procedures.
12792 
12793 -- Backup_Node
12794 -- recursive function to copy current node, its children, and its siblings
12795 -- to the backup node table
12796 PROCEDURE backup_node
12797   (p_node_index IN INTEGER)
12798   IS
12799      l_node_index INTEGER;
12800 BEGIN
12801    g_backup_node_counter := g_backup_node_counter + 1;
12802    g_backup_nodes(g_backup_node_counter) := g_nodes(p_node_index);
12803    g_backup_nodes(g_backup_node_counter).node_index := p_node_index;
12804 
12805    l_node_index := g_nodes(p_node_index).first_child_index;
12806    WHILE l_node_index <> 0 LOOP
12807       backup_node(l_node_index);
12808       l_node_index := g_nodes(l_node_index).next_sibling_index;
12809    END LOOP;
12810 END backup_node;
12811 
12812 -- Procedure
12813 --   backup_tree
12814 -- Description
12815 --   backup the current state of a tree.  This procedure returns a backup_id
12816 --   which needs to be passed to restore_tree in order to restore the correct
12817 --   version of the quantity tree.  Unlike the older version of backup_tree,
12818 --   this can be called multiple times without overwriting previous backups.
12819 --   The backups dissappear when clear_quantity_cache is called.
12820 --
12821 PROCEDURE backup_tree
12822   (
12823      x_return_status OUT NOCOPY VARCHAR2
12824    , p_tree_id       IN  INTEGER
12825    , x_backup_id     OUT NOCOPY NUMBER
12826    ) IS
12827       l_return_status   VARCHAR2(1) := fnd_api.g_ret_sts_success;
12828       l_root_id INTEGER;
12829       l_backup_id NUMBER;
12830       l_api_name        VARCHAR2(30) := 'BACKUP_TREE';
12831 BEGIN
12832    IF g_debug = 1 THEN
12833       print_debug(l_api_name || ' Entered',9);
12834    END IF;
12835 
12836    l_root_id := g_demand_info(p_tree_id).root_id;
12837    IF is_tree_valid(l_root_id) = FALSE THEN
12838       fnd_message.set_name('INV', 'INV-Qtyroot not found');
12839       fnd_message.set_token('ROUTINE', 'Backup_Tree');
12840       fnd_msg_pub.ADD;
12841       RAISE fnd_api.g_exc_error;
12842    END IF;
12843 
12844    g_backup_tree_counter := g_backup_tree_counter + 1;
12845    l_backup_id := g_backup_tree_counter;
12846 
12847    --populate parent table - g_backup_trees
12848    g_backup_trees(l_backup_id).root_id := l_root_id;
12849    g_backup_trees(l_backup_id).first_node := g_backup_node_counter + 1;
12850 
12851    --populate child table - g_backup_nodes - by calling recursive function
12852    backup_node(g_rootinfos(l_root_id).item_node_index);
12853 
12854    --store id of last record of current tree
12855    g_backup_trees(l_backup_id).last_node := g_backup_node_counter;
12856 
12857    x_return_status := l_return_status;
12858    x_backup_id := l_backup_id;
12859 
12860    IF g_debug = 1 THEN
12861       print_debug(l_api_name || ' Exited with status = '||l_return_status,9);
12862       print_debug(' ',9);
12863    END IF;
12864 
12865 EXCEPTION
12866 
12867    WHEN fnd_api.g_exc_error THEN
12868        x_return_status := fnd_api.g_ret_sts_error;
12869 
12870    WHEN fnd_api.g_exc_unexpected_error THEN
12871       x_return_status := fnd_api.g_ret_sts_unexp_error ;
12872 
12873    WHEN OTHERS THEN
12874       x_return_status := fnd_api.g_ret_sts_unexp_error ;
12875 
12876 END backup_tree;
12877 
12878 -- Procedure
12879 --   restore_tree
12880 -- Description
12881 --   Restores the quantity tree to the point indicated by the backup_id.
12882 --   Tree_id is not strictly needed here, but is kept for overloading and
12883 --   error checking purposes.  Restore_tree can be called multiple times for
12884 --   the same backup_id - a saved quantity tree is not deleted until
12885 --   clear_quantity_cache is called.
12886 PROCEDURE restore_tree
12887   (
12888      x_return_status OUT NOCOPY VARCHAR2
12889    , p_tree_id       IN  INTEGER
12890    , p_backup_id     IN  NUMBER
12891    ) IS
12892       l_return_status   VARCHAR2(1) := fnd_api.g_ret_sts_success;
12893       l_root_id         INTEGER;
12894       l_loop_index   NUMBER;
12895       l_node_index   NUMBER;
12896       l_api_name    VARCHAR2(30) := 'RESTORE_TREE';
12897 BEGIN
12898    IF g_debug = 1 THEN
12899       print_debug(l_api_name || ' Entered',9);
12900    END IF;
12901 
12902    IF NOT g_demand_info.exists(p_tree_id) THEN
12903    raise fnd_api.g_exc_unexpected_error;
12904    END IF;
12905    IF NOT g_backup_trees.exists(p_backup_id) THEN
12906    raise fnd_api.g_exc_unexpected_error;
12907    END IF;
12908 
12909    l_root_id := g_demand_info(p_tree_id).root_id;
12910 
12911    IF l_root_id <> g_backup_trees(p_backup_id).root_id THEN
12912         raise fnd_api.g_exc_unexpected_error;
12913    END IF;
12914 
12915    l_loop_index := g_backup_trees(p_backup_id).first_node;
12916 
12917    LOOP
12918      EXIT when l_loop_index > g_backup_trees(p_backup_id).last_node;
12919      l_node_index := g_backup_nodes(l_loop_index).node_index;
12920      g_nodes(l_node_index) :=g_backup_nodes(l_loop_index);
12921      l_loop_index := l_loop_index + 1;
12922    END LOOP;
12923 
12924    x_return_status := l_return_status;
12925 
12926    IF g_debug = 1 THEN
12927       print_debug(l_api_name || ' Exited with status = '||l_return_status,9);
12928       print_debug(' ',9);
12929    END IF;
12930 
12931 EXCEPTION
12932 
12933    WHEN fnd_api.g_exc_error THEN
12934        x_return_status := fnd_api.g_ret_sts_error;
12935 
12936    WHEN fnd_api.g_exc_unexpected_error THEN
12937       x_return_status := fnd_api.g_ret_sts_unexp_error ;
12938 
12939 
12940    WHEN OTHERS THEN
12941       x_return_status := fnd_api.g_ret_sts_unexp_error ;
12942 
12943 END restore_tree;
12944 
12945 
12946 --
12947 -- Debugging Procedures
12948 --
12949 -- simple test
12950 PROCEDURE test
12951   IS
12952      l_return_status   VARCHAR2(1) := fnd_api.g_ret_sts_success;
12953      l_msg_count       NUMBER;
12954      l_msg_data        VARCHAR2(1000);
12955      l_tree_id         INTEGER;
12956      l_msg             VARCHAR2(1000);
12957 BEGIN
12958    NULL;
12959    create_tree
12960     (
12961         p_api_version_number      => 1.0
12962       , p_init_msg_lst            => fnd_api.g_true
12963       , x_return_status           => l_return_status
12964       , x_msg_count               => l_msg_count
12965       , x_msg_data                => l_msg_data
12966       , p_organization_id         => 207
12967       , p_inventory_item_id       => 4702
12968       , p_tree_mode               => g_transaction_mode
12969       , p_is_revision_control     => TRUE
12970       , p_is_lot_control          => FALSE
12971       , p_is_serial_control       => FALSE
12972       , p_asset_sub_only          => FALSE
12973       , p_include_suggestion      => FALSE
12974       , p_demand_source_type_id   => 13
12975       , p_demand_source_header_id => 1000
12976       , p_demand_source_line_id   => 1000
12977       , p_demand_source_name      => NULL
12978       , p_demand_source_delivery  => 1000
12979       , p_lot_expiration_date     => NULL
12980       , x_tree_id                 => l_tree_id
12981       );
12982 
12983 --   dbm_output.put_line(l_return_status);
12984 --   dbm_output.put_line('message count: '||To_char(l_msg_count));
12985    IF l_msg_count = 0
12986      OR l_msg_count IS NULL THEN
12987       NULL;
12988     ELSIF l_msg_count = 1 THEN
12989 --      dbm_output.put_line('Error: '||l_msg_data);
12990       NULL;
12991     ELSE
12992       FOR l_counter IN 1..l_msg_count LOOP
12993     --         dbm_output.put_line(fnd_msg_pub.get);
12994     NULL;
12995       END LOOP;
12996    END IF;
12997    IF l_return_status = 'S' THEN
12998       print_tree(l_tree_id);
12999       dump_tree_to_db_pipe(l_return_status, 'treedemo1', l_tree_id);
13000    END IF;
13001 END test;
13002 
13003 FUNCTION send
13004   (  p_pipename      IN  VARCHAR2
13005    , p_message       IN  VARCHAR2
13006    ) RETURN NUMBER IS
13007       l_rval NUMBER := NULL;
13008 BEGIN
13009    dbms_pipe.pack_message(p_message);
13010    l_rval := dbms_pipe.send_message(p_pipename, 120, 1000000);
13011    RETURN l_rval;
13012 END send;
13013 
13014 FUNCTION receive
13015   (  p_pipename      IN  VARCHAR2
13016    , x_message       OUT NOCOPY VARCHAR2
13017    ) RETURN NUMBER IS
13018       l_rval NUMBER := NULL;
13019 BEGIN
13020    l_rval := dbms_pipe.receive_message(p_pipename, 30);
13021    IF l_rval = 0 THEN
13022       dbms_pipe.unpack_message(x_message);
13023     ELSE
13024       x_message := NULL;
13025    END IF;
13026    RETURN l_rval;
13027 END receive;
13028 
13029 PROCEDURE dump_tree_node
13030   (
13031      x_return_status  OUT NOCOPY VARCHAR2
13032    , p_pipename       IN  VARCHAR2
13033    , p_node_index     IN INTEGER
13034    ) IS
13035       l_return_status VARCHAR2(1) := fnd_api.g_ret_sts_success;
13036       l_node_level INTEGER;
13037       l_node_index INTEGER;
13038       l_buf        VARCHAR2(4096);
13039       l_inventory_item_id NUMBER;
13040       l_rval NUMBER;
13041 BEGIN
13042    l_buf := '<NODE NAME="';
13043    IF p_node_index <> 0 THEN
13044       l_node_level := g_nodes(p_node_index).node_level;
13045       IF l_node_level = g_item_level THEN
13046          l_inventory_item_id :=
13047            g_rootinfos(g_nodes(p_node_index).parent_index).inventory_item_id;
13048          l_buf := l_buf || 'ITEM '||To_char(l_inventory_item_id);
13049        ELSIF l_node_level = g_revision_level THEN
13050          l_buf := l_buf || 'REVISION '
13051            || g_nodes(p_node_index).revision;
13052        ELSIF l_node_level = g_lot_level THEN
13053          l_buf := l_buf || 'LOT '
13054            || g_nodes(p_node_index).lot_number;
13055        ELSIF l_node_level = g_sub_level THEN
13056          l_buf := l_buf || 'SUBINVENTORY '
13057            || g_nodes(p_node_index).subinventory_code;
13058        ELSIF l_node_level = g_locator_level THEN
13059          l_buf := l_buf || 'LOCATORID '
13060            || g_nodes(p_node_index).locator_id;
13061        ELSIF l_node_level = g_cost_group_level THEN
13062          l_buf := l_buf || 'COSTGROUPID '
13063            || g_nodes(p_node_index).cost_group_id;
13064        ELSE
13065          l_buf := l_buf || 'UNKNOWN ';
13066       END IF;
13067 
13068       l_buf := l_buf || '"';
13069 
13070       l_buf := l_buf || ' NODE_LEVEL="';
13071       IF l_node_level = g_item_level THEN
13072          l_inventory_item_id :=
13073            g_rootinfos(g_nodes(p_node_index).parent_index).inventory_item_id;
13074          l_buf := l_buf || 'ITEM"';
13075        ELSIF l_node_level = g_revision_level THEN
13076          l_buf := l_buf || 'REVISION"';
13077        ELSIF l_node_level = g_lot_level THEN
13078          l_buf := l_buf || 'LOT"';
13079        ELSIF l_node_level = g_sub_level THEN
13080          l_buf := l_buf || 'SUBINVENTORY"';
13081        ELSIF l_node_level = g_locator_level THEN
13082          l_buf := l_buf || 'LOCATOR"';
13083        ELSIF l_node_level = g_cost_group_level THEN
13084          l_buf := l_buf || 'COST_GROUP"';
13085        ELSE
13086          l_buf := l_buf || 'UNKNOWN"';
13087       END IF;
13088 
13089       l_buf := l_buf || ' NODE_ID="' || To_char(p_node_index) ||'"';
13090 
13091       l_buf := l_buf || ' REVISION="'||g_nodes(p_node_index).revision || '"';
13092       l_buf := l_buf || ' LOT_NUMBER="'||substr(g_nodes(p_node_index).lot_number,1,10)
13093         || '"';
13094       l_buf := l_buf || ' SUBINVENTORY_CODE="'
13095         ||g_nodes(p_node_index).subinventory_code || '"';
13096       IF g_nodes(p_node_index).is_reservable_sub THEN
13097          l_buf := l_buf || ' IS_RESERVABLE_SUB="TRUE"';
13098        ELSE
13099          l_buf := l_buf || ' IS_RESERVABLE_SUB="FALSE"';
13100       END IF;
13101 
13102       l_buf := l_buf || ' LOCATOR_ID="'
13103         || To_char(g_nodes(p_node_index).locator_id) || '"';
13104       l_buf := l_buf || ' COST_GROUP_ID="'
13105         || To_char(g_nodes(p_node_index).cost_group_id) || '"';
13106 
13107       l_buf := l_buf || ' QOH="'||To_char(g_nodes(p_node_index).qoh) || '"';
13108       l_buf := l_buf || ' RQOH="'||To_char(g_nodes(p_node_index).rqoh) || '"';
13109       l_buf := l_buf || ' QR="'||To_char(g_nodes(p_node_index).qr) || '"';
13110       l_buf := l_buf || ' QS="'||To_char(g_nodes(p_node_index).qs) || '"';
13111       l_buf := l_buf || ' ATT="'||To_char(g_nodes(p_node_index).att) || '"';
13112       l_buf := l_buf || ' ATR="'||To_char(g_nodes(p_node_index).atr) || '"';
13113 
13114       IF g_nodes(p_node_index).check_mark THEN
13115          l_buf := l_buf || ' check_mark="TRUE"';
13116        ELSE
13117          l_buf := l_buf || ' check_mark="FALSE"';
13118       END IF;
13119 
13120       l_buf := l_buf || ' NEXT_SIBLING_INDEX="'
13121         || To_char(g_nodes(p_node_index).next_sibling_index) || '"';
13122 
13123       l_buf := l_buf || ' FIRST_CHILD_INDEX="'
13124         || To_char(g_nodes(p_node_index).first_child_index) || '"';
13125 
13126       l_buf := l_buf || ' LAST_CHILD_INDEX="'
13127         || To_char(g_nodes(p_node_index).last_child_index)  || '"';
13128       l_buf := l_buf || ' PARENT_INDEX="'
13129         || To_char(g_nodes(p_node_index).parent_index) || '"';
13130 
13131       l_buf := l_buf || '>';
13132 
13133       l_rval := send
13134         (
13135            p_pipename      => p_pipename
13136          , p_message       => l_buf
13137          );
13138 
13139       IF l_rval <> 0 THEN
13140          fnd_message.set_name('INV', 'INV-FAILED_TO_SEND_MESSAGE');
13141          fnd_msg_pub.add;
13142 --       dbm_output.put_line('Error: failed to send message to the pipe.'
13143 --                            || 'Error code is '||To_char(l_rval));
13144          RAISE fnd_api.g_exc_error;
13145       END IF ;
13146 
13147       l_node_index := g_nodes(p_node_index).first_child_index;
13148 
13149       WHILE l_node_index <> 0 LOOP
13150          dump_tree_node(
13151                           x_return_status  => l_return_status
13152                         , p_pipename       => p_pipename
13153                         , p_node_index     => l_node_index
13154                         );
13155 
13156          IF l_return_status = fnd_api.g_ret_sts_error THEN
13157             RAISE fnd_api.g_exc_error;
13158          END IF ;
13159 
13160          IF l_return_status = fnd_api.g_ret_sts_unexp_error THEN
13161             RAISE fnd_api.g_exc_unexpected_error;
13162          END IF;
13163 
13164          l_node_index := g_nodes(l_node_index).next_sibling_index;
13165       END LOOP;
13166 
13167       l_buf := '</NODE>';
13168       l_rval := send
13169         (
13170            p_pipename      => p_pipename
13171          , p_message       => l_buf
13172          );
13173 
13174       IF l_rval <> 0 THEN
13175          fnd_message.set_name('INV', 'INV-FAILED_TO_SEND_MESSAGE');
13176          fnd_msg_pub.add;
13177 --       dbm_output.put_line('Error: failed to send message to the pipe.'
13178 --                            || 'Error code is '||To_char(l_rval));
13179          RAISE fnd_api.g_exc_error;
13180       END IF ;
13181 
13182    END IF;
13183 
13184    x_return_status := l_return_status;
13185 
13186 EXCEPTION
13187    WHEN fnd_api.g_exc_error THEN
13188        x_return_status := fnd_api.g_ret_sts_error;
13189 
13190    WHEN fnd_api.g_exc_unexpected_error THEN
13191       x_return_status := fnd_api.g_ret_sts_unexp_error ;
13192 
13193 
13194    WHEN OTHERS THEN
13195       x_return_status := fnd_api.g_ret_sts_unexp_error ;
13196 
13197 END dump_tree_node;
13198 
13199 PROCEDURE dump_rootinfo
13200   (
13201      x_return_status  OUT NOCOPY VARCHAR2
13202    , p_pipename       IN  VARCHAR2
13203    , p_tree_id        IN  INTEGER
13204    ) IS
13205       l_return_status VARCHAR2(1) := fnd_api.g_ret_sts_success;
13206       l_buf           VARCHAR2(4096);
13207       l_tmp           VARCHAR2(1000);
13208       l_rval          NUMBER := NULL;
13209 BEGIN
13210 --   dbm_output.put_line('In dump rootinfo');
13211    l_tmp := 'TreeID_' || To_char(p_tree_id)
13212      || '_Org_' || To_char(g_rootinfos(p_tree_id).organization_id)
13213      || '_Item_'|| To_char(g_rootinfos(p_tree_id).inventory_item_id);
13214    l_buf := '<ROOTINFO NAME="' || l_tmp || '"';
13215 
13216    l_buf := l_buf || ' TIMESTAMP="'||fnd_date.date_to_canonical(Sysdate)
13217      || '"';
13218    l_buf := l_buf || ' TREE_ID="'||To_char(p_tree_id) ||'"';
13219    l_buf := l_buf || ' ORGANIZATION_ID="'
13220      || To_char(g_rootinfos(p_tree_id).organization_id)|| '"';
13221    l_buf := l_buf || ' INVENTORY_ITEM_ID="'
13222      || To_char(g_rootinfos(p_tree_id).inventory_item_id)|| '"';
13223 
13224    IF g_rootinfos(p_tree_id).is_revision_control THEN
13225       l_buf := l_buf || ' IS_REVISION_CONTROL="TRUE"';
13226     ELSE
13227       l_buf := l_buf || ' IS_REVISION_CONTROL="FALSE"';
13228    END IF;
13229 
13230    IF g_rootinfos(p_tree_id).is_lot_control THEN
13231       l_buf := l_buf || ' IS_LOT_CONTROL="TRUE"';
13232     ELSE
13233       l_buf := l_buf || ' IS_LOT_CONTROL="FALSE"';
13234    END IF;
13235 
13236    IF g_rootinfos(p_tree_id).is_serial_control THEN
13237       l_buf := l_buf || ' IS_SERIAL_CONTROL="TRUE"';
13238     ELSE
13239       l_buf := l_buf || ' IS_SERIAL_CONTROL="FALSE"';
13240    END IF;
13241 
13242    IF g_rootinfos(p_tree_id).neg_inv_allowed THEN
13243       l_buf := l_buf || ' NEG_INV_ALLOWED="TRUE"';
13244     ELSE
13245       l_buf := l_buf || ' NEG_INV_ALLOWED="FALSE"';
13246    END IF;
13247 
13248    IF g_rootinfos(p_tree_id).tree_mode = g_reservation_mode THEN
13249       l_buf := l_buf || ' TREE_MODE="RESERVATION"';
13250     ELSIF g_rootinfos(p_tree_id).tree_mode = g_transaction_mode THEN
13251       l_buf := l_buf || ' TREE_MODE="TRANSACTION"';
13252     ELSE
13253       l_buf := l_buf || ' TREE_MODE="INVALID_'
13254         || To_char(g_rootinfos(p_tree_id).tree_mode)|| '"';
13255    END IF;
13256 
13257    l_buf := l_buf || ' DEMAND_SOURCE_TYPE_ID="'
13258       || To_char(g_rootinfos(p_tree_id).demand_source_type_id)|| '"';
13259    l_buf := l_buf || ' DEMAND_SOURCE_HEADER_ID="'
13260       || To_char(g_rootinfos(p_tree_id).demand_source_header_id)|| '"';
13261    l_buf := l_buf || ' DEMAND_SOURCE_LINE_ID="'
13262       || To_char(g_rootinfos(p_tree_id).demand_source_line_id)|| '"';
13263    l_buf := l_buf || ' DEMAND_SOURCE_NAME="'
13264      || g_rootinfos(p_tree_id).demand_source_name|| '"';
13265    l_buf := l_buf || ' DEMAND_SOURCE_DELIVERY="'
13266      || To_char(g_rootinfos(p_tree_id).demand_source_delivery) || '"';
13267 
13268    IF g_rootinfos(p_tree_id).need_refresh THEN
13269       l_buf := l_buf || ' NEED_REFRESH="TRUE"';
13270     ELSE
13271       l_buf := l_buf || ' NEED_REFRESH="FALSE"';
13272    END IF;
13273 
13274    l_buf := l_buf || ' LOT_EXPIRATION_DATE="'
13275      ||fnd_date.date_to_canonical
13276      (g_rootinfos(p_tree_id).lot_expiration_date)|| '"';
13277    l_buf := l_buf || ' ITEM_NODE_INDEX="'
13278      || To_char(g_rootinfos(p_tree_id).item_node_index)|| '"';
13279 
13280    l_buf := l_buf || '>';
13281 
13282    l_rval := send
13283      (
13284         p_pipename      => p_pipename
13285       , p_message       => l_buf
13286       );
13287 
13288    IF l_rval <> 0 THEN
13289       fnd_message.set_name('INV', 'INV-FAILED_TO_SEND_MESSAGE');
13290       fnd_msg_pub.add;
13291 --      dbm_output.put_line('Error: failed to send message to the pipe.'
13292 --                         || 'Error code is '||To_char(l_rval));
13293       RAISE fnd_api.g_exc_error;
13294    END IF ;
13295 
13296    dump_tree_node(
13297                     x_return_status  => l_return_status
13298                   , p_pipename       => p_pipename
13299                   , p_node_index     => g_rootinfos(p_tree_id).item_node_index
13300                   );
13301 
13302    IF l_return_status = fnd_api.g_ret_sts_error THEN
13303       RAISE fnd_api.g_exc_error;
13304    END IF ;
13305 
13306    IF l_return_status = fnd_api.g_ret_sts_unexp_error THEN
13307       RAISE fnd_api.g_exc_unexpected_error;
13308    END IF;
13309 
13310    l_buf := '</ROOTINFO>';
13311    l_rval := send
13312      (
13313         p_pipename      => p_pipename
13314       , p_message       => l_buf
13315       );
13316 
13317    IF l_rval <> 0 THEN
13318       fnd_message.set_name('INV', 'INV-FAILED_TO_SEND_MESSAGE');
13319       fnd_msg_pub.add;
13320 --      dbm_output.put_line('Error: failed to send message to the pipe.'
13321 --                         || 'Error code is '||To_char(l_rval));
13322       RAISE fnd_api.g_exc_error;
13323    END IF ;
13324 
13325 
13326    x_return_status := l_return_status;
13327 
13328 EXCEPTION
13329    WHEN fnd_api.g_exc_error THEN
13330        x_return_status := fnd_api.g_ret_sts_error;
13331 
13332    WHEN fnd_api.g_exc_unexpected_error THEN
13333       x_return_status := fnd_api.g_ret_sts_unexp_error ;
13334 
13335 
13336    WHEN OTHERS THEN
13337       x_return_status := fnd_api.g_ret_sts_unexp_error ;
13338 
13339 END dump_rootinfo;
13340 
13341 PROCEDURE dump_tree_to_db_pipe
13342   (
13343      x_return_status  OUT NOCOPY VARCHAR2
13344    , p_pipename       IN  VARCHAR2
13345    , p_tree_id        IN  INTEGER
13346    ) IS
13347       l_return_status  VARCHAR2(1) := fnd_api.g_ret_sts_success;
13348       l_rval           NUMBER;
13349 BEGIN
13350    --   dbm_output.put_line('Dumping Tree: '||To_char(p_tree_id));
13351    -- check if tree id is valid
13352    IF is_tree_valid(p_tree_id) = FALSE THEN
13353       fnd_message.set_name('INV', 'INV-Qtyroot not found');
13354       fnd_message.set_token('ROUTINE', 'Dump_Tree_To_DB_Pipe');
13355       fnd_msg_pub.ADD;
13356       RAISE fnd_api.g_exc_error;
13357    END IF;
13358 
13359    dump_rootinfo
13360      (
13361         x_return_status  => l_return_status
13362       , p_pipename       => p_pipename
13363       , p_tree_id        => p_tree_id
13364       );
13365 
13366    IF l_return_status = fnd_api.g_ret_sts_error THEN
13367       RAISE fnd_api.g_exc_error;
13368    END IF ;
13369 
13370    IF l_return_status = fnd_api.g_ret_sts_unexp_error THEN
13371       RAISE fnd_api.g_exc_unexpected_error;
13372    END IF;
13373 
13374    l_rval := send
13375      (
13376         p_pipename      => p_pipename
13377       , p_message       => '.'  -- no more to come, used as a separator
13378       );
13379 
13380    IF l_rval <> 0 THEN
13381       fnd_message.set_name('INV', 'INV-FAILED_TO_SEND_MESSAGE');
13382       fnd_msg_pub.add;
13383 --      dbm_output.put_line('Error: failed to send message to the pipe.'
13384 --                         || 'Error code is '||To_char(l_rval));
13385       RAISE fnd_api.g_exc_error;
13386    END IF ;
13387 
13388    x_return_status := l_return_status;
13389 
13390 EXCEPTION
13391 
13392    WHEN fnd_api.g_exc_error THEN
13393        x_return_status := fnd_api.g_ret_sts_error;
13394 
13395    WHEN fnd_api.g_exc_unexpected_error THEN
13396       x_return_status := fnd_api.g_ret_sts_unexp_error ;
13397 
13398 
13399    WHEN OTHERS THEN
13400       x_return_status := fnd_api.g_ret_sts_unexp_error ;
13401 
13402 END dump_tree_to_db_pipe;
13403 
13404 -- Procedure
13405 --   dump_tree_to_db_pipe
13406 -- Description
13407 --   Generate a XML document for all valid trees and send the document
13408 --   to a dbms_pipe. We have a Java Application that reads from the pipe
13409 --   to monitor the changes in the quantity tree.
13410 PROCEDURE dump_tree_to_db_pipe
13411   (
13412      x_return_status OUT NOCOPY VARCHAR2
13413    , p_pipename      IN  VARCHAR2
13414    ) IS
13415       l_return_status  VARCHAR2(1) := fnd_api.g_ret_sts_success;
13416       l_rval           NUMBER;
13417       l_tree_id        INTEGER;
13418       l_buf            VARCHAR2(4096);
13419       l_root_id      NUMBER;
13420 BEGIN
13421 
13422 --   dbm_output.put_line('Dumping All Trees');
13423 
13424    l_buf := '<TREES NAME="QUANTITY_TREES" TIMESTAMP="'
13425      || fnd_date.date_to_canonical(Sysdate) || '">';
13426 
13427    l_rval := send
13428      (
13429         p_pipename      => p_pipename
13430       , p_message       => l_buf
13431       );
13432 
13433    IF l_rval <> 0 THEN
13434       fnd_message.set_name('INV', 'INV-FAILED_TO_SEND_MESSAGE');
13435       fnd_msg_pub.add;
13436 --      dbm_output.put_line('Error: failed to send message to the pipe.'
13437 --                         || 'Error code is '||To_char(l_rval));
13438       RAISE fnd_api.g_exc_error;
13439    END IF ;
13440 
13441    FOR l_tree_id IN 1..g_all_roots_counter LOOP
13442       l_root_id := g_all_roots(l_tree_id).root_id;
13443       -- check if tree id is valid
13444       IF is_tree_valid(l_root_id) THEN
13445          dump_rootinfo
13446            (
13447               x_return_status  => l_return_status
13448             , p_pipename       => p_pipename
13449             , p_tree_id        => l_root_id
13450             );
13451       END IF;
13452    END LOOP;
13453 
13454    l_buf := '</TREES>';
13455    l_rval := send
13456      (
13457         p_pipename      => p_pipename
13458       , p_message       => l_buf
13459       );
13460 
13461    IF l_rval <> 0 THEN
13462       fnd_message.set_name('INV', 'INV-FAILED_TO_SEND_MESSAGE');
13463       fnd_msg_pub.add;
13464 --      dbm_output.put_line('Error: failed to send message to the pipe.'
13465 --                         || 'Error code is '||To_char(l_rval));
13466       RAISE fnd_api.g_exc_error;
13467    END IF ;
13468 
13469    l_rval := send
13470      (
13471         p_pipename      => p_pipename
13472       , p_message       => '.'  -- no more to come, used as a separator
13473       );
13474 
13475    IF l_rval <> 0 THEN
13476       fnd_message.set_name('INV', 'INV-FAILED_TO_SEND_MESSAGE');
13477       fnd_msg_pub.add;
13478 --      dbm_output.put_line('Error: failed to send message to the pipe.'
13479 --                         || 'Error code is '||To_char(l_rval));
13480       RAISE fnd_api.g_exc_error;
13481    END IF ;
13482 
13483    x_return_status := l_return_status;
13484 
13485 EXCEPTION
13486 
13487    WHEN fnd_api.g_exc_error THEN
13488        x_return_status := fnd_api.g_ret_sts_error;
13489 
13490    WHEN fnd_api.g_exc_unexpected_error THEN
13491       x_return_status := fnd_api.g_ret_sts_unexp_error ;
13492 
13493 
13494    WHEN OTHERS THEN
13495       x_return_status := fnd_api.g_ret_sts_unexp_error ;
13496 
13497 END dump_tree_to_db_pipe;
13498 
13499 
13500 function do_check_release_locks return boolean IS
13501 cursor C1 is select organization_id,inventory_item_id
13502                from mtl_do_check_temp;
13503 l_return_status varchar2(1);
13504 l_msg_count number;
13505 l_msg_data varchar2(2000);
13506 l_api_number number := 1.0;
13507 
13508 begin
13509   for c1_rec in C1 loop
13510       INV_QUANTITY_TREE_PVT.release_lock(
13511          l_api_number,
13512          fnd_api.g_false,
13513          l_return_status,
13514          l_msg_count,
13515          l_msg_data,
13516          c1_rec.organization_id,
13517          c1_rec.inventory_item_id);
13518   if l_return_status = fnd_api.g_ret_sts_error then
13519     Return FALSE;
13520   End if;
13521   end loop;
13522 return TRUE;
13523 end;
13524 
13525 -------------------------------------------------------------------------------
13526 -- Coding standard used in this program
13527 -- 1. PLSQL business object api coding standard
13528 -- 2. Oracle application developer's guide
13529 -- Note:
13530 -- 1. Data types are not initialized to fnd_api.g_miss_???
13531 -- 2. Procedures or functions not exposed to user do not have the following parameters:
13532 --    p_api_version, p_msg_count, p_msg_data. x_return_status is optional.
13533 -- 3. identation and character case uses plsql mode of emacs
13534 -------------------------------------------------------------------------------
13535 END inv_quantity_tree_pvt;