DBA Data[Home] [Help]

PACKAGE BODY: APPS.INV_UTILITIES

Source


1 PACKAGE BODY inv_utilities AS
2   /* $Header: INVUTILB.pls 120.6.12010000.5 2009/01/15 09:04:17 hjogleka ship $ */
3   PROCEDURE do_sql(p_sql_stmt IN VARCHAR2) IS
4     cursor_id  INTEGER;
5     return_val INTEGER;
6     sql_stmt   VARCHAR2(8192);
7     l_debug    NUMBER         := NVL(fnd_profile.VALUE('INV_DEBUG_TRACE'), 0);
8   BEGIN
9     -- set sql statement
10     sql_stmt    := p_sql_stmt;
11     -- open a cursor
12     cursor_id   := DBMS_SQL.open_cursor;
13     -- parse sql statement
14     DBMS_SQL.parse(cursor_id, sql_stmt, DBMS_SQL.v7);
15     -- execute statement
16     return_val  := DBMS_SQL.EXECUTE(cursor_id);
17     -- close cursor
18     DBMS_SQL.close_cursor(cursor_id);
19   END do_sql;
20 
21  /*********************************** DEPRECATED *************************************
22   *********************************** DEPRECATED *************************************
23   *********************************** DEPRECATED *************************************
24   * Procedure OBSOLETED. Use INV_PICK_SLIP_REPORT.RUN_DETAIL_ENGINE for Future use.  *
25   *                THIS PROCEDURE WILL NOT BE SUPPORTED ANY MORE                     *
26   *********************************** DEPRECATED *************************************
27   *********************************** DEPRECATED *************************************
28   *********************************** DEPRECATED *************************************/
29   --Added NOCOPY hint to p_detail_status OUT parameter
30   --to comply with GSCC File.Sql.39 standard Bug:4410848
31   PROCEDURE run_detail_engine(
32     p_detail_status           OUT NOCOPY   VARCHAR2
33   , p_org_id                  IN           NUMBER
34   , p_move_order_type         IN           NUMBER
35   , p_transfer_order          IN           VARCHAR2
36   , p_source_subinv           IN           VARCHAR2
37   , p_source_locid            IN           NUMBER
38   , p_dest_subinv             IN           VARCHAR2
39   , p_dest_locid              IN           NUMBER
40   , p_requested_by            IN           NUMBER
41   , p_plan_tasks              IN           BOOLEAN
42   , p_pick_slip_group_rule_id IN           NUMBER
43   ) IS
44     v_line_id                NUMBER         := 0;
45     v_num_of_rows            NUMBER         := 0;
46     v_detailed_qty           NUMBER         := 0;
47     v_secondary_detailed_qty NUMBER         := NULL;   --INVCONV
48     v_return_status          VARCHAR2(10);
49     v_msg                    VARCHAR2(2000);
50     v_count                  NUMBER;
51     v_rev                    VARCHAR2(100)  := NULL;
52     v_from_loc_id            NUMBER         := 0;
53     v_to_loc_id              NUMBER         := 0;
54 -- Increased lot size to 80 Char - Mercy Thomas - B4625329
55     v_lot_number             VARCHAR2(80);
56     v_expiration_date        DATE;
57     v_transaction_temp_id    NUMBER;
58     v_header_id              NUMBER;
59     l_serial_flag            VARCHAR2(1)    := 'F';
60     serial_control_code      NUMBER;
61     v_inventory_item_id      NUMBER;
62     l_move_order_type        NUMBER;
63     l_max_batch              NUMBER;
64     l_batch_size             NUMBER;
65     /* FP-J PAR Replenishment Count: 3 new variables declared */
66     v_pick_slip_no           NUMBER;
67     v_err_msg                VARCHAR2(1000);
68     mtrh_header_change_track NUMBER         := 0;
69     l_req_msg                VARCHAR2(30)   := NULL;
70     /* Tracking variable to check the change in the header_id from the set of mtrls
71        fetched. If header_id changes, then update GROUPING_RULE_ID for the header
72        and continue the FOR loop until header_id changes again.  */
73 
74     /* Bug #2060360
75      * Added NVL for from_subinventory_code to allocate lines
76      * where from sub is not specified.
77     */
78     --bug 2307649
79     --type codes have changed, so we need to handle situation
80     -- where p_move_order_type = 99 (all lines)
81 
82     -- kkoothan Bug Fix:2352405
83     -- Added one more column to_account_id
84     -- in the cursor below which is later used to update
85     -- the distribution_account_id of MMTT
86 
87     /* Restructured the Following Cursor SQL as part of
88            Performance Fix: 2853526.
89            Removed NVLs around from and to Subinventory Codes and
90            used base tables mtl_txn_request_headers and
91            mtl_txn_request_lines instead of the View mtl_txn_request_lines_v*/
92     /* FP-J PAR Replenishment Counts: Introduced 3 more columns to be fetched
93        viz., header_id, project_id and task_id. Also, the cursor is now ordered by
94        mtrl.header_id so that update of GROUPING_RULE_ID of mtrh (for header_id) is
95        done efficiently knowing the fact that the cursor may fetch multiple lines
96        from same header and across headers. column header_id is used to update GROUPINNG_RULE_ID
97        of MTRH, project_id and task_id are used as input parameters for the new call
98        INV_PR_PICK_SLIP_NUMBER.GET_PICK_SLIP_NUMBER() to generate the pick slip number.*/
99     CURSOR c_move_order_lines IS
100       SELECT   mtrl.line_id
101              , mtrl.inventory_item_id
102              , mtrh.move_order_type
103              , mtrl.to_account_id
104              , mtrl.header_id
105              , mtrl.project_id
106              , mtrl.task_id
107           FROM mtl_txn_request_lines mtrl, mtl_txn_request_headers mtrh
108          WHERE mtrl.line_status IN(3, 7)
109            AND mtrl.header_id = mtrh.header_id
110            AND mtrl.organization_id = p_org_id
111            AND(
112                (p_move_order_type IN(1, 2)
113                 AND mtrh.move_order_type = p_move_order_type)
114                OR(p_move_order_type = 99
115                   AND mtrh.move_order_type IN(1, 2))
116               )
117            AND mtrl.quantity > NVL(mtrl.quantity_detailed, 0)
118            AND mtrh.request_number = NVL(p_transfer_order, mtrh.request_number)
119            AND mtrl.created_by = NVL(p_requested_by, mtrl.created_by)
120            AND(p_source_subinv IS NULL
121                OR mtrl.from_subinventory_code = p_source_subinv)
122            AND(p_dest_subinv IS NULL
123                OR mtrl.to_subinventory_code = p_dest_subinv)
124       ORDER BY mtrl.header_id;
125 
126     CURSOR c_mmtt IS
127       SELECT transaction_temp_id
128            , subinventory_code
129            , locator_id
130            , transfer_subinventory
131            , transfer_to_location
132            , revision
133         FROM mtl_material_transactions_temp
134        WHERE move_order_line_id = v_line_id
135          AND pick_slip_number IS NULL;
136 
137     l_debug                  NUMBER         := NVL(fnd_profile.VALUE('INV_DEBUG_TRACE'), 0);
138   BEGIN
139     IF p_org_id IS NULL
140        OR p_move_order_type IS NULL THEN
141       RETURN;
142     END IF;
143 
144     --only allocate requisition and replenishment move orders
145     --99 is "All"
146     IF p_move_order_type NOT IN(1, 2, 99) THEN
147       RETURN;
148     END IF;
149 
150     l_max_batch   := TO_NUMBER(fnd_profile.VALUE('INV_PICK_SLIP_BATCH_SIZE'));
151 
152     IF (l_debug = 1) THEN
153       inv_log_util.TRACE('max batch: ' || l_max_batch, 'INV_UTILITIES', 9);
154     END IF;
155 
156     IF l_max_batch IS NULL
157        OR l_max_batch <= 0 THEN
158       l_max_batch  := 20;
159 
160       IF (l_debug = 1) THEN
161         inv_log_util.TRACE('using default batch size', 'INV_UTILITIES', 9);
162       END IF;
163     END IF;
164 
165     l_batch_size  := 0;
166 
167     IF (l_debug = 1) THEN
168       inv_log_util.TRACE('Pick Slip Grouping Rule Id ' || TO_CHAR(p_pick_slip_group_rule_id), 'INV_UTILITIES', 9);
169     END IF;
170 
171     --device integration starts
172     IF (inv_install.adv_inv_installed(p_org_id) = TRUE) THEN --for WMS org
173        IF wms_device_integration_pvt.wms_call_device_request IS NULL THEN
174 	  wms_device_integration_pvt.is_device_set_up(p_org_id,wms_device_integration_pvt.WMS_BE_MO_TASK_ALLOC,v_return_status);
175        END IF;
176     END IF;
177     --device integration end
178 
179 
180     FOR move_ord_rec IN c_move_order_lines LOOP
181        l_batch_size       := l_batch_size + 1;
182        v_line_id          := move_ord_rec.line_id;
183        l_move_order_type  := move_ord_rec.move_order_type;
184 
185        /* FP-J PAR Replenishment Count: Code block to update GROUPING_RULE_ID of mtrh
186          only once per header_id change in the set of mtrls fetched in the cursor.
187          This approach works because cursor is ordered by mtrl.header_id.
188          Implied inline branching between I and J here is to check whether
189          p_pick_slip_group_rule_id IS NULL or not. In FP-I, concurrent program
190          cannot pass p_pick_slip_group_rule_id(hence default NULL). */
191       IF move_ord_rec.header_id <> mtrh_header_change_track
192          AND p_pick_slip_group_rule_id IS NOT NULL THEN
193         mtrh_header_change_track  := move_ord_rec.header_id;
194 
195         IF (l_debug = 1) THEN
196           inv_log_util.TRACE('Updating MTRH Id ' || TO_CHAR(mtrh_header_change_track), 'INV_UTILITIES', 9);
197         END IF;
198 
199         UPDATE mtl_txn_request_headers
200            SET grouping_rule_id = p_pick_slip_group_rule_id
201          WHERE header_id = move_ord_rec.header_id;
202 
203         -- Flushing out the Cached Pick Slip Numbers.
204         inv_pr_pick_slip_number.delete_wip_ps_tbl;
205       END IF;
206 
207       SELECT serial_number_control_code
208         INTO serial_control_code
209         FROM mtl_system_items
210        WHERE inventory_item_id = move_ord_rec.inventory_item_id
211          AND organization_id = p_org_id;
212 
213       IF serial_control_code <> 1 THEN
214         l_serial_flag  := 'T';
215       END IF;
216 
217       SELECT mtl_material_transactions_s.NEXTVAL
218         INTO v_header_id
219         FROM DUAL;
220 
221       inv_replenish_detail_pub.line_details_pub(
222         p_line_id                    => v_line_id
223       , x_number_of_rows             => v_num_of_rows
224       , x_detailed_qty               => v_detailed_qty
225       , x_detailed_qty2              => v_secondary_detailed_qty  --INVCONV
226       , x_return_status              => v_return_status
227       , x_msg_count                  => v_count
228       , x_msg_data                   => v_msg
229       , x_revision                   => v_rev
230       , x_locator_id                 => v_from_loc_id
231       , x_transfer_to_location       => v_to_loc_id
232       , x_lot_number                 => v_lot_number
233       , x_expiration_date            => v_expiration_date
234       , x_transaction_temp_id        => v_transaction_temp_id
235       , p_transaction_header_id      => v_header_id
236       , p_transaction_mode           => NULL
237       , p_move_order_type            => l_move_order_type
238       , p_serial_flag                => l_serial_flag
239       , p_plan_tasks                 => p_plan_tasks
240       );
241 
242       --INVCONV  Added secondary qty
243       UPDATE mtl_txn_request_lines
244          SET quantity_detailed = (nvl(quantity_delivered,0) + v_detailed_qty) -- against bug : 4155230
245             ,secondary_quantity_detailed = DECODE(v_secondary_detailed_qty,0,NULL,v_secondary_detailed_qty)
246        WHERE line_id = v_line_id
247          AND organization_id = p_org_id;
248 
249       /* FP-J PAR Replenishment Counts: Implied inline branching b/w I and J is to check
250          if p_pick_slip_group_rule_id is NULL or not. In FP-I, concurrent program cannot pass
251          p_pick_slip_group_rule_id (hence default null) */
252       IF p_pick_slip_group_rule_id IS NOT NULL THEN
253         -- Looping for each allocation of the MO Line for which Pick Slip Number is not stamped.
254         FOR v_mmtt IN c_mmtt LOOP
255           inv_pr_pick_slip_number.get_pick_slip_number(
256             p_pick_grouping_rule_id      => p_pick_slip_group_rule_id
257           , p_org_id                     => p_org_id
258           , p_wip_entity_id              => NULL
259           , p_rep_schedule_id            => NULL
260           , p_operation_seq_num          => NULL
261           , p_dept_id                    => NULL
262           , p_push_or_pull               => NULL
263           , p_supply_subinventory        => v_mmtt.transfer_subinventory
264           , p_supply_locator_id          => v_mmtt.transfer_to_location
265           , p_project_id                 => move_ord_rec.project_id
266           , p_task_id                    => move_ord_rec.task_id
267           , p_src_subinventory           => v_mmtt.subinventory_code
268           , p_src_locator_id             => v_mmtt.locator_id
269           , p_inventory_item_id          => move_ord_rec.inventory_item_id
270           , p_revision                   => v_mmtt.revision
271           , p_lot_number                 => NULL
272           , x_pick_slip_number           => v_pick_slip_no
273           , x_api_status                 => v_return_status
274           , x_error_message              => v_err_msg
275           );
276           UPDATE mtl_material_transactions_temp
277              SET pick_slip_number = v_pick_slip_no
278            WHERE transaction_temp_id = v_mmtt.transaction_temp_id;
279         END LOOP;
280       END IF;
281 
282       -- kkoothan Bug Fix:2352405
283       -- Update the distribution_account_id of MMTT
284       -- from to_account_id of mtl_txn_request_lines_v
285       -- since this was not done previously.After this fix,
286       -- MOs allocated using MO Pick Slip Report too,
287       -- along with manually allocated MO will populate
288       -- the distribution_account_id of MMTT.
289       IF move_ord_rec.to_account_id IS NOT NULL THEN
290         UPDATE mtl_material_transactions_temp
291            SET distribution_account_id = move_ord_rec.to_account_id
292          WHERE move_order_line_id = v_line_id;
293       END IF;
294 
295       IF l_batch_size >= l_max_batch THEN
296         COMMIT;
297 
298         IF (l_debug = 1) THEN
299           inv_log_util.TRACE('commit', 'INV_UTILITIES', 9);
300         END IF;
301 
302         l_batch_size  := 0;
303       END IF;
304     END LOOP;
305 
306     -- Call Device Integration API to send the details of this
307     -- PickRelease Wave to devices, if it is a WMS organization.
308     -- Note: We don't check for the return condition of this API as
309     -- we let the Move Order Allocation  process succeed
310     -- irrespective of DeviceIntegration succeed or fail.
311     if (WMS_INSTALL.check_install
312 	  (
313 	   x_return_status   => v_return_status,
314 	   x_msg_count       => v_count,
315 	   x_msg_data        => v_msg,
316 	   p_organization_id => p_org_id
317 	   ) = TRUE	) then
318        WMS_DEVICE_INTEGRATION_PVT.device_request
319 	 (p_bus_event      => WMS_DEVICE_INTEGRATION_PVT.WMS_BE_MO_TASK_ALLOC,
320 	  p_call_ctx       => WMS_Device_integration_pvt.DEV_REQ_AUTO,
321 	  p_task_trx_id    => NULL,
322 	  x_request_msg    => l_req_msg,
323 	  x_return_status  => v_return_status,
324 	  x_msg_count      => v_count,
325 	  x_msg_data       => v_msg
326 	  );
327 
328        IF (l_debug = 1) THEN
329           inv_log_util.TRACE('Device_API: return stat:'||v_return_status, 'INV_UTILITIES', 9);
330        END IF;
331 
332     end if;
333 
334 
335 
336     COMMIT;
337   EXCEPTION
338     WHEN NO_DATA_FOUND THEN
339       v_return_status  := 'E';
340   END run_detail_engine;
341 
342   --Added NOCOPY hint to table_of_strings OUT parameter to comply
343   --with GSCC File.Sql.39 standard .Bug:4410848
344   PROCEDURE parse_vector(vector_in IN VARCHAR2, delimiter IN VARCHAR2, table_of_strings OUT NOCOPY vector_tabtype) IS
345     delimiter_index NUMBER;
346     string_in       VARCHAR2(32767);
347     counter         NUMBER;
348     l_debug         NUMBER          := NVL(fnd_profile.VALUE('INV_DEBUG_TRACE'), 0);
349   BEGIN
350     --parse the input vector of strings
351     --by separating the strings that are delimitted by commas
352     string_in                  := vector_in;
353     delimiter_index            := INSTR(string_in, delimiter, 1);
354     counter                    := 0;
355 
356     --dbms_output.put_line('string_in '||string_in);
357     --dbms_output.put_line('delimiter '||delimiter);
358     --dbms_output.put_line('index '||delimiter_index);
359     WHILE delimiter_index > 0 LOOP
360       table_of_strings(counter)  := SUBSTR(string_in, 1, delimiter_index - 1);
361       string_in                  := SUBSTR(string_in, delimiter_index + 1);
362       delimiter_index            := INSTR(string_in, delimiter, 1);
363       counter                    := counter + 1;
364     END LOOP;
365 
366     --add last element of string to table
367     table_of_strings(counter)  := string_in;
368   END parse_vector;
369 
370 
371 /*
372  Added for bug No 7440217
373  PO API for LCM
374 */
375 FUNCTION inv_check_lcm(
376          p_inventory_item_id IN NUMBER,
377          p_ship_to_org_id IN NUMBER,
378          p_consigned_flag IN VARCHAR2,
379          p_outsource_assembly_flag IN VARCHAR2,
380          p_vendor_id IN NUMBER,
381          p_vendor_site_id IN NUMBER
382  )
383  RETURN VARCHAR2 IS
384       v_stock_enabled_flag VARCHAR2(1);
385       v_lcm_enabled_flag VARCHAR2(1);
386 	  v_inv_asset_flag VARCHAR2(1);
387 BEGIN
388       IF    NVL(p_consigned_flag, 'N') = 'Y'
389       OR    NVL(p_outsource_assembly_flag, 'N') = 'Y'
390       OR    NVL(p_inventory_item_id, -9999) = -9999
391       THEN
392             RETURN 'N';
393       ELSE
394            SELECT STOCK_ENABLED_FLAG,INVENTORY_ASSET_FLAG
395            INTO   v_stock_enabled_flag,v_inv_asset_flag
396            FROM   MTL_SYSTEM_ITEMS
397            WHERE  INVENTORY_ITEM_ID = p_inventory_item_id
398            AND    ORGANIZATION_ID = p_ship_to_org_id;
399 
400            IF (NVL(v_stock_enabled_flag, 'N') = 'Y' and NVL(v_inv_asset_flag,'N') = 'Y')
401            THEN
402                 SELECT NVL(LCM_ENABLED_FLAG, 'N')
403                 INTO   v_lcm_enabled_flag
404                 FROM   MTL_PARAMETERS
405                 WHERE  ORGANIZATION_ID = p_ship_to_org_id;
406 
407                 RETURN v_lcm_enabled_flag;
408             ELSE
409                 RETURN 'N';
410             END IF;
411         END IF;
412 END inv_check_lcm;
413 /*
414  END for bug No 7440217
415  PO API for LCM
416 */
417 
418 
419 
420   FUNCTION get_conc_segments(x_org_id IN NUMBER, x_loc_id IN NUMBER)
421     RETURN VARCHAR2 IS
422     x_conc_segs        VARCHAR2(2000) := NULL;
423     v_loc_str          VARCHAR2(2000) := NULL;
424     v_proj_name        VARCHAR2(50)   := NULL;
425     v_task_name        VARCHAR2(50)   := NULL;
426     v_append           VARCHAR2(1000) := NULL;
427     v_parse_str        VARCHAR2(3000) := NULL;
428     v_num              NUMBER;
429     v_cnt              NUMBER         := 0;
430     v_proj_ref_enabled NUMBER         := NULL;
431     v_flex_code        VARCHAR2(5)    := 'MTLL';
432     v_flex_num         NUMBER;
433     v_seg19_f          BOOLEAN        := FALSE;
434     v_seg20_f          BOOLEAN        := FALSE;
435     v_delim            VARCHAR2(1)    := NULL;
436     dsql_cur           NUMBER;
437     rows_processed     NUMBER;
438     str1               VARCHAR2(15)   := NULL;
439     d_data_str         VARCHAR2(1000) := NULL;
440 
441     CURSOR cur1(flex_code VARCHAR2) IS
442       SELECT   a.application_column_name
443           FROM fnd_id_flex_segments_vl a
444          WHERE a.application_id = 401
445            AND a.id_flex_code = flex_code
446            AND a.id_flex_num = (SELECT id_flex_num
447                                   FROM fnd_id_flex_structures
448                                  WHERE id_flex_code = flex_code)
449            AND a.enabled_flag = 'Y'
450            AND a.display_flag = 'Y'
451       ORDER BY a.segment_num;
452 
453     l_debug            NUMBER         := NVL(fnd_profile.VALUE('INV_DEBUG_TRACE'), 0);
454   BEGIN
455     SELECT id_flex_num
456       INTO v_flex_num
457       FROM fnd_id_flex_structures
458      WHERE id_flex_code = 'MTLL';
459 
460     SELECT project_reference_enabled
461       INTO v_proj_ref_enabled
462       FROM mtl_parameters
463      WHERE organization_id = x_org_id;
464 
465     v_delim  := fnd_flex_ext.get_delimiter('INV', v_flex_code, v_flex_num);
466     str1     := '||''' || v_delim || '''||';
467 
468     FOR cur2 IN cur1(v_flex_code) LOOP
469       IF v_proj_ref_enabled = 1
470          AND(cur2.application_column_name = 'SEGMENT19'
471              OR cur2.application_column_name = 'SEGMENT20') THEN
472         IF cur2.application_column_name = 'SEGMENT19' THEN
473           BEGIN
474             v_seg19_f  := TRUE;
475 
476             -- bug 4662395 set the profile mfg_organization_id so
477             -- the call to MTL_PROJECT_V will return data.
478 
479             FND_PROFILE.put('MFG_ORGANIZATION_ID',x_org_id);
480 
481             SELECT DISTINCT project_number
482                        INTO v_proj_name
483                        FROM mtl_project_v
484                       WHERE project_id = (SELECT NVL(TO_NUMBER(segment19), 0)
485                                             FROM mtl_item_locations
486                                            WHERE inventory_location_id = x_loc_id
487                                              AND organization_id = x_org_id);
488           EXCEPTION
489             WHEN OTHERS THEN
490               v_proj_name  := NULL;
491           END;
492         ELSIF cur2.application_column_name = 'SEGMENT20' THEN
493           BEGIN
494             v_seg20_f  := TRUE;
495 
496             SELECT DISTINCT a.task_number
497                        INTO v_task_name
498                        FROM mtl_task_v a
499                       WHERE a.task_id = (SELECT NVL(TO_NUMBER(segment20), 0)
500                                            FROM mtl_item_locations
501                                           WHERE inventory_location_id = x_loc_id
502                                             AND organization_id = x_org_id)
503                         AND a.project_id = (SELECT NVL(TO_NUMBER(segment19), a.project_id)
504                                               FROM mtl_item_locations
505                                              WHERE inventory_location_id = x_loc_id
506                                                AND organization_id = x_org_id);
507           EXCEPTION
508             WHEN OTHERS THEN
509               v_task_name  := NULL;
510           END;
511         END IF;
512       END IF;
513     END LOOP;
514 
515     FOR cur2 IN cur1(v_flex_code) LOOP
516       IF v_loc_str IS NOT NULL THEN
517         v_append  := v_loc_str || str1;
518       ELSE
519         v_append  := NULL;
520       END IF;
521 
522       /*Bug#4278601
523       v_loc_str needs to contain the locator segments in the order it was defined,
524       including project and task segments.*/
525       IF (CUR2.APPLICATION_COLUMN_NAME =  'SEGMENT19') THEN
526           v_loc_str := v_append||''''||v_proj_name||'''';
527       ELSIF (CUR2.APPLICATION_COLUMN_NAME =  'SEGMENT20') THEN
528           v_loc_str := v_append||''''||v_task_name||'''';
529       ELSIF (cur2.application_column_name <> 'SEGMENT19'
530           AND cur2.application_column_name <> 'SEGMENT20') THEN
531           v_loc_str  := v_append || cur2.application_column_name;
532       END IF;
533     END LOOP;
534 
535     IF v_loc_str IS NOT NULL THEN
536       v_parse_str     :=
537             'select ' || v_loc_str || ' from mtl_item_locations where inventory_location_id = :loc_id ' || ' and organization_id = :org_id';
538       dsql_cur        := DBMS_SQL.open_cursor;
539       DBMS_SQL.parse(dsql_cur, v_parse_str, DBMS_SQL.native);
540       DBMS_SQL.define_column(dsql_cur, 1, d_data_str, 800);
541       DBMS_SQL.bind_variable(dsql_cur, 'loc_id', x_loc_id);
542       DBMS_SQL.bind_variable(dsql_cur, 'org_id', x_org_id);
543       rows_processed  := DBMS_SQL.EXECUTE(dsql_cur);
544 
545       LOOP
546         IF (DBMS_SQL.fetch_rows(dsql_cur) > 0) THEN
547           DBMS_SQL.column_value(dsql_cur, 1, d_data_str);
548         ELSE
549           -- No more rows in cursor
550           DBMS_SQL.close_cursor(dsql_cur);
551           EXIT;
552         END IF;
553       END LOOP;
554 
555       IF DBMS_SQL.is_open(dsql_cur) THEN
556         DBMS_SQL.close_cursor(dsql_cur);
557       END IF;
558     END IF;
559 
560     /*Bug 4278601
561     Comment out this section because now d_data_str will have the complete locator information
562     in the order it was defined.
563     IF v_seg19_f
564        AND v_seg20_f THEN
565       x_conc_segs  := d_data_str || v_delim || v_proj_name || v_delim || v_task_name;
566     ELSIF v_seg19_f THEN
567       x_conc_segs  := d_data_str || v_delim || v_proj_name;
568     ELSIF v_seg20_f THEN
569       x_conc_segs  := d_data_str || v_delim || v_task_name;
570     ELSE
571       x_conc_segs  := d_data_str;
572     END IF;*/
573 
574     x_conc_segs := d_data_str; --Bug#4278601
575 
576     RETURN x_conc_segs;
577   EXCEPTION
578     WHEN OTHERS THEN
579       x_conc_segs  := NULL;
580       RETURN x_conc_segs;
581   END get_conc_segments;
582 
583   /*
584    Added for bug No :2326247.
585    Calculates the item cost based on costing.
586   */
587   --Added NOCOPY hint to v_item_cost OUT parameter to comply
588   --with GSCC standard File.Sql.39. Bug:4410848
589   PROCEDURE get_item_cost(v_org_id IN NUMBER, v_item_id IN NUMBER, v_locator_id IN NUMBER, v_item_cost OUT NOCOPY NUMBER) IS
590     -- For standard costed orgs, get the item cost with the common
591     -- cost group ID = 1.  For average costed orgs, use the org's
592     -- default cost group ID
593     -- Bug # 2180251: All primary costing methods not equal to 1 should
594     -- also be considered as an average costed org
595     l_debug NUMBER := NVL(fnd_profile.VALUE('INV_DEBUG_TRACE'), 0);
596     --Forward port bug7037252 	of bugs 6349028 and 6343400
597     --Added DECODE on wms_enabled_flag in the 2nd SELECT stmt.
598     --For WMS enabled average costing org, the org level CG may not be same as the onhand CG because you can have CG rules.
599     l_wms_enabled_flag VARCHAR2(1) :=  'N';
600   BEGIN
601     --Bug7037252/6349028/6343400. Added following SELECT
602     SELECT NVL(mp.wms_enabled_flag,'N')
603      INTO l_wms_enabled_flag
604     FROM MTL_PARAMETERS mp
605     WHERE mp.organization_id=v_org_id ;
606     SELECT NVL(ccicv.item_cost, 0)
607       INTO v_item_cost
608       FROM cst_cg_item_costs_view ccicv, mtl_parameters mp
609      WHERE v_locator_id IS NULL
610        AND ccicv.organization_id = v_org_id
611        AND ccicv.inventory_item_id = v_item_id
612        AND ccicv.organization_id = mp.organization_id
613        AND ccicv.cost_group_id = DECODE(mp.primary_cost_method, 1, 1, NVL(mp.default_cost_group_id, 1))
614     UNION ALL
615     SELECT NVL(ccicv.item_cost, 0)
616       FROM mtl_item_locations mil, cst_cg_item_costs_view ccicv, mtl_parameters mp
617      WHERE v_locator_id IS NOT NULL
618        AND mil.organization_id = v_org_id
619        AND mil.inventory_location_id = v_locator_id
620        AND mil.project_id IS NULL
621        AND ccicv.organization_id = mil.organization_id
622        AND ccicv.inventory_item_id = v_item_id
623        AND ccicv.organization_id = mp.organization_id
624     AND ccicv.cost_group_id = DECODE(mp.primary_cost_method, 1, 1, DECODE(l_wms_enabled_flag,'Y',ccicv.cost_group_id, NVL(mp.default_cost_group_id, 1)))
625     UNION ALL
626     SELECT NVL(ccicv.item_cost, 0)
627       FROM mtl_item_locations mil, mrp_project_parameters mrp, cst_cg_item_costs_view ccicv, mtl_parameters mp
628      WHERE v_locator_id IS NOT NULL
629        AND mil.organization_id = v_org_id
630        AND mil.inventory_location_id = v_locator_id
631        AND mil.project_id IS NOT NULL
632        AND mrp.organization_id = mil.organization_id
633        AND mrp.project_id = mil.project_id
634        AND ccicv.organization_id = mil.organization_id
635        AND ccicv.inventory_item_id = v_item_id
636        AND ccicv.organization_id = mp.organization_id
637        AND ccicv.cost_group_id = DECODE(mp.primary_cost_method, 1, 1, NVL(mrp.costing_group_id, 1));
638   EXCEPTION
639     WHEN NO_DATA_FOUND THEN
640       v_item_cost  := -999;
641     WHEN TOO_MANY_ROWS THEN  --Bug    --Forward port 7037252/6349028/6343400
642      IF (l_wms_enabled_flag = 'Y' ) THEN
643        --For WMS org with average costing, there may be more than one rows in cst_cg_item_costs_view.
644        --In this case, the correct cost will be stamped from INV_COST_GROUP_PVT after obtaining exact cost group.
645        v_item_cost := 1; --This is hard-coded so that we can retrieve the percent value in  INV_COST_GROUP_PVT.
646      ELSE
647        v_item_cost  := -999;  --This should result in error for non-wms orgs.
648      END IF;
649   END get_item_cost;
650 
651   PROCEDURE get_sales_order_id (
652     p_sales_order_number               NUMBER  ,
653     p_sales_order_type                 VARCHAR2,
654     p_sales_order_source               VARCHAR2,
655     p_concatenated_segments OUT NOCOPY VARCHAR2,
656     p_source_id             OUT NOCOPY NUMBER) IS
657   /*
658     ||==============================================================================||
659     ||  Created By : Nalin Kumar                                                    ||
660     ||  Created On : 03-May-2005                                                    ||
661     ||  Purpose    : This procedure will get called from TMO. This procedure will   ||
662     ||               return the Sales Order ID and Concatenated Segments. Created   ||
663     ||               as part of Depot Repair Enh. Bug# 4346443                      ||
664     ||                                                                              ||
665     ||  Known limitations, enhancements or remarks :                                ||
666     ||  Change History :                                                            ||
667     ||  Who             When            What                                        ||
668     ||  (reverse chronological order - newest change first)                         ||
669     ||==============================================================================||
670   */
671     l_delimiter VARCHAR2(1) := NULL;
672     l_segment_array FND_FLEX_EXT.SegmentArray;
673     l_n_segments NUMBER;
674     l_val BOOLEAN;
675   BEGIN
676     p_source_id := NULL;
677     --Get the Delimiter...
678     l_delimiter := fnd_flex_apis.get_segment_delimiter(
679                      x_application_id => 401,
680                      x_id_flex_code   => 'MKTS',
681                      x_id_flex_num    => '101');
682 
683     l_segment_array(1) := p_sales_order_number;
684     l_segment_array(2) := p_sales_order_type;
685     l_segment_array(3) := p_sales_order_source;
686     l_n_segments       := 3;
687 
688     --Get Concatenated Segments...
689     p_concatenated_segments := fnd_flex_ext.concatenate_segments(l_n_segments, l_segment_array, l_delimiter);
690 
691     --Check for the combination...
692     l_val := fnd_flex_keyval.validate_segs(
693                operation        => 'FIND_COMBINATION',
694                appl_short_name  => 'INV',
695                key_flex_code    => 'MKTS',
696                structure_number => '101',
697                concat_segments  => p_concatenated_segments,
698                validation_date  => SYSDATE);
699 
700     --Get the combination id (source_id)...
701     IF l_val THEN
702       p_source_id := fnd_flex_keyval.combination_id;
703     END IF;
704   END get_sales_order_id ;
705 
706 END inv_utilities;