DBA Data[Home] [Help]

PACKAGE BODY: APPS.INV_WIP_PICKING_PVT

Source


1 PACKAGE BODY inv_wip_picking_pvt AS
2   /* $Header: INVVWPKB.pls 120.10 2006/08/24 22:12:02 qxliu noship $ */
3 
4   -- Conc mode identification
5   g_conc_mode BOOLEAN := FALSE;
6   g_trace_on NUMBER := NVL(FND_PROFILE.VALUE('INV_DEBUG_TRACE'),2);
7 
8   -- Allocation Status - Used both at Header Level (Pick_Release) and Lines Level (Process_Line)
9   g_completely_allocated VARCHAR2(1) := 'S';
10   g_partially_allocated  VARCHAR2(1) := 'P';
11   g_not_allocated        VARCHAR2(1) := 'N';
12 
13   -- Global table to store allocation status at the move order line level
14   TYPE g_mo_line_stat_type IS TABLE OF VARCHAR2(1) INDEX BY BINARY_INTEGER;
15   g_mo_line_stat_tbl g_mo_line_stat_type;
16 
17   -- Bug 5469486: add a separate counter for lines where MO line not created
18   g_mol_fail_count       NUMBER;
19 
20   -- Global variable for tracking WIP patch level
21   -- Bug 4288399, moved to spec
22   --g_wip_patch_level NUMBER := -999;
23 
24   -- Forward declarations
25   PROCEDURE process_line(
26     p_mo_line_rec        IN OUT NOCOPY inv_move_order_pub.trolin_rec_type
27   , p_allow_partial_pick IN     VARCHAR2  DEFAULT  fnd_api.g_true
28   , p_grouping_rule_id   IN     NUMBER    DEFAULT  NULL
29   , p_plan_tasks         IN     BOOLEAN
30   , p_call_wip_api       IN     BOOLEAN   --Added bug 4634522
31   , x_return_status      OUT    NOCOPY  VARCHAR2
32   , x_msg_count          OUT    NOCOPY  NUMBER
33   , x_msg_data           OUT    NOCOPY  VARCHAR2
34   , x_detail_rec_count   OUT    NOCOPY  NUMBER
35   );
36 
37   PROCEDURE update_mmtt_for_wip(
38     x_return_status    OUT NOCOPY VARCHAR2
39   , p_mo_line_rec      IN         inv_move_order_pub.trolin_rec_type
40   , p_grouping_rule_id IN         NUMBER
41   );
42 
43   FUNCTION get_mo_alloc_stat RETURN VARCHAR2;
44   -- End forward declarations
45 
46   PROCEDURE print_debug(p_message IN VARCHAR2, p_module IN VARCHAR2) IS
47   BEGIN
48     inv_log_util.trace(p_message, g_pkg_name || '.' || p_module,3);
49   END print_debug;
50 
51 
52   --
53   -- pre patchset I version
54   --
55   PROCEDURE release_pick_batch
56   ( p_mo_header_rec           IN   INV_Move_Order_PUB.Trohdr_Rec_Type
57   , p_mo_line_rec_tbl         IN   INV_Move_Order_PUB.Trolin_Tbl_Type
58   , p_auto_detail_flag        IN   VARCHAR2
59   , p_auto_pick_confirm_flag  IN   VARCHAR2
60   , p_allow_partial_pick      IN   VARCHAR2
61   , p_commit                  IN   VARCHAR2
62   , p_init_msg_lst            IN   VARCHAR2
63   , x_return_status           OUT  NOCOPY  VARCHAR2
64   , x_msg_count               OUT  NOCOPY  NUMBER
65   , x_msg_data                OUT  NOCOPY  VARCHAR2
66   ) IS
67 
68     l_conc_req_id        NUMBER;
69     l_api_return_status  VARCHAR2(1);
70     l_debug              NUMBER := NVL(FND_PROFILE.VALUE('INV_DEBUG_TRACE'),0);
71     l_mo_header_rec      INV_Move_Order_PUB.Trohdr_Rec_Type;
72 
73 -- Bug 4288399
74     l_wip_error_table    INV_WIP_Picking_PVT.Trolin_ErrTbl_Type;
75 
76   BEGIN
77     IF (l_debug = 1) THEN
78        print_debug('Pre-I version of pick release called', 'RELEASE_PICK_BATCH');
79     END IF;
80 
81     g_wip_patch_level := 1158;
82     l_mo_header_rec   := p_mo_header_rec;
83 
84     --
85     -- Pre 11.5.9 WIP uses 2 move order types (G_MOVE_ORDER_WIP_ISSUE and G_MOVE_ORDER_BACKFLUSH),
86     -- but Inventory 11.5.9 has changed to a single type (G_MOVE_ORDER_MFG_PICK)
87     --
88     IF l_mo_header_rec.move_order_type = INV_GLOBALS.G_MOVE_ORDER_BACKFLUSH THEN
89        l_mo_header_rec.move_order_type := INV_GLOBALS.G_MOVE_ORDER_MFG_PICK;
90        IF (l_debug = 1) THEN
91           print_debug('Changed MO type from ' || INV_GLOBALS.G_MOVE_ORDER_BACKFLUSH ||' to ' || l_mo_header_rec.move_order_type, 'RELEASE_PICK_BATCH');
92        END IF;
93     END IF;
94 
95     release_pick_batch(
96       p_mo_header_rec           => l_mo_header_rec
97     , p_mo_line_rec_tbl         => p_mo_line_rec_tbl
98     , p_auto_detail_flag        => p_auto_detail_flag
99     , p_auto_pick_confirm_flag  => p_auto_pick_confirm_flag
100     , p_allow_partial_pick      => p_allow_partial_pick
101     , p_print_pick_slip         => FND_API.G_FALSE
102     , p_plan_tasks              => FALSE
103     , p_commit                  => p_commit
104     , p_init_msg_lst            => p_init_msg_lst
105     , x_return_status           => l_api_return_status
106     , x_msg_count               => x_msg_count
107     , x_msg_data                => x_msg_data
108     , x_conc_req_id             => l_conc_req_id
109     , x_mo_line_errrec_tbl      => l_wip_error_table -- Bug 4288399
110     );
111 
112     IF (l_debug = 1) THEN
113       print_debug('Return Status from release_pick_batch (main): ' || l_api_return_status, 'RELEASE_PICK_BATCH');
114     END IF;
115 
116     --
117     -- Pre 11.5.9 WIP code does not recognize status 'N'
118     --
119     IF l_api_return_status = 'N' THEN
120        l_api_return_status := 'P';
121     END IF;
122 
123     x_return_status := l_api_return_status;
124   EXCEPTION
125     WHEN OTHERS THEN
126       IF (l_debug = 1) THEN
127          print_debug('Error: ' || SQLCODE || ', ' || SQLERRM, 'RELEASE_PICK_BATCH');
128       END IF;
129       x_return_status := fnd_api.g_ret_sts_error;
130   END release_pick_batch;
131 
132 
133 
134   --
135   -- patchset I version
136   --
137   PROCEDURE release_pick_batch
138   ( p_mo_header_rec           IN OUT NOCOPY inv_move_order_pub.trohdr_rec_type
139   , p_mo_line_rec_tbl         IN     inv_move_order_pub.trolin_tbl_type
140   , p_auto_detail_flag        IN     VARCHAR2
141   , p_auto_pick_confirm_flag  IN     VARCHAR2
142   , p_allow_partial_pick      IN     VARCHAR2
143   , p_print_pick_slip         IN     VARCHAR2
144   , p_plan_tasks              IN     BOOLEAN
145   , p_commit                  IN     VARCHAR2
146   , p_init_msg_lst            IN     VARCHAR2
147   , x_return_status           OUT    NOCOPY  VARCHAR2
148   , x_msg_count               OUT    NOCOPY  NUMBER
149   , x_msg_data                OUT    NOCOPY  VARCHAR2
150   , x_conc_req_id             OUT    NOCOPY  NUMBER
151   , x_mo_line_errrec_tbl      OUT    NOCOPY  INV_WIP_Picking_PVT.Trolin_ErrTbl_Type  -- Bug 4288399
152   ) IS
153 
154     l_api_version_number    NUMBER       := 1.0;
155     l_api_return_status     VARCHAR2(1);
156     l_commit                VARCHAR2(1)  := fnd_api.g_false;
157     l_temp                  BOOLEAN;
158     l_trohdr_val_rec        inv_move_order_pub.trohdr_val_rec_type;
159     l_trolin_val_tbl        inv_move_order_pub.trolin_val_tbl_type;
160     l_organization_id       NUMBER;
161     l_auto_pick_confirm     VARCHAR2(1)  := fnd_api.g_false;
162     l_entity_type           NUMBER;
163     l_max_batch             NUMBER;
164     l_counter               NUMBER;
165     l_last_rec              NUMBER;
166     l_last_batch_rec        NUMBER;
167     l_rec_count             NUMBER;
168     l_index                 NUMBER;
169     l_line_tbl              inv_move_order_pub.trolin_tbl_type;
170     l_is_wms_org            BOOLEAN  := FALSE;
171     l_mo_allocation_status  VARCHAR2(1) := g_not_allocated;
172     l_req_msg               VARCHAR2(255); -- Informational message from device integration API
173 
174 -- Bug 4288399
175     l_wip_error_table       INV_WIP_Picking_PVT.Trolin_ErrTbl_Type;
176     l_wip_error_table_cnt   NUMBER := 0;
177     l_msgcnt                NUMBER;
178     l_msg_data              VARCHAR2(2000);
179 
180     l_savept_exists         BOOLEAN := FALSE;
181     l_wip_err_count         NUMBER;
182     l_err_start_index       NUMBER;
183 
184     CURSOR c_get_entity_type(p_wip_entity_id IN NUMBER, p_org_id IN NUMBER) IS
185         SELECT entity_type
186           FROM wip_entities
187          WHERE wip_entity_id   = p_wip_entity_id
188            AND organization_id = p_org_id;
189 
190     l_debug number := NVL(FND_PROFILE.VALUE('INV_DEBUG_TRACE'),0);
191   BEGIN
192 
193     IF NVL(g_wip_patch_level,-999) = -999 THEN
194        g_wip_patch_level := 1159;
195     END IF;
196 
197     l_organization_id  := p_mo_header_rec.organization_id;
198     IF (l_debug = 1) THEN
199        print_debug('***************** Start of WIP pick release ****************', 'RELEASE_PICK_BATCH');
200        print_debug('Org ID: '|| TO_CHAR(l_organization_id), 'RELEASE_PICK_BATCH');
201     END IF;
202     g_mo_line_stat_tbl.DELETE;
203     g_mol_fail_count := 0;
204 
205     SAVEPOINT inv_wip_pick_release;
206     l_savept_exists := TRUE;
207 
208     --  Initialize message list.
209     IF fnd_api.to_boolean(p_init_msg_lst) THEN
210        fnd_msg_pub.initialize;
211     END IF;
212 
213     -- Validate parameter for allowing partial pick release
214     IF  p_allow_partial_pick NOT IN (fnd_api.g_true, fnd_api.g_false) THEN
215        IF (l_debug = 1) THEN
216           print_debug('Error: invalid partial pick parameter','RELEASE_PICK_BATCH');
217        END IF;
218        fnd_message.set_name('INV', 'INV_INVALID_PARTIAL_PICK_PARAM');
219        fnd_msg_pub.ADD;
220        RAISE fnd_api.g_exc_unexpected_error;
221     END IF;
222 
223     IF (l_debug = 1) THEN
224        print_debug('p_allow_partial_pick is '|| p_allow_partial_pick, 'RELEASE_PICK_BATCH');
225     END IF;
226 
227     --Bug 4288399, if its not a concurrent mode, the profile is set to -1
228     --so, changed the check below from 0 to -1
229     IF NVL(fnd_profile.VALUE('CONC_REQUEST_ID'), -1) <> -1 THEN
230        g_conc_mode  := TRUE;
231     ELSE
232        g_conc_mode  := FALSE;
233     END IF;
234 
235     l_is_wms_org := inv_install.adv_inv_installed(l_organization_id);
236 
237     -- Initialize API return status to success
238     x_return_status := fnd_api.g_ret_sts_success;
239 
240     -- Determine whether or not to automatically pick confirm
241     IF p_auto_pick_confirm_flag <> fnd_api.g_miss_char THEN
242        IF (p_auto_pick_confirm_flag NOT IN  (fnd_api.g_true, fnd_api.g_false) ) THEN
243           IF (l_debug = 1) THEN
244              print_debug('Error: Invalid auto_pick_confirm flag', 'RELEASE_PICK_BATCH');
245           END IF;
246           fnd_message.set_name('INV', 'INV_AUTO_PICK_CONFIRM_PARAM');
247           fnd_msg_pub.ADD;
248           RAISE fnd_api.g_exc_unexpected_error;
249        ELSE
250           l_auto_pick_confirm  := p_auto_pick_confirm_flag;
251        END IF;
252     ELSE
253        -- Retrieve the org-level parameter for auto-pick confirm
254        BEGIN
255           -- The parameter is for whether pick confirm is required or not,
256           -- so the auto-pick confirm flag is the opposite of this.
257           SELECT DECODE(NVL(mo_pick_confirm_required, 2), 1, fnd_api.g_false, 2, fnd_api.g_true, fnd_api.g_true)
258             INTO l_auto_pick_confirm
259             FROM mtl_parameters
260            WHERE organization_id = l_organization_id;
261        EXCEPTION
262           WHEN NO_DATA_FOUND THEN
263               IF (l_debug = 1) THEN
264                   print_debug('Error: Invalid auto_pick_confirm flag', 'RELEASE_PICK_BATCH');
265               END IF;
266               fnd_message.set_name('INV', 'INV-NO ORG INFORMATION');
267               fnd_msg_pub.ADD;
268               RAISE fnd_api.g_exc_unexpected_error;
269        END;
270     END IF;
271 
272     IF (l_debug = 1) THEN
273        print_debug('Auto Pick Confirm flag: '|| l_auto_pick_confirm, 'RELEASE_PICK_BATCH');
274     END IF;
275 
276     -- Bug 2666620: Grouping Rule ID has to be stamped
277     -- Bug 2844622: Skip this check if WIP patch level is below 11.5.9
278     IF g_wip_patch_level >= 1159 THEN
279        IF nvl(p_mo_header_rec.grouping_rule_id,fnd_api.g_miss_num) =  fnd_api.g_miss_num THEN
280           IF (l_debug = 1) THEN
281              print_debug('No Pick Slip Grouping Rule ID specified', 'RELEASE_PICK_BATCH');
282           END IF;
283           fnd_message.set_name('INV', 'INV_NO_PICK_SLIP_NUMBER');
284           fnd_msg_pub.ADD;
285           RAISE fnd_api.g_exc_unexpected_error;
286        END IF;
287     ELSE
288        IF (l_debug = 1) THEN
289           print_debug('WIP patch level is ' || to_char(g_wip_patch_level) ||
290                       ' so skipping grouping_rule_id check.', 'RELEASE_PICK_BATCH');
291        END IF;
292     END IF;
293 
294     IF (l_debug = 1) THEN
295        print_debug('Calling Create Move Order Header', 'RELEASE_PICK_BATCH');
296     END IF;
297 
298     inv_move_order_pub.create_move_order_header(
299       p_api_version_number  => l_api_version_number
300     , p_init_msg_list       => fnd_api.g_false
301     , p_return_values       => fnd_api.g_true
302     , p_commit              => l_commit
303     , x_return_status       => l_api_return_status
304     , x_msg_count           => x_msg_count
305     , x_msg_data            => x_msg_data
306     , p_trohdr_rec          => p_mo_header_rec
307     , p_trohdr_val_rec      => l_trohdr_val_rec
308     , x_trohdr_rec          => p_mo_header_rec
309     , x_trohdr_val_rec      => l_trohdr_val_rec
310     );
311 
312     IF l_api_return_status <> fnd_api.g_ret_sts_success THEN
313        IF (l_debug = 1) THEN
314           print_debug('Error occurred in Create_Move_Order_Header', 'RELEASE_PICK_BATCH');
315        END IF;
316        RAISE fnd_api.g_exc_unexpected_error;
317     ELSE
318        IF (l_debug = 1) THEN
319           print_debug('Created MO Header successfully: '|| p_mo_header_rec.header_id, 'RELEASE_PICK_BATCH');
320        END IF;
321     END IF;
322 
323     IF p_mo_line_rec_tbl.COUNT > 0 THEN
324        IF (l_debug = 1) THEN
325           print_debug('Number of MO Lines to create: '|| TO_CHAR(p_mo_line_rec_tbl.COUNT), 'RELEASE_PICK_BATCH');
326        END IF;
327     ELSE
328        IF (l_debug = 1) THEN
329           print_debug('No MO Lines to create!', 'RELEASE_PICK_BATCH');
330        END IF;
331        RAISE fnd_api.g_exc_unexpected_error;
332     END IF;
333 
334     --
335     -- Bug 2844622: Skip performance changes (breaking up move order lines
336     -- into batches) if WIP patch level is below 11.5.9
337     --
338     IF g_wip_patch_level >= 1159 THEN
339        l_max_batch := to_number(fnd_profile.value('INV_COMPONENT_PICK_BATCH_SIZE'));
340        IF (l_debug = 1) THEN
341           print_debug('Max batch size: ' || l_max_batch, 'RELEASE_PICK_BATCH');
342        END IF;
343        IF l_max_batch IS NULL or l_max_batch <= 0 THEN
344           l_max_batch := 20;
345           IF (l_debug = 1) THEN
346              print_debug('using default batch size of 20', 'RELEASE_PICK_BATCH');
347           END IF;
348        END IF;
349 
350        l_last_rec := p_mo_line_rec_tbl.LAST;
351        l_counter  := p_mo_line_rec_tbl.FIRST;
352        WHILE l_counter <= l_last_rec LOOP
353          IF (l_debug = 1) THEN
354              print_debug('Rec Counter: ' || l_counter, 'RELEASE_PICK_BATCH');
355          END IF;
356          l_last_batch_rec := l_counter + l_max_batch-1;
357          IF l_last_batch_rec >= l_last_rec THEN
358             l_last_batch_rec := l_last_rec;
359             -- find the end of the current ship set.  All the lines for this
360             -- shipset should be processed in the same commit cycle
361          ELSIF p_mo_line_rec_tbl(l_last_batch_rec).ship_set_id IS NOT NULL THEN
362             LOOP
363                EXIT WHEN l_last_batch_rec = l_last_rec;
364 
365                IF p_mo_line_rec_tbl(l_last_batch_rec+1).ship_set_id IS NULL
366                   OR (p_mo_line_rec_tbl(l_last_batch_rec).ship_set_id
367                       <> p_mo_line_rec_tbl(l_last_batch_rec+1).ship_set_id)
368                THEN
369                   -- last_batch_rec is the last line in this shipset, so exit
370                   EXIT;
371                END IF;
372 
373                l_last_batch_rec := l_last_batch_rec + 1;
374             END LOOP;
375          END IF;
376 
377          IF (l_debug = 1) THEN
378             print_debug('Last batch record:'||l_last_batch_rec, 'RELEASE_PICK_BATCH');
379          END IF;
380 
381          --copy move order lines into table to pass to create MO lines and pick release;
382          l_rec_count := l_counter;
383          l_index := 1;
384          LOOP
385             EXIT WHEN l_rec_count > l_last_batch_rec;
386             l_line_tbl(l_index) := p_mo_line_rec_tbl(l_rec_count);
387             l_line_tbl(l_index).header_id := p_mo_header_rec.header_id;
388             l_line_tbl(l_index).line_number := l_rec_count;
389             l_index := l_index + 1;
390             l_rec_count:= l_rec_count + 1;
391          END LOOP;
392 
393          IF (l_debug = 1) THEN
394             print_debug('Calling create_move_order_lines', 'RELEASE_PICK_BATCH');
395          END IF;
396 
397          IF NOT l_savept_exists THEN
398             SAVEPOINT inv_wip_pick_release;
399             l_savept_exists := TRUE;
400          END IF;
401 
402          inv_move_order_pub.create_move_order_lines(
403            p_api_version_number  => l_api_version_number
404          , p_init_msg_list       => fnd_api.g_true
405          , p_return_values       => fnd_api.g_true
406          , p_commit              => l_commit
407          , x_return_status       => l_api_return_status
408          , x_msg_count           => x_msg_count
409          , x_msg_data            => x_msg_data
410          , p_trolin_tbl          => l_line_tbl
411          , p_trolin_val_tbl      => l_trolin_val_tbl
412          , x_trolin_tbl          => l_line_tbl
413          , x_trolin_val_tbl      => l_trolin_val_tbl
414          );
415 
416          IF l_api_return_status <> fnd_api.g_ret_sts_success THEN
417             IF (l_debug = 1) THEN
418                print_debug('Error occurred in Create_Move_Order_Lines = '||l_api_return_status
419                           ,'RELEASE_PICK_BATCH');
420             END IF;
421          -- Bug 4288399, Filtering the errored records and continuing
422             IF l_api_return_status = fnd_api.g_ret_sts_unexp_error THEN
423                RAISE fnd_api.g_exc_unexpected_error;
424             ELSIF (g_conc_mode) THEN
425                l_wip_err_count := 0;
426                l_err_start_index := l_wip_error_table.COUNT;
427                IF (l_debug = 1) THEN
428                   print_debug('Conc_mode is True', 'RELEASE_PICK_BATCH');
429                   print_debug('Number of records currently in error table: ' || l_err_start_index,
430                               'RELEASE_PICK_BATCH');
431                END IF;
432                FOR i in 1..l_line_tbl.COUNT LOOP
433                  IF l_line_tbl(i).return_status = fnd_api.g_ret_sts_error THEN
434                     IF (l_debug = 1) THEN
435                        print_debug('Delete Line '||l_line_tbl(i).line_id, 'RELEASE_PICK_BATCH');
436                     END IF;
437 
438                     -- Bug 5469486: handle the case where line ID is g_miss_num
439                     IF l_line_tbl(i).line_id = fnd_api.g_miss_num THEN
440                        g_mol_fail_count := g_mol_fail_count + 1;
441                     ELSE
442                        g_mo_line_stat_tbl(l_line_tbl(i).line_id) := g_not_allocated;
443                     END IF;
444 
445                     l_wip_error_table_cnt := l_wip_error_table.COUNT + 1;
446                     l_wip_err_count := l_wip_err_count + 1;
447                     l_wip_error_table(l_wip_error_table_cnt).line_id := l_line_tbl(i).line_id;
448                     l_wip_error_table(l_wip_error_table_cnt).header_id  := l_line_tbl(i).header_id;
449                     l_wip_error_table(l_wip_error_table_cnt).organization_id  := l_line_tbl(i).organization_id;
450                     l_wip_error_table(l_wip_error_table_cnt).inventory_item_id  := l_line_tbl(i).inventory_item_id;
451                     l_wip_error_table(l_wip_error_table_cnt).txn_source_id := l_line_tbl(i).txn_source_id;
452                     l_wip_error_table(l_wip_error_table_cnt).txn_source_line_id := l_line_tbl(i).txn_source_line_id;
453                     l_wip_error_table(l_wip_error_table_cnt).from_subinventory_code := l_line_tbl(i).from_subinventory_code;
454                     l_wip_error_table(l_wip_error_table_cnt).to_subinventory_code := l_line_tbl(i).to_subinventory_code;
455                     l_wip_error_table(l_wip_error_table_cnt).line_status  := l_line_tbl(i).line_status;
456                     l_wip_error_table(l_wip_error_table_cnt).lot_number  := l_line_tbl(i).lot_number;
457                     l_wip_error_table(l_wip_error_table_cnt).from_locator_id  := l_line_tbl(i).from_locator_id;
458                     l_wip_error_table(l_wip_error_table_cnt).to_locator_id  := l_line_tbl(i).to_locator_id;
459                     l_wip_error_table(l_wip_error_table_cnt).project_id  := l_line_tbl(i).project_id;
460                     l_wip_error_table(l_wip_error_table_cnt).task_id  := l_line_tbl(i).task_id;
461                     l_wip_error_table(l_wip_error_table_cnt).revision  := l_line_tbl(i).revision;
462                     l_wip_error_table(l_wip_error_table_cnt).transaction_type_id  := l_line_tbl(i).transaction_type_id;
463                     l_wip_error_table(l_wip_error_table_cnt).primary_quantity  :=   l_line_tbl(i).primary_quantity;
464                     l_wip_error_table(l_wip_error_table_cnt).to_organization_id  :=   l_line_tbl(i).to_organization_id;
465                     l_wip_error_table(l_wip_error_table_cnt).uom_code  :=   l_line_tbl(i).uom_code;
466                     l_wip_error_table(l_wip_error_table_cnt).lpn_id  :=   l_line_tbl(i).lpn_id;
467                     l_wip_error_table(l_wip_error_table_cnt).to_lpn_id  :=   l_line_tbl(i).to_lpn_id;
468                     l_wip_error_table(l_wip_error_table_cnt).return_status  :=   l_line_tbl(i).return_status;
469                     l_wip_error_table(l_wip_error_table_cnt).ship_set_id  :=   l_line_tbl(i).ship_set_id;
470                     l_wip_error_table(l_wip_error_table_cnt).required_quantity  :=   l_line_tbl(i).required_quantity;
471                     l_wip_error_table(l_wip_error_table_cnt).quantity   := l_line_tbl(i).quantity;
472                     l_wip_error_table(l_wip_error_table_cnt).quantity_delivered   := l_line_tbl(i).quantity_delivered;
473                     l_wip_error_table(l_wip_error_table_cnt).quantity_detailed   := l_line_tbl(i).quantity_detailed;
474                     l_wip_error_table(l_wip_error_table_cnt).line_number   := l_line_tbl(i).line_number;
475                     l_wip_error_table(l_wip_error_table_cnt).creation_date := l_line_tbl(i).creation_date;
476                     l_wip_error_table(l_wip_error_table_cnt).date_required := l_line_tbl(i).date_required;
477                     l_wip_error_table(l_wip_error_table_cnt).to_organization_id := l_line_tbl(i).to_organization_id;
478                     l_wip_error_table(l_wip_error_table_cnt).ship_model_id := l_line_tbl(i).ship_model_id;
479                     l_line_tbl.DELETE(i);
480                     l_trolin_val_tbl.DELETE(i);
481                  END IF;
482                END LOOP;
483                FND_MSG_PUB.Count_And_Get(p_encoded => 'T', p_count => l_msgcnt, p_data  => l_msg_data);
484                IF (l_debug = 1) THEN
485                   print_debug('Msg count: ' || l_msgcnt, 'RELEASE_PICK_BATCH');
486                   print_debug('WIP err table count: ' || l_wip_error_table.count, 'RELEASE_PICK_BATCH');
487                END IF;
488                FOR  x IN 1..l_msgcnt LOOP
489                    IF (l_debug = 1) THEN
490                       print_debug('Msg number: ' || x, 'RELEASE_PICK_BATCH');
491                    END IF;
492                    l_msg_data  := fnd_msg_pub.get(x, 'F');
493                    IF (l_debug = 1) THEN
494                       print_debug('Error message: ' || l_msg_data, 'RELEASE_PICK_BATCH');
495                    END IF;
496                    IF (l_debug = 1) THEN
497                       print_debug('  Errored Line Details wip_entity_id ='||l_wip_error_table(x).txn_source_id||
498                                   ', operation_sec_num ='||l_wip_error_table(x).txn_source_line_id||
499                                   ', inventory_item_id ='||l_wip_error_table(x).inventory_item_id,
500                                   'RELEASE_PICK_BATCH');
501                    END IF;
502                    IF l_msgcnt = l_wip_err_count THEN
503                       l_wip_error_table(l_err_start_index + x).error_message := l_msg_data;
504                    END IF;
505                END LOOP;
506              ELSE
507                IF (l_debug = 1) THEN
508                   print_debug('Conc_mode is False', 'RELEASE_PICK_BATCH');
509                END IF;
510                RAISE fnd_api.g_exc_unexpected_error;
511             END IF;
512          ELSE
513             IF (l_debug = 1) THEN
514                print_debug('Created MO Lines successfully', 'RELEASE_PICK_BATCH');
515             END IF;
516          END IF;
517 
518          IF (l_debug = 1) THEN
519             print_debug('MO line creation complete, before calling pick release..',
520                         'RELEASE_PICK_BATCH');
521          END IF;
522 
523          IF p_auto_detail_flag = fnd_api.g_true AND l_line_tbl.COUNT > 0 THEN
524             IF (l_debug = 1) THEN
525                print_debug('Calling pick_release', 'RELEASE_PICK_BATCH');
526             END IF;
527             l_api_return_status := fnd_api.g_ret_sts_success;
528             pick_release(
529               x_return_status      => l_api_return_status
530             , x_msg_count          => x_msg_count
531             , x_msg_data           => x_msg_data
532             , p_commit             => l_commit
533             , p_init_msg_lst       => fnd_api.g_true
534             , p_mo_line_tbl        => l_line_tbl
535             , p_allow_partial_pick => p_allow_partial_pick
536             , p_grouping_rule_id   => p_mo_header_rec.grouping_rule_id
537             , p_plan_tasks         => p_plan_tasks
538             , p_call_wip_api       => TRUE
539             );
540 
541             IF l_api_return_status <> fnd_api.g_ret_sts_success THEN
542                IF (l_debug = 1) THEN
543                   print_debug('Error occurred in Pick_Release', 'RELEASE_PICK_BATCH');
544                END IF;
545                RAISE fnd_api.g_exc_unexpected_error;
546             END IF;
547          END IF; -- end if auto detail flag is true
548 
549          COMMIT;
550          l_savept_exists := FALSE;
551 
552          l_counter := l_last_batch_rec + 1;
553          l_line_tbl.DELETE;
554          inv_quantity_tree_pvt.clear_quantity_cache;
555        END LOOP;
556     ELSE
557        -- WIP is 11.5.8 or lower
558        l_line_tbl := p_mo_line_rec_tbl;
559 
560        FOR ii IN l_line_tbl.FIRST..l_line_tbl.LAST
561        LOOP
562            l_line_tbl(ii).header_id := p_mo_header_rec.header_id;
563            l_line_tbl(ii).line_number := ii;
564        END LOOP;
565 
566        inv_move_order_pub.create_move_order_lines(
567          p_api_version_number  => l_api_version_number
568        , p_init_msg_list       => fnd_api.g_false
569        , p_return_values       => fnd_api.g_true
570        , p_commit              => l_commit
571        , x_return_status       => l_api_return_status
572        , x_msg_count           => x_msg_count
573        , x_msg_data            => x_msg_data
574        , p_trolin_tbl          => l_line_tbl
575        , p_trolin_val_tbl      => l_trolin_val_tbl
576        , x_trolin_tbl          => l_line_tbl
577        , x_trolin_val_tbl      => l_trolin_val_tbl
578        );
579 
580        IF l_api_return_status <> FND_API.G_RET_STS_SUCCESS THEN
581           print_debug ('Error occurred in INV_Move_Order_PUB.Create_Move_Order_Lines', 'RELEASE_PICK_BATCH');
582           RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
583        ELSE
584           print_debug ('Created MO Lines successfully', 'RELEASE_PICK_BATCH');
585        END IF;
586 
587        IF p_auto_detail_flag = FND_API.G_TRUE THEN
588           pick_release(
589             x_return_status       => l_api_return_status
590           , x_msg_count           => x_msg_count
591           , x_msg_data            => x_msg_data
592           , p_commit              => l_commit
593           , p_init_msg_lst        => fnd_api.g_false
594           , p_mo_line_tbl         => l_line_tbl
595           , p_allow_partial_pick  => p_allow_partial_pick
596           , p_grouping_rule_id    => NULL
597           , p_plan_tasks          => p_plan_tasks
598           , p_call_wip_api        => TRUE
599           );
600 
601           IF l_api_return_status <> FND_API.G_RET_STS_SUCCESS AND
602              l_api_return_status <> 'P'  THEN
603              print_debug ('Error occurred in Pick_Release', 'RELEASE_PICK_BATCH');
604              RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
605           ELSIF l_api_return_status = 'P' THEN
606              print_debug ('One or more lines failed to allocate fully', 'RELEASE_PICK_BATCH');
607              x_return_status := 'P';
608           ELSE
609              print_debug ('Pick Release successful.', 'RELEASE_PICK_BATCH');
610           END IF;
611        END IF; -- end if auto detail flag is true
612     END IF; -- end if wip patch level >= 1159
613 
614     l_mo_allocation_status := get_mo_alloc_stat();
615     g_mo_line_stat_tbl.DELETE;
616     g_mol_fail_count := 0;
617 
618     IF NOT l_savept_exists THEN
619        SAVEPOINT inv_wip_pick_release;
620        l_savept_exists := TRUE;
621     END IF;
622 
623     -- Printing the Pick Slip
624     IF p_print_pick_slip = FND_API.G_TRUE AND l_mo_allocation_status <> g_not_allocated THEN
625        x_conc_req_id := inv_pr_pick_slip_number.print_pick_slip(
626                           x_return_status      => l_api_return_status
627                         , x_msg_data           => x_msg_data
628                         , x_msg_count          => x_msg_count
629                         , p_organization_id    => l_organization_id
630                         , p_mo_request_number  => p_mo_header_rec.request_number
631                         , p_plan_tasks         => p_plan_tasks
632                         );
633 
634        IF l_api_return_status <> fnd_api.g_ret_sts_success THEN
635           IF (l_debug = 1) THEN
636              print_debug('Unable to submit Pick Slip Report Request','RELEASE_PICK_BATCH');
637           END IF;
638           RAISE fnd_api.g_exc_unexpected_error;
639        END IF;
640        IF (l_debug = 1) THEN
641           print_debug('Pick Slip Report Request ID = ' || x_conc_req_id,'RELEASE_PICK_BATCH');
642        END IF;
643     END IF;
644 
645     -- Delete the pick slip number cache if WIP patch level is 11.5.9 or higher
646     IF g_wip_patch_level >= 1159 THEN
647        inv_pr_pick_slip_number.delete_wip_ps_tbl;
648     END IF;
649 
650     IF l_is_wms_org THEN
651       --
652       -- Call Device Integration API to send the details of this
653       -- Pick Release Wave to devices, based on configuration.
654       -- All the Move Order Lines should have the same MO Header ID.
655       -- So using the FIRST line's Header ID.
656       -- Note: We don't check for the return condition of this API as
657       -- we let the Pick Release process to complete whether or not
658       -- Device Integration succeeds.
659       --
660       wms_device_integration_pvt.device_request(
661         p_bus_event      => wms_device_integration_pvt.wms_be_pick_release
662       , p_call_ctx       => wms_device_integration_pvt.dev_req_user
663       , p_task_trx_id    => p_mo_header_rec.header_id
664       , x_request_msg    => l_req_msg
665       , x_return_status  => l_api_return_status
666       , x_msg_count      => x_msg_count
667       , x_msg_data       => x_msg_data
668       );
669       IF (l_debug = 1) THEN
670          print_debug('Device_API Return Status = '|| l_api_return_status ||
671                      ' : Request Msg = ' || l_req_msg, 'RELEASE_PICK_BATCH');
672       END IF;
673     END IF;
674 
675     -- Standard call to commit
676     IF p_commit = fnd_api.g_true THEN
677        COMMIT;
678        l_savept_exists := FALSE;
679     END IF;
680 
681     x_return_status := l_mo_allocation_status;
682 
683     -- Bug 4288399, returning the table of errored records back to the calling program.
684     x_mo_line_errrec_tbl := l_wip_error_table;
685 
686   EXCEPTION
687     WHEN OTHERS THEN
688       x_return_status  := fnd_api.g_ret_sts_error;
689       IF l_debug = 1 THEN
690          print_debug ('Release_pick_batch Error: ' || SQLERRM, 'RELEASE_PICK_BATCH');
691       END IF;
692       fnd_msg_pub.count_and_get( p_count => x_msg_count, p_data => x_msg_data, p_encoded => fnd_api.g_false);
693       IF (l_savept_exists) THEN
694          ROLLBACK TO inv_wip_pick_release;
695       END IF;
696       IF g_conc_mode THEN
697         l_temp  := fnd_concurrent.set_completion_status('ERROR', '');
698       END IF;
699   END release_pick_batch;
700 
701 
702 
703   PROCEDURE pick_release(
704     x_return_status       OUT  NOCOPY VARCHAR2
705   , x_msg_count           OUT  NOCOPY NUMBER
706   , x_msg_data            OUT  NOCOPY VARCHAR2
707   , p_commit              IN   VARCHAR2
708   , p_init_msg_lst        IN   VARCHAR2
709   , p_mo_line_tbl         IN   inv_move_order_pub.trolin_tbl_type
710   , p_allow_partial_pick  IN   VARCHAR2
711   , p_grouping_rule_id    IN   NUMBER
712   , p_plan_tasks          IN   BOOLEAN
713   , p_call_wip_api        IN   BOOLEAN
714   ) IS
715 
716     l_api_version_number     NUMBER   := 1.0;
717     l_line_index             NUMBER; -- The index of the line in the table being processed
718     l_mo_line                inv_move_order_pub.trolin_rec_type;
719     l_organization_id        NUMBER; -- The OrgID to use (based on the MO Lines Passed in).
720     l_mo_header_id           NUMBER; -- Move Order Header ID
721     l_mo_type                NUMBER; -- The type of the move order (Should be only 5)
722     l_mo_number              VARCHAR2(30); -- The move order number
723     l_api_return_status      VARCHAR2(1);
724     l_processed_row_count    NUMBER   := 0; -- The number of rows which have been processed.
725     l_detail_rec_count       NUMBER   := 0;
726     l_quantity               NUMBER;
727     l_transaction_quantity   NUMBER;
728     l_primary_quantity       NUMBER;
729     l_wip_alloc_qty          NUMBER;
730     l_line_status            NUMBER;
731     l_disable_cartonization  VARCHAR2(1);
732     l_wip_entity_name        VARCHAR2(240);
733     l_item_number            VARCHAR2(40);
734 
735     -- Used for processing WIP pick sets (ship_set_id)
736     l_cur_ship_set_id        NUMBER   := NULL;
737     l_set_index              NUMBER;
738     l_start_index            NUMBER;
739     l_set_process            NUMBER;
740     l_start_process          NUMBER;
741 
742     l_tree_id                NUMBER;
743     l_revision_control_code  NUMBER;
744     l_lot_control_code       NUMBER;
745 
746     l_is_wms_org             BOOLEAN  := FALSE;
747 
748     TYPE quantity_tree_tbl_type IS TABLE OF NUMBER
749       INDEX BY BINARY_INTEGER;
750 
751     l_quantity_tree_tbl      quantity_tree_tbl_type;
752     l_qtree_backup_tbl       quantity_tree_tbl_type;
753 
754     l_debug number := NVL(FND_PROFILE.VALUE('INV_DEBUG_TRACE'),0);
755 
756     -- Bug 4349602: save all MOL IDs in current batch
757     TYPE l_molid_tbltyp IS TABLE OF NUMBER INDEX BY BINARY_INTEGER;
758     l_mol_id_tbl                  l_molid_tbltyp;
759     l_mol_id_index                NUMBER;
760 
761   BEGIN
762     -- Set savepoint for this API
763     IF (l_debug = 1) THEN
764        print_debug('Inside Pick_Release', 'PICK_RELEASE');
765     END IF;
766     SAVEPOINT pick_release;
767     -- Initialize API return status to success
768     x_return_status    := fnd_api.g_ret_sts_success;
769 
770     --  Initialize message list.
771     IF fnd_api.to_boolean(p_init_msg_lst) THEN
772       fnd_msg_pub.initialize;
773     END IF;
774 
775     --Added bug 4634522
776     IF (WIP_CONSTANTS.DMF_PATCHSET_LEVEL = WIP_CONSTANTS.DMF_PATCHSET_I_VALUE) THEN
777     	g_wip_patch_level := 1159;
778     ELSIF (WIP_CONSTANTS.DMF_PATCHSET_LEVEL = WIP_CONSTANTS.DMF_PATCHSET_J_VALUE) THEN
779       	g_wip_patch_level := 11510;
780     END IF;
781     --end of fix for  bug 4634522
782 
783     IF p_mo_line_tbl.COUNT = 0 THEN
784       IF (l_debug = 1) THEN
785          print_debug('No Lines to pick', 'PICK_RELEASE');
786       END IF;
787       fnd_message.set_name('INV', 'INV_NO_LINES_TO_PICK');
788       fnd_msg_pub.ADD;
789       RAISE fnd_api.g_exc_unexpected_error;
790     END IF;
791 
792     -- Bug 2038564: Clearing Qty Tree
793     inv_quantity_tree_pvt.clear_quantity_cache;
794 
795     -- Validate that all move order lines are from the same org, that all lines
796     -- have a status of pre-approved (7) or approved (3), and that all of the move
797     -- order lines are of type Manufacturing Component Pick (5)
798     l_line_index       := p_mo_line_tbl.FIRST;
799     l_mol_id_index     := 1;
800     l_organization_id  := p_mo_line_tbl(l_line_index).organization_id;
801     l_is_wms_org       := inv_install.adv_inv_installed(l_organization_id);
802 
803     --Bug 4288399, Printing Org ID as l_organization_id
804     IF (l_debug = 1) THEN
805        print_debug('MO Line count = ' || p_mo_line_tbl.COUNT ||
806                    ' : Org ID = '     || l_organization_id, 'PICK_RELEASE');
807     END IF;
808 
809     -- Bug 2666620: Moved it outside of LOOP so that it is done only once.
810     -- Verify that the move order type is of type Manufacturing Component Pick (5)
811     BEGIN
812        SELECT header_id, move_order_type, request_number
813          INTO l_mo_header_id, l_mo_type, l_mo_number
814         FROM mtl_txn_request_headers
815        WHERE header_id = p_mo_line_tbl(l_line_index).header_id;
816     EXCEPTION
817       WHEN NO_DATA_FOUND THEN
818         IF (l_debug = 1) THEN
819            print_debug('Error: Move Order Header not found', 'PICK_RELEASE');
820         END IF;
821         fnd_message.set_name('INV', 'INV_NO_HEADER_FOUND');
822         fnd_message.set_token('MO_LINE_ID', TO_CHAR(p_mo_line_tbl(l_line_index).line_id));
823         fnd_msg_pub.ADD;
824         RAISE fnd_api.g_exc_unexpected_error;
825     END;
826 
827     IF l_mo_type <> inv_globals.g_move_order_mfg_pick THEN
828       IF (l_debug = 1) THEN
829          print_debug('Error: Trying to release non WIP move order', 'PICK_RELEASE');
830       END IF;
831       fnd_message.set_name('INV', 'INV_NOT_WIP_MOVE_ORDER');
832       fnd_message.set_token('MO_NUMBER', l_mo_number);
833       fnd_msg_pub.ADD;
834       RAISE fnd_api.g_exc_unexpected_error;
835     END IF;
836 
837     LOOP
838       l_mo_line := p_mo_line_tbl(l_line_index);
839 
840       IF (l_mo_line.return_status NOT IN (fnd_api.g_ret_sts_unexp_error, fnd_api.g_ret_sts_error) ) THEN
841         -- Verify that the lines are all for the same organization
842         IF l_mo_line.organization_id <> l_organization_id THEN
843           IF (l_debug = 1) THEN
844              print_debug('Error: Trying to pick for different org', 'PICK_RELEASE');
845           END IF;
846           fnd_message.set_name('INV', 'INV_PICK_DIFFERENT_ORG');
847           fnd_msg_pub.ADD;
848           RAISE fnd_api.g_exc_unexpected_error;
849         END IF;
850 
851         -- Verify that the line status is approved or pre-approved
852         IF (l_mo_line.line_status NOT IN (3,7)) THEN
853           IF (l_debug = 1) THEN
854              print_debug('Error: Invalid Move Order Line Status', 'PICK_RELEASE');
855           END IF;
856           fnd_message.set_name('INV', 'INV_PICK_LINE_STATUS');
857           fnd_msg_pub.ADD;
858           RAISE fnd_api.g_exc_unexpected_error;
859         END IF;
860 
861         -- Carton Grouping ID has to be stamped.
862         -- Bug 2844622: Skip this check if WIP patch level is below 11.5.9
863         IF g_wip_patch_level >= 1159 THEN
864           IF (l_is_wms_org AND NVL(l_mo_line.carton_grouping_id, fnd_api.g_miss_num) = fnd_api.g_miss_num) THEN
865             IF (l_debug = 1) THEN
866                print_debug('Error: No Carton Grouping ID specified', 'PICK_RELEASE');
867             END IF;
868             fnd_message.set_name('WMS', 'WMS_NO_CARTON_GROUP_ID');
869             fnd_msg_pub.ADD;
870             RAISE fnd_api.g_exc_unexpected_error;
871           END IF;
872         ELSE
873           IF (l_debug = 1) THEN
874             print_debug('WIP Patch Level = ' || g_wip_patch_level ||' so skipping Carton Group ID check', 'PICK_RELEASE');
875            END IF;
876         END IF;
877         -- Bug 2666620: End of Code Changes
878         l_mol_id_tbl(l_mol_id_index) := l_mo_line.line_id;
879         l_mol_id_index := l_mol_id_index + 1;
880       END IF; -- end if MO line status is error
881 
882       -- We should create the quantity tree here so that we can
883       -- a) lock the tree
884       -- b) use the tree id to backup the quantity tree for ship
885       --    set and ship model id;
886       -- we only want to call create_tree once per org/item;
887       -- This should not be a performance hit as long as ARU
888       -- 1625268 has been applied.
889 
890       IF NOT (l_quantity_tree_tbl.EXISTS(l_mo_line.inventory_item_id)) THEN
891         IF (l_debug = 1) THEN
892            print_debug('Creating Qty Tree for Item '|| TO_CHAR(l_mo_line.inventory_item_id), 'PICK_RELEASE');
893         END IF;
894 
895         BEGIN
896           SELECT revision_qty_control_code, lot_control_code
897             INTO l_revision_control_code, l_lot_control_code
898             FROM mtl_system_items
899            WHERE organization_id = l_organization_id
900              AND inventory_item_id = l_mo_line.inventory_item_id;
901         EXCEPTION
902           WHEN NO_DATA_FOUND THEN
903             IF (l_debug = 1) THEN
904                print_debug('No Item Info found', 'PICK_RELEASE');
905             END IF;
906             RAISE fnd_api.g_exc_unexpected_error;
907         END;
908 
909         inv_quantity_tree_pvt.create_tree
910         ( p_api_version_number       => 1.0
911         , p_init_msg_lst             => fnd_api.g_false
912         , x_return_status            => l_api_return_status
913         , x_msg_count                => x_msg_count
914         , x_msg_data                 => x_msg_data
915         , p_organization_id          => l_organization_id
916         , p_inventory_item_id        => l_mo_line.inventory_item_id
917         , p_tree_mode                => inv_quantity_tree_pvt.g_transaction_mode
918         , p_is_revision_control      => (l_revision_control_code = 2)
919         , p_is_lot_control           => (l_lot_control_code = 2)
920         , p_is_serial_control        => FALSE
921         , p_asset_sub_only           => FALSE
922         , p_include_suggestion       => FALSE
923         , p_demand_source_type_id    => -99
924         , p_demand_source_header_id  => -99
925         , p_demand_source_line_id    => -99
926         , p_demand_source_delivery   => NULL
927         , p_demand_source_name       => NULL
928         , p_lot_expiration_date      => SYSDATE
929         , x_tree_id                  => l_tree_id
930         , p_exclusive                => inv_quantity_tree_pvt.g_exclusive
931         , p_pick_release             => inv_quantity_tree_pvt.g_pick_release_yes
932         );
933 
934         IF l_api_return_status = fnd_api.g_ret_sts_error THEN
935           RAISE fnd_api.g_exc_error;
936         ELSIF l_api_return_status = fnd_api.g_ret_sts_unexp_error THEN
937           RAISE fnd_api.g_exc_unexpected_error;
938         END IF;
939 
940         l_quantity_tree_tbl(l_mo_line.inventory_item_id)  := l_tree_id;
941       END IF; -- not exist in quantity tree tbl
942 
943       EXIT WHEN l_line_index = p_mo_line_tbl.LAST;
944       l_line_index := p_mo_line_tbl.NEXT(l_line_index);
945     END LOOP;
946 
947     IF (l_debug = 1) THEN
948        print_debug('Validations complete, starting pick release', 'PICK_RELEASE');
949     END IF;
950     l_line_index       := p_mo_line_tbl.FIRST;
951 
952     LOOP
953       l_mo_line     := p_mo_line_tbl(l_line_index);
954       IF (l_debug = 1) THEN
955          print_debug('Loop index: ' || TO_CHAR(l_line_index), 'PICK_RELEASE');
956          print_debug('MO line   : ' || TO_CHAR(l_mo_line.line_id), 'PICK_RELEASE');
957          print_debug('Item      : ' || TO_CHAR(l_mo_line.inventory_item_id), 'PICK_RELEASE');
958          print_debug('Quantity  : ' || TO_CHAR(l_mo_line.quantity), 'PICK_RELEASE');
959       END IF;
960 
961       IF (l_mo_line.return_status <> fnd_api.g_ret_sts_unexp_error
962           AND l_mo_line.return_status <> fnd_api.g_ret_sts_error)
963       THEN
964         IF  l_mo_line.ship_set_id IS NOT NULL
965             AND (l_cur_ship_set_id IS NULL OR l_cur_ship_set_id <> l_mo_line.ship_set_id)
966         THEN
967           SAVEPOINT shipset;
968           l_cur_ship_set_id  := l_mo_line.ship_set_id;
969           l_start_index      := l_line_index;
970           l_start_process    := l_processed_row_count;
971           l_qtree_backup_tbl.DELETE;
972           IF (l_debug = 1) THEN
973              print_debug('Start Pick Set: '|| TO_CHAR(l_cur_ship_set_id), 'PICK_RELEASE');
974           END IF;
975         ELSIF  l_cur_ship_set_id IS NOT NULL AND l_mo_line.ship_set_id IS NULL THEN
976           IF (l_debug = 1) THEN
977              print_debug('End of Shipset: '|| TO_CHAR(l_cur_ship_set_id), 'PICK_RELEASE');
978           END IF;
979           l_cur_ship_set_id  := NULL;
980           l_qtree_backup_tbl.DELETE;
981         END IF;
982 
983         IF  (l_mo_line.ship_set_id IS NOT NULL)
984             AND NOT (l_qtree_backup_tbl.EXISTS(l_mo_line.inventory_item_id)) THEN
985           IF (l_debug = 1) THEN
986              print_debug('Backing up qty tree: '|| TO_CHAR(l_tree_id), 'PICK_RELEASE');
987           END IF;
988           l_tree_id := l_quantity_tree_tbl(l_mo_line.inventory_item_id);
989           inv_quantity_tree_pvt.backup_tree(x_return_status => l_api_return_status, p_tree_id => l_tree_id);
990 
991           IF l_api_return_status = fnd_api.g_ret_sts_error THEN
992             RAISE fnd_api.g_exc_error;
993           ELSIF l_api_return_status = fnd_api.g_ret_sts_unexp_error THEN
994             RAISE fnd_api.g_exc_unexpected_error;
995           END IF;
996 
997           l_qtree_backup_tbl(l_mo_line.inventory_item_id)  := l_tree_id;
998         END IF; -- Pick set NOT NULL
999 
1000         -- Call the Pick Release Process_Line API on the current Move Order Line
1001         process_line(
1002           p_mo_line_rec         => l_mo_line
1003         , p_allow_partial_pick  => p_allow_partial_pick
1004         , p_grouping_rule_id    => p_grouping_rule_id
1005         , p_plan_tasks          => p_plan_tasks
1006         , p_call_wip_api        => p_call_wip_api   --Added bug 4634522
1007         , x_return_status       => l_api_return_status
1008         , x_msg_count           => x_msg_count
1009         , x_msg_data            => x_msg_data
1010         , x_detail_rec_count    => l_detail_rec_count
1011         );
1012         IF (l_debug = 1) THEN
1013            print_debug('Process Line Return Status = '|| l_api_return_status ||
1014                        ' : Detail Rec Count = ' || to_char(l_detail_rec_count), 'PICK_RELEASE');
1015         END IF;
1016 
1017         IF l_api_return_status <> fnd_api.g_ret_sts_success AND p_allow_partial_pick = fnd_api.g_false THEN
1018            fnd_message.set_name('INV', 'INV_COULD_NOT_PICK_FULL');
1019            fnd_msg_pub.ADD;
1020            RAISE fnd_api.g_exc_unexpected_error;
1021         END IF;
1022 
1023         g_mo_line_stat_tbl(l_mo_line.line_id) := l_api_return_status;
1024 
1025         SELECT quantity, line_status
1026           INTO l_quantity, l_line_status
1027           FROM mtl_txn_request_lines
1028          WHERE line_id = l_mo_line.line_id;
1029 
1030         SELECT NVL(SUM(transaction_quantity), 0), NVL(SUM(primary_quantity), 0)
1031           INTO l_transaction_quantity, l_primary_quantity
1032           FROM mtl_material_transactions_temp
1033          WHERE move_order_line_id = l_mo_line.line_id;
1034 
1035         -- If the total allocated quantity is less than the requested
1036         -- quantity update the move order line to change the
1037         -- requested quantity to be equal to the allocated quantity.
1038 
1039         IF (l_transaction_quantity < l_quantity)
1040            OR (l_transaction_quantity = 0 AND l_quantity = 0) THEN
1041           -- For shipsets, if any of the lines fail to allocate completely,
1042           -- rollback all allocations
1043 
1044           IF l_cur_ship_set_id IS NOT NULL THEN
1045             IF (l_debug = 1) THEN
1046                print_debug('Rollback for pick set: '|| TO_CHAR(l_cur_ship_set_id), 'PICK_RELEASE');
1047             END IF;
1048             ROLLBACK TO shipset;
1049             l_set_index             := l_start_index;
1050             l_set_process           := l_start_process;
1051 
1052             -- loop through all move order lines for this ship set
1053             LOOP
1054               l_mo_line      := p_mo_line_tbl(l_set_index);
1055               IF (l_debug = 1) THEN
1056                  print_debug(TO_CHAR(l_set_process) || ' Rolling back allocations for MO line: '
1057                              ||TO_CHAR(l_mo_line.line_id), 'PICK_RELEASE');
1058               END IF;
1059 
1060               g_mo_line_stat_tbl(l_mo_line.line_id) := g_not_allocated;
1061 
1062               IF l_qtree_backup_tbl.EXISTS(l_mo_line.inventory_item_id) THEN
1063                 l_tree_id  := l_qtree_backup_tbl(l_mo_line.inventory_item_id);
1064                 IF (l_debug = 1) THEN
1065                    print_debug('Restoring Quantity Tree: '|| TO_CHAR(l_tree_id), 'PICK_RELEASE');
1066                 END IF;
1067 
1068                 inv_quantity_tree_pvt.restore_tree
1069                 ( x_return_status => l_api_return_status
1070                 , p_tree_id       => l_tree_id
1071                 );
1072 
1073                 IF (l_api_return_status = fnd_api.g_ret_sts_error) THEN
1074                   IF (l_debug = 1) THEN
1075                      print_debug('Error in Restore_Tree', 'Pick_Release');
1076                   END IF;
1077                   RAISE fnd_api.g_exc_error;
1078                 ELSIF l_api_return_status = fnd_api.g_ret_sts_unexp_error THEN
1079                   IF (l_debug = 1) THEN
1080                      print_debug('Unexpected error in Restore_tree', 'PICK_RELEASE');
1081                   END IF;
1082                   RAISE fnd_api.g_exc_unexpected_error;
1083                 END IF;
1084 
1085                 -- delete entry, so we don't restore tree more than once
1086                 l_qtree_backup_tbl.DELETE(l_mo_line.inventory_item_id);
1087               END IF;
1088 
1089               -- close the move order line
1090               UPDATE mtl_txn_request_lines
1091                  SET quantity = 0, quantity_detailed = 0, line_status = 5
1092                WHERE line_id = l_mo_line.line_id;
1093 
1094               -- Exit if there are no more move order lines to detail
1095               -- or when the next move order is not for the same ship set.
1096               -- l_set_index should always be equal to the last line
1097               -- in the current ship set, so that the logic at the
1098               -- end of the outer loop works correctly.
1099               EXIT WHEN p_mo_line_tbl.LAST = l_set_index;
1100               l_set_index    := p_mo_line_tbl.NEXT(l_set_index);
1101 
1102               IF NVL(p_mo_line_tbl(l_set_index).ship_set_id, -1) <> l_cur_ship_set_id THEN
1103                 l_set_index  := p_mo_line_tbl.PRIOR(l_set_index);
1104                 EXIT;
1105               END IF;
1106 
1107               l_set_process  := l_set_process + 1;
1108             END LOOP;
1109 
1110             -- At the end of this loop, l_mo_line and l_set_index
1111             -- point to the last line for this ship set.
1112             l_line_index            := l_set_index;
1113             l_cur_ship_set_id       := NULL;
1114             l_processed_row_count   := l_set_process;
1115             l_detail_rec_count      := 0;
1116 
1117             --
1118             -- Bug 2501138:
1119             -- Set txn qty to 0, so that we don't invoke
1120             -- wip_picking_pub.allocate_material
1121             --
1122             l_transaction_quantity  := 0;
1123             l_primary_quantity      := 0;
1124             l_qtree_backup_tbl.DELETE;
1125             IF (l_debug = 1) THEN
1126                print_debug('Finished rolling back all lines in shipset', 'PICK_RELEASE');
1127             END IF;
1128           ELSE
1129             UPDATE mtl_txn_request_lines
1130                SET quantity = l_transaction_quantity
1131              WHERE line_id = l_mo_line.line_id;
1132 
1133             IF (l_transaction_quantity = 0) THEN
1134               UPDATE mtl_txn_request_lines
1135                  SET line_status = 5
1136                WHERE line_id = l_mo_line.line_id;
1137             END IF;
1138           END IF; -- cur ship set id
1139         END IF; -- transaction quantity < quantity or transaction quantity is 0
1140 
1141 
1142         l_processed_row_count  := l_processed_row_count + 1;
1143         IF (l_debug = 1) THEN
1144            print_debug('Processed row : ' || TO_CHAR(l_processed_row_count), 'PICK_RELEASE');
1145            print_debug('MO line ID    : ' || TO_CHAR(l_mo_line.line_id), 'PICK_RELEASE');
1146            print_debug('Return Status : ' || l_api_return_status, 'PICK_RELEASE');
1147            print_debug('Dtl rec count : ' || TO_CHAR(l_detail_rec_count), 'PICK_RELEASE');
1148         END IF;
1149 
1150         l_detail_rec_count     := 0;
1151 
1152         -- Update WIP with allocated qty if alloc qty > 0
1153         IF p_call_wip_api AND l_transaction_quantity > 0 THEN
1154           IF (l_debug = 1) THEN
1155              print_debug('Updating WIP with Allocated Qty: '|| l_primary_quantity, 'PICK_RELEASE');
1156           END IF;
1157           wip_picking_pub.allocate_material(
1158             p_wip_entity_id           => l_mo_line.txn_source_id
1159           , p_operation_seq_num       => l_mo_line.txn_source_line_id
1160           , p_inventory_item_id       => l_mo_line.inventory_item_id
1161           , p_repetitive_schedule_id  => l_mo_line.reference_id
1162           , p_primary_quantity        => l_primary_quantity
1163           , x_quantity_allocated      => l_wip_alloc_qty
1164           , x_return_status           => l_api_return_status
1165           , x_msg_data                => x_msg_data
1166           );
1167 
1168           IF l_api_return_status <> fnd_api.g_ret_sts_success THEN
1169             IF (l_debug = 1) THEN
1170                print_debug('Error in wip_picking_pub.allocate_material', 'PICK_RELEASE');
1171                print_debug('WIP entity ID: ' || TO_CHAR(l_mo_line.txn_source_id), 'PICK_RELEASE');
1172                print_debug('Op seq num   : ' || TO_CHAR(l_mo_line.txn_source_line_id), 'PICK_RELEASE');
1173                print_debug('Rep sch ID   : ' || TO_CHAR(l_mo_line.reference_id), 'PICK_RELEASE');
1174                print_debug('Item ID      : ' || TO_CHAR(l_mo_line.inventory_item_id), 'PICK_RELEASE');
1175             END IF;
1176             RAISE fnd_api.g_exc_error;
1177           END IF;
1178         END IF;
1179       END IF; -- mo line return status <> ERROR
1180 
1181       EXIT WHEN l_line_index = p_mo_line_tbl.LAST;
1182       l_line_index  := p_mo_line_tbl.NEXT(l_line_index);
1183     END LOOP; -- end looping through MO lines
1184 
1185     IF (l_debug = 1) THEN
1186        print_debug('Done looping through MO lines', 'PICK_RELEASE');
1187     END IF;
1188 
1189     -- Bug 4349602: Deleting Move Order Lines which are not allocated
1190     BEGIN
1191        IF (l_debug = 1) THEN
1192           print_debug('Deleting closed MOLs..','PICK_RELEASE');
1193        END IF;
1194        FORALL ii IN l_mol_id_tbl.FIRST..l_mol_id_tbl.LAST
1195           DELETE FROM mtl_txn_request_lines  mtrl
1196            WHERE line_status = 5
1197              AND line_id = l_mol_id_tbl(ii);
1198     EXCEPTION
1199       WHEN OTHERS THEN
1200         IF (l_debug = 1) THEN
1201            print_debug('Error in Deleting Move Order Lines: ' || sqlerrm
1202                       ,'PICK_RELEASE');
1203         END IF;
1204         RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
1205     END;
1206 
1207     IF l_is_wms_org THEN
1208       -- Call cartonization API to assign task types and split and merge tasks.
1209       -- Bug 2666620: Cartonization is not disabled and Packaging Mode is set
1210       IF (l_debug = 1) THEN
1211          print_debug('Calling Cartonization Engine', 'PICK_RELEASE');
1212       END IF;
1213 
1214       -- Bug 2844622: Disable cartonization if WIP patch level is below 11.5.9
1215       IF g_wip_patch_level >= 1159 THEN
1216          l_disable_cartonization := 'N';
1217       ELSE
1218          l_disable_cartonization := 'Y';
1219       END IF;
1220 
1221       wms_cartnzn_wrap.cartonize
1222       ( p_api_version            => l_api_version_number
1223       , p_init_msg_list          => fnd_api.g_false
1224       , p_commit                 => fnd_api.g_false
1225       , p_validation_level       => fnd_api.g_valid_level_full
1226       , x_return_status          => l_api_return_status
1227       , x_msg_count              => x_msg_count
1228       , x_msg_data               => x_msg_data
1229       , p_out_bound              => 'Y'
1230       , p_org_id                 => l_organization_id
1231       , p_move_order_header_id   => l_mo_header_id
1232       , p_disable_cartonization  => l_disable_cartonization
1233       , p_packaging_mode         => wms_cartnzn_wrap.mfg_pr_pkg_mode
1234       );
1235 
1236       IF l_api_return_status <> fnd_api.g_ret_sts_success THEN
1237         IF (l_debug = 1) THEN
1238            print_debug('Cartonization returned with an error status: '||l_api_return_status, 'Pick_Release');
1239         END IF;
1240         RAISE fnd_api.g_exc_unexpected_error;
1241       END IF;
1242     END IF;
1243 
1244     -- Standard call to commit
1245     IF p_commit = fnd_api.g_true THEN
1246       COMMIT;
1247     END IF;
1248 
1249     IF (l_debug = 1) THEN
1250        print_debug('x_return_status = '|| x_return_status, 'PICK_RELEASE');
1251     END IF;
1252 
1253   EXCEPTION
1254     WHEN fnd_api.g_exc_error THEN
1255       ROLLBACK TO pick_release;
1256       inv_quantity_tree_pvt.clear_quantity_cache;
1257       x_return_status  := fnd_api.g_ret_sts_error;
1258       fnd_msg_pub.count_and_get(p_count => x_msg_count, p_data => x_msg_data, p_encoded => fnd_api.g_false);
1259     WHEN OTHERS THEN
1260       ROLLBACK TO pick_release;
1261       inv_quantity_tree_pvt.clear_quantity_cache;
1262       x_return_status  := fnd_api.g_ret_sts_unexp_error;
1263       fnd_msg_pub.count_and_get(p_count => x_msg_count, p_data => x_msg_data, p_encoded => fnd_api.g_false);
1264   END pick_release;
1265 
1266 
1267 
1268   --
1269   -- Name
1270   --   PROCEDURE Process_Line
1271   --
1272   -- Package
1273   --   INV_Pick_Release_PVT
1274   --
1275   -- Purpose
1276   --   Pick releases the move order line passed in.  Any necessary validation is
1277   --   assumed to have been done by the caller.
1278   --
1279   -- Input Parameters
1280   --   p_mo_line_rec
1281   --       The Move Order Line record to pick release
1282   --   p_allow_partial_pick
1283   --       TRUE if the pick release process should continue after a line fails to
1284   --       be detailed completely.
1285   --       FALSE if the process should stop and roll back all changes if a line
1286   --       cannot be fully detailed.
1287   --
1288   -- Output Parameters
1289   --   x_return_status
1290   --       if the process succeeds, the value is
1291   --   FND_API.G_RET_STS_SUCCESS;
1292   --       if there is an expected error, the value is
1293   --             fnd_api.g_ret_sts_error;
1294   --       if there is an unexpected error, the value is
1295   --             fnd_api.g_ret_sts_unexp_error;
1296   --   x_msg_count
1297   --       if there is one or more errors, the number of error messages
1298   --        in the buffer
1299   --   x_msg_data
1300   --       if there is one and only one error, the error message
1301   --
1302   -- (See FND_API package for more details about the above output parameters)
1303   --
1304 
1305   PROCEDURE process_line
1306   ( p_mo_line_rec        IN OUT NOCOPY inv_move_order_pub.trolin_rec_type
1307   , p_allow_partial_pick IN     VARCHAR2 DEFAULT fnd_api.g_true
1308   , p_grouping_rule_id   IN     NUMBER
1309   , p_plan_tasks         IN     BOOLEAN
1310   , p_call_wip_api       IN     BOOLEAN     --Added bug 4634522
1311   , x_return_status      OUT    NOCOPY  VARCHAR2
1312   , x_msg_count          OUT    NOCOPY  NUMBER
1313   , x_msg_data           OUT    NOCOPY  VARCHAR2
1314   , x_detail_rec_count   OUT    NOCOPY  NUMBER
1315   ) IS
1316     -- Empty record for calling Create_Suggestions
1317     l_demand_rsvs_ordered    inv_reservation_global.mtl_reservation_tbl_type;
1318     l_request_number         NUMBER; -- MO Header number
1319     l_primary_uom            VARCHAR2(3); -- The primary UOM for the item
1320     l_quantity_detailed      NUMBER; -- The quantity for the current MO which was detailed in Primary UOM
1321     l_num_detail_recs        NUMBER; -- The number of MO Line details for this MO Line.
1322     l_mol_allocation_status  VARCHAR2(1); -- A flag indicating the status of the MOL Allocation.
1323     l_quantity_detailed_conv NUMBER; -- The quantity detailed for the current MO in UOM of MO
1324     l_api_return_status      VARCHAR2(1); -- The return status of APIs called within the Process Line API.
1325     l_count                  NUMBER;
1326     l_message                VARCHAR2(255);
1327     l_allocate_quantity      NUMBER;
1328     l_use_pick_set_flag      VARCHAR2(1);
1329 
1330     l_debug number := NVL(FND_PROFILE.VALUE('INV_DEBUG_TRACE'),0);
1331   BEGIN
1332     IF (l_debug = 1) THEN
1333        print_debug('Inside Process_Line', 'PROCESS_LINE');
1334        print_debug('WIP Entity ID: '|| TO_CHAR(p_mo_line_rec.txn_source_id), 'PROCESS_LINE');
1335        print_debug('Op seq num   : '|| TO_CHAR(p_mo_line_rec.txn_source_line_id), 'PROCESS_LINE');
1336        print_debug('Rep sch ID   : '|| TO_CHAR(p_mo_line_rec.reference_id), 'PROCESS_LINE');
1337        print_debug('Item ID      : '|| TO_CHAR(p_mo_line_rec.inventory_item_id), 'PROCESS_LINE');
1338        print_debug('MO line ID   : '|| TO_CHAR(p_mo_line_rec.line_id), 'PROCESS_LINE');
1339        print_debug('Unit num     : '|| p_mo_line_rec.unit_number, 'PROCESS_LINE');
1340        print_debug('Project ID   : '|| TO_CHAR(p_mo_line_rec.project_id), 'PROCESS_LINE');
1341        print_debug('Task ID      : '|| TO_CHAR(p_mo_line_rec.task_id), 'PROCESS_LINE');
1342     END IF;
1343     SAVEPOINT process_line_pvt;
1344     x_detail_rec_count  := 0;
1345     l_num_detail_recs   := 0;
1346     -- Initialize API return status to success
1347     x_return_status     := fnd_api.g_ret_sts_success;
1348 
1349     -- Bug 4880578: return if MO line has 0 qty
1350     IF NVL(p_mo_line_rec.quantity,0) = 0 THEN
1351        IF (l_debug = 1) THEN
1352           print_debug('MO line has 0 qty: '||p_mo_line_rec.quantity,'PROCESS_LINE');
1353        END IF;
1354        x_return_status := g_not_allocated;
1355        RETURN;
1356     END IF;
1357 
1358     l_allocate_quantity := nvl(p_mo_line_rec.quantity,0)
1359                            - nvl(p_mo_line_rec.quantity_detailed, 0);
1360 
1361     IF (l_debug = 1) THEN
1362        print_debug('Quantity to detail: '||l_allocate_quantity,'PROCESS_LINE');
1363     END IF;
1364 
1365     -- Return success immediately if the line is already fully detailed
1366     IF l_allocate_quantity <= 0 THEN
1367        IF (l_debug = 1) THEN
1368           print_debug('MO line is already fully detailed', 'PROCESS_LINE');
1369        END IF;
1370        RETURN;
1371     END IF;
1372 
1373     IF p_mo_line_rec.ship_set_id IS NOT NULL THEN
1374       l_use_pick_set_flag := 'Y';
1375     ELSE
1376       l_use_pick_set_flag := 'N';
1377     END IF;
1378 
1379     -- Bug 2844622: Skip this callback if WIP patch level is below 11.5.9
1380     IF g_wip_patch_level >= 1159 AND p_call_wip_api THEN -- bug 4634522.Added p_call_wip_api
1381        --calling WIP callback API
1382        IF (l_debug = 1) THEN
1383           print_debug('Calling pre_allocate_material', 'PROCESS_LINE');
1384        END IF;
1385 
1386        wip_picking_pub.pre_allocate_material
1387        ( p_wip_entity_id          => p_mo_line_rec.txn_source_id
1388        , p_operation_seq_num      => p_mo_line_rec.txn_source_line_id
1389        , p_inventory_item_id      => p_mo_line_rec.inventory_item_id
1390        , p_repetitive_schedule_id => p_mo_line_rec.reference_id
1391        , p_use_pickset_flag       => l_use_pick_set_flag
1392        , p_allocate_quantity      => l_allocate_quantity
1393        , x_return_status          => l_api_return_status
1394        , x_msg_data               => x_msg_data
1395        );
1396        IF l_api_return_status <> fnd_api.g_ret_sts_success THEN
1397          IF (l_debug = 1) THEN
1398             print_debug('Error in pre_allocate_material','PROCESS_LINE');
1399          END IF;
1400          RAISE fnd_api.g_exc_unexpected_error;
1401        END IF;
1402     ELSE
1403        IF (l_debug = 1) THEN
1404           print_debug('WIP Patch Level = ' || g_wip_patch_level || ', so skipping pre_allocate_material', 'PROCESS_LINE');
1405        END IF;
1406     END IF;
1407 
1408     IF (l_debug = 1) THEN
1409        print_debug('Calling Create Suggestions for MOLine: '|| p_mo_line_rec.line_id, 'PROCESS_LINE');
1410     END IF;
1411     inv_ppengine_pvt.create_suggestions
1412     ( p_api_version          => 1.0
1413     , p_init_msg_list        => fnd_api.g_false
1414     , p_commit               => fnd_api.g_false
1415     , x_return_status        => l_api_return_status
1416     , x_msg_count            => x_msg_count
1417     , x_msg_data             => x_msg_data
1418     , p_transaction_temp_id  => p_mo_line_rec.line_id
1419     , p_reservations         => l_demand_rsvs_ordered
1420     , p_suggest_serial       => 'T'
1421     , p_plan_tasks           => p_plan_tasks
1422     );
1423 
1424     IF l_api_return_status <> fnd_api.g_ret_sts_success THEN
1425       IF (l_debug = 1) THEN
1426          print_debug('Ret stat: '|| l_api_return_status || ', INV detailing failed', 'PROCESS_LINE');
1427       END IF;
1428       fnd_msg_pub.count_and_get(p_count => l_count, p_data => l_message, p_encoded => 'F');
1429 
1430       IF (l_count = 0) THEN
1431         IF (l_debug = 1) THEN
1432            print_debug('No message from detailing engine', 'PROCESS_LINE');
1433         END IF;
1434       ELSIF (l_count = 1) THEN
1435         IF (l_debug = 1) THEN
1436            print_debug(l_message, 'PROCESS_LINE');
1437         END IF;
1438       ELSE
1439         FOR i IN 1 .. l_count LOOP
1440           l_message  := fnd_msg_pub.get(i, 'F');
1441           IF (l_debug = 1) THEN
1442              print_debug(l_message, 'PROCESS_LINE');
1443           END IF;
1444         END LOOP;
1445 
1446         fnd_msg_pub.delete_msg();
1447       END IF;
1448 
1449       BEGIN
1450         SELECT request_number
1451           INTO l_request_number
1452           FROM mtl_txn_request_lines_v
1453          WHERE line_id = p_mo_line_rec.line_id;
1454       EXCEPTION
1455         WHEN NO_DATA_FOUND THEN
1456           RAISE fnd_api.g_exc_unexpected_error;
1457       END;
1458 
1459       fnd_message.set_name('INV', 'INV_DETAILING_FAILED');
1460       fnd_message.set_token('LINE_NUM', TO_CHAR(p_mo_line_rec.line_number));
1461       fnd_message.set_token('MO_NUMBER', l_request_number);
1462       fnd_msg_pub.ADD;
1463       RAISE fnd_api.g_exc_unexpected_error;
1464     END IF;
1465 
1466     IF (l_debug = 1) THEN
1467        print_debug('After calling Create Suggestions: Ret Status = '|| l_api_return_status, 'PROCESS_LINE');
1468     END IF;
1469 
1470     -- Update the detailed quantity (and if possible, the sourcing information)
1471     SELECT NVL(SUM(primary_quantity), 0), COUNT(*)
1472       INTO l_quantity_detailed, l_num_detail_recs
1473       FROM mtl_material_transactions_temp
1474      WHERE move_order_line_id = p_mo_line_rec.line_id;
1475 
1476     IF (l_debug = 1) THEN
1477       print_debug('Qty detailed = '|| l_quantity_detailed || ' : Num of Details = ' || l_num_detail_recs, 'PROCESS_LINE');
1478     END IF;
1479 
1480     -- If the move order line is not fully detailed, update the return status as appropriate.
1481     IF l_quantity_detailed < p_mo_line_rec.primary_quantity AND p_allow_partial_pick = fnd_api.g_false THEN
1482       fnd_message.set_name('INV', 'INV_COULD_NOT_PICK_FULL');
1483       fnd_msg_pub.ADD;
1484       RAISE fnd_api.g_exc_unexpected_error;
1485     END IF;
1486 
1487     IF (l_num_detail_recs = 0) THEN
1488       p_mo_line_rec.quantity_detailed  := NVL(l_quantity_detailed, 0) + NVL(p_mo_line_rec.quantity_delivered, 0);
1489       IF (l_debug = 1) THEN
1490          print_debug('Updating Move Order Line', 'PROCESS_LINE');
1491       END IF;
1492       inv_trolin_util.update_row(p_mo_line_rec);
1493       l_mol_allocation_status := g_not_allocated;
1494     ELSIF l_num_detail_recs > 0 THEN
1495       IF l_quantity_detailed < p_mo_line_rec.primary_quantity THEN
1496          l_mol_allocation_status := g_partially_allocated;
1497       ELSE
1498          l_mol_allocation_status := g_completely_allocated;
1499       END IF;
1500       -- Calculate the quantity detailed in the UOM of the move order line
1501       SELECT primary_uom_code INTO l_primary_uom
1502         FROM mtl_system_items
1503        WHERE organization_id = p_mo_line_rec.organization_id
1504          AND inventory_item_id = p_mo_line_rec.inventory_item_id;
1505 
1506       IF (l_primary_uom <> p_mo_line_rec.uom_code) THEN
1507         l_quantity_detailed_conv  := inv_convert.inv_um_convert
1508                                      ( item_id        => p_mo_line_rec.inventory_item_id
1509                                      , PRECISION      => NULL
1510                                      , from_quantity  => l_quantity_detailed
1511                                      , from_unit      => l_primary_uom
1512                                      , to_unit        => p_mo_line_rec.uom_code
1513                                      , from_name      => NULL
1514                                      , to_name        => NULL
1515                                      );
1516         IF (l_debug = 1) THEN
1517            print_debug('After calling convert', 'PROCESS_LINE');
1518         END IF;
1519 
1520         -- Update the Move Order Line with the quantity which was detailed.
1521         IF (l_quantity_detailed_conv = -99999) THEN
1522           fnd_message.set_name('INV', 'INV-CANNOT CONVERT');
1523           fnd_message.set_token('UOM', p_mo_line_rec.uom_code);
1524           fnd_message.set_token('ROUTINE', 'Pick Release process');
1525           fnd_msg_pub.ADD;
1526           RAISE fnd_api.g_exc_unexpected_error;
1527         END IF;
1528       ELSE
1529         l_quantity_detailed_conv  := l_quantity_detailed;
1530       END IF;
1531 
1532       -- bug 4634522 .begin
1533       IF (l_mol_allocation_status = g_partially_allocated) THEN
1534 	IF (l_debug = 1) THEN
1535          print_debug('  p_mo_line_rec.quantit '||p_mo_line_rec.quantity || ' l_quantity_detailed_conv'||l_quantity_detailed_conv||
1536                    'p_mo_line_rec.quantity_delivered '||p_mo_line_rec.quantity_delivered  ||'   p_mo_line_rec.detailed_quantity '||
1537                     p_mo_line_rec.quantity_detailed , 'PROCESS_LINE');
1538         END IF;
1539 
1540       wip_picking_pub.unallocate_material(
1541          p_wip_entity_id          => p_mo_line_rec.txn_source_id
1542        , p_operation_seq_num      => p_mo_line_rec.txn_source_line_id
1543        , p_inventory_item_id      => p_mo_line_rec.inventory_item_id
1544        , p_repetitive_schedule_id => p_mo_line_rec.reference_id
1545        , p_primary_quantity       => p_mo_line_rec.quantity- ( NVL(l_quantity_detailed_conv, 0) + NVL(p_mo_line_rec.quantity_delivered, 0) ) --pass backordered  qty
1546        , x_return_status          => l_api_return_status
1547        , x_msg_data               => x_msg_data
1548        );
1549 
1550        IF (l_debug = 1) THEN
1551         print_debug('wip_picking_pub.unallocate_material returned '|| l_api_return_status , 'PROCESS_LINE');
1552        END IF;
1553       END IF;  --   end if fix for  bug 4634522
1554 
1555       p_mo_line_rec.quantity_detailed  := NVL(l_quantity_detailed_conv, 0) + NVL(p_mo_line_rec.quantity_delivered, 0);
1556       p_mo_line_rec.pick_slip_date     := SYSDATE;
1557       IF (l_debug = 1) THEN
1558         print_debug('Detailed Qty = '|| p_mo_line_rec.quantity_detailed, 'PROCESS_LINE');
1559         print_debug('Updating Move Order Line', 'PROCESS_LINE');
1560       END IF;
1561       inv_trolin_util.update_row(p_mo_line_rec);
1562       update_mmtt_for_wip(x_return_status, p_mo_line_rec, p_grouping_rule_id);
1563       IF x_return_status <> fnd_api.g_ret_sts_success THEN
1564         print_debug('Error occurred while updating MMTT with WIP Attributes','PROCESS_LINE');
1565         RAISE fnd_api.g_exc_unexpected_error;
1566       END IF;
1567     END IF; -- if l_num_detail_rec > 0
1568 
1569     -- If the line was only partially detailed and the API was about to return success,
1570     -- set the return status to 'P' (Partial) or 'N' (None) instead.
1571     x_detail_rec_count  := l_num_detail_recs;
1572     x_return_status := l_mol_allocation_status;
1573     IF l_debug = 1 THEN
1574        print_debug('Return status: ' || l_mol_allocation_status,'PROCESS_LINE');
1575     END IF;
1576   EXCEPTION
1577     WHEN OTHERS THEN
1578       ROLLBACK TO process_line_pvt;
1579       IF l_debug = 1 THEN
1580          print_debug('Error in process line: ' || sqlcode || ', ' || sqlerrm,'PROCESS_LINE');
1581       END IF;
1582       x_return_status  := g_not_allocated;
1583       fnd_msg_pub.count_and_get(p_count => x_msg_count, p_data => x_msg_data, p_encoded => fnd_api.g_false);
1584   END process_line;
1585 
1586   PROCEDURE update_mol_for_wip
1587   ( x_return_status       OUT  NOCOPY VARCHAR2
1588   , x_msg_count           OUT  NOCOPY NUMBER
1589   , x_msg_data            OUT  NOCOPY VARCHAR2
1590   , p_move_order_line_id  IN   NUMBER
1591   , p_op_seq_num          IN   NUMBER
1592   ) IS
1593     l_debug number := NVL(FND_PROFILE.VALUE('INV_DEBUG_TRACE'),0);
1594   BEGIN
1595     x_return_status  := fnd_api.g_ret_sts_success;
1596     IF (l_debug = 1) THEN
1597        print_debug('p_move_order_line_id => '|| p_move_order_line_id, 'update_mol_for_wip');
1598        print_debug('p_op_seq_num => '|| p_op_seq_num, 'update_mol_for_wip');
1599     END IF;
1600 
1601     UPDATE mtl_txn_request_lines mol
1602        SET mol.txn_source_line_id = p_op_seq_num
1603      WHERE mol.line_id = p_move_order_line_id
1604        AND EXISTS( SELECT ''
1605                      FROM mtl_txn_request_headers moh
1606                     WHERE moh.header_id = mol.header_id
1607                       AND move_order_type = 5);
1608 
1609     IF SQL%NOTFOUND THEN
1610       IF (l_debug = 1) THEN
1611          print_debug('No move order lines being updated', 'update_mol_for_wip');
1612       END IF;
1613       x_return_status  := fnd_api.g_ret_sts_error;
1614       RETURN;
1615     END IF;
1616 
1617     UPDATE mtl_material_transactions_temp mmtt
1618        SET mmtt.trx_source_line_id = p_op_seq_num
1619      WHERE mmtt.move_order_line_id = p_move_order_line_id
1620        AND EXISTS( SELECT ''
1621                      FROM mtl_txn_request_headers moh, mtl_txn_request_lines mol
1622                     WHERE mol.line_id = mmtt.move_order_line_id
1623                       AND mol.header_id = moh.header_id
1624                       AND move_order_type = 5);
1625   EXCEPTION
1626     WHEN OTHERS THEN
1627       x_return_status  := fnd_api.g_ret_sts_unexp_error;
1628   END update_mol_for_wip;
1629 
1630   PROCEDURE update_mmtt_for_wip(
1631     x_return_status   OUT NOCOPY VARCHAR2
1632   , p_mo_line_rec      IN        inv_move_order_pub.trolin_rec_type
1633   , p_grouping_rule_id IN        NUMBER
1634   ) IS
1635     l_wip_entity_type    NUMBER;
1636     l_repetitive_line_id NUMBER;
1637     l_department_id      NUMBER;
1638     l_department_code    bom_departments.department_code%TYPE;
1639     l_push_vs_pull       VARCHAR2(4);
1640     l_pick_slip_number   NUMBER;
1641     l_index              NUMBER                                 := 0;
1642     l_msg_data VARCHAR2(2000);
1643     l_debug NUMBER := NVL(FND_PROFILE.VALUE('INV_DEBUG_TRACE'),0);
1644 
1645     CURSOR c_mmtt IS
1646       SELECT transaction_temp_id, revision, subinventory_code, locator_id, transfer_subinventory, transfer_to_location, pick_slip_number
1647         FROM mtl_material_transactions_temp
1648        WHERE move_order_line_id = p_mo_line_rec.line_id;
1649   BEGIN
1650     get_wip_attributes(
1651       x_return_status           => x_return_status
1652     , x_wip_entity_type         => l_wip_entity_type
1653     , x_push_vs_pull            => l_push_vs_pull
1654     , x_repetitive_line_id      => l_repetitive_line_id
1655     , x_department_id           => l_department_id
1656     , x_department_code         => l_department_code
1657     , x_pick_slip_number        => l_pick_slip_number
1658     , p_wip_entity_id           => p_mo_line_rec.txn_source_id
1659     , p_operation_seq_num       => p_mo_line_rec.txn_source_line_id
1660     , p_rep_schedule_id         => p_mo_line_rec.reference_id
1661     , p_organization_id         => p_mo_line_rec.organization_id
1662     , p_inventory_item_id       => p_mo_line_rec.inventory_item_id
1663     , p_transaction_type_id     => p_mo_line_rec.transaction_type_id
1664     , p_get_pick_slip_number    => FALSE
1665     );
1666 
1667     IF x_return_status <> fnd_api.g_ret_sts_success THEN
1668       print_debug('Error Occurred while getting WIP Attributes','UPDATE_MMTT_FOR_WIP');
1669       RAISE fnd_api.g_exc_unexpected_error;
1670     END IF;
1671 
1672     FOR c_mmtt_rec IN c_mmtt LOOP
1673       l_index  := l_index + 1;
1674 
1675       IF c_mmtt_rec.pick_slip_number IS NULL THEN
1676         IF g_wip_patch_level >= 1159 THEN
1677           inv_pr_pick_slip_number.get_pick_slip_number(
1678             p_pick_grouping_rule_id  => p_grouping_rule_id
1679           , p_org_id                 => p_mo_line_rec.organization_id
1680           , p_wip_entity_id          => p_mo_line_rec.txn_source_id
1681           , p_rep_schedule_id        => p_mo_line_rec.reference_id
1682           , p_operation_seq_num      => p_mo_line_rec.txn_source_line_id
1683           , p_dept_id                => l_department_id
1684           , p_push_or_pull           => l_push_vs_pull
1685           , p_supply_subinventory    => c_mmtt_rec.transfer_subinventory
1686           , p_supply_locator_id      => c_mmtt_rec.transfer_to_location
1687           , p_project_id             => p_mo_line_rec.project_id
1688           , p_task_id                => p_mo_line_rec.task_id
1689           , p_src_subinventory       => c_mmtt_rec.subinventory_code
1690           , p_src_locator_id         => c_mmtt_rec.locator_id
1691           , p_inventory_item_id      => p_mo_line_rec.inventory_item_id
1692           , p_revision               => c_mmtt_rec.revision
1693           , p_lot_number             => NULL
1694           , x_pick_slip_number       => l_pick_slip_number
1695           , x_api_status             => x_return_status
1696           , x_error_message          => l_msg_data
1697           );
1698 
1699           IF x_return_status <> fnd_api.g_ret_sts_success THEN
1700              IF (l_debug = 1) THEN
1701                 print_debug('Error occurred in getting the Pick Slip Number: '|| l_msg_data, 'UPDATE_WITH_PICK_SLIP');
1702              END IF;
1703              fnd_message.set_name('INV','INV_NO_PICK_SLIP_NUMBER');
1704              fnd_msg_pub.add;
1705              RAISE fnd_api.g_exc_unexpected_error;
1706           END IF;
1707         ELSE
1708           BEGIN
1709             SELECT WSH_PICK_SLIP_NUMBERS_S.NEXTVAL INTO l_pick_slip_number FROM DUAL;
1710           EXCEPTION
1711             WHEN OTHERS THEN
1712                fnd_message.set_name('INV','INV_NO_PICK_SLIP_NUMBER');
1713                fnd_msg_pub.add;
1714                RAISE fnd_api.g_exc_unexpected_error;
1715           END;
1716         END IF;
1717       ELSE
1718         l_pick_slip_number := c_mmtt_rec.pick_slip_number;
1719       END IF;
1720 
1721       IF p_mo_line_rec.transaction_type_id = INV_GLOBALS.G_TYPE_XFER_ORDER_WIP_ISSUE THEN
1722         UPDATE mtl_material_transactions_temp
1723            SET transaction_source_id      = p_mo_line_rec.txn_source_id
1724              , trx_source_line_id         = p_mo_line_rec.txn_source_line_id
1725              , demand_source_header_id    = p_mo_line_rec.txn_source_id
1726              , demand_source_line         = p_mo_line_rec.txn_source_line_id
1727              , transaction_source_type_id = inv_globals.g_sourcetype_wip
1728              , transaction_type_id        = p_mo_line_rec.transaction_type_id
1729              , transaction_action_id      = inv_globals.g_action_issue
1730              , wip_entity_type            = l_wip_entity_type
1731              , repetitive_line_id         = l_repetitive_line_id
1732              , operation_seq_num          = p_mo_line_rec.txn_source_line_id
1733              , department_id              = l_department_id
1734              , department_code            = l_department_code
1735              , lock_flag                  = 'N'
1736              , primary_switch             = l_index
1737              , wip_supply_type            = 1
1738              , negative_req_flag          = SIGN(transaction_quantity)
1739              , required_flag              = '1'
1740              , pick_slip_number           = l_pick_slip_number
1741          WHERE transaction_temp_id        = c_mmtt_rec.transaction_temp_id;
1742       ELSIF p_mo_line_rec.transaction_type_id = INV_GLOBALS.G_TYPE_XFER_ORDER_REPL_SUBXFR THEN
1743         UPDATE mtl_material_transactions_temp
1744            SET transaction_source_id      = p_mo_line_rec.txn_source_id
1745              , trx_source_line_id         = p_mo_line_rec.txn_source_line_id
1746              , demand_source_header_id    = p_mo_line_rec.txn_source_id
1747              , demand_source_line         = p_mo_line_rec.txn_source_line_id
1748              , transaction_source_type_id = inv_globals.g_sourcetype_inventory
1749              , transaction_type_id        = p_mo_line_rec.transaction_type_id
1750              , transaction_action_id      = inv_globals.g_action_subxfr
1751              , wip_entity_type            = l_wip_entity_type
1752              , wip_supply_type            = NULL -- Bug#2057540
1753              , pick_slip_number           = l_pick_slip_number
1754          WHERE transaction_temp_id        = c_mmtt_rec.transaction_temp_id;
1755       END IF;
1756     END LOOP;
1757   EXCEPTION
1758     WHEN OTHERS THEN
1759       IF (l_debug = 1) THEN
1760          print_debug('Exception Occurred: Code = ' || SQLCODE || ' : Error '|| SQLERRM, 'UPDATE_MMTT_FOR_WIP');
1761       END IF;
1762       x_return_status := fnd_api.g_ret_sts_unexp_error;
1763   END update_mmtt_for_wip;
1764 
1765   PROCEDURE get_wip_attributes(
1766     x_return_status           OUT NOCOPY VARCHAR2
1767   , x_wip_entity_type         OUT NOCOPY NUMBER
1768   , x_push_vs_pull            OUT NOCOPY VARCHAR2
1769   , x_repetitive_line_id      OUT NOCOPY NUMBER
1770   , x_department_id           OUT NOCOPY NUMBER
1771   , x_department_code         OUT NOCOPY VARCHAR2
1772   , x_pick_slip_number        OUT NOCOPY NUMBER
1773   , p_wip_entity_id            IN        NUMBER
1774   , p_operation_seq_num        IN        NUMBER
1775   , p_rep_schedule_id          IN        NUMBER
1776   , p_organization_id          IN        NUMBER
1777   , p_inventory_item_id        IN        NUMBER
1778   , p_transaction_type_id      IN        NUMBER
1779   , p_get_pick_slip_number     IN        BOOLEAN
1780   ) IS
1781 
1782     CURSOR c_wip_entity_type IS
1783       SELECT entity_type
1784         FROM wip_entities
1785        WHERE wip_entity_id = p_wip_entity_id;
1786 
1787     CURSOR c_repetitive_line_id IS
1788       SELECT line_id
1789         FROM wip_repetitive_schedules
1790        WHERE repetitive_schedule_id = p_rep_schedule_id
1791          AND organization_id = p_organization_id
1792          AND wip_entity_id = p_wip_entity_id;
1793 
1794     CURSOR c_push_vs_pull IS
1795       SELECT decode(wip_supply_type,1,'PUSH',2,'PULL',3,'PULL')
1796         FROM wip_requirement_operations
1797        WHERE p_rep_schedule_id IS null
1798          AND wip_entity_id = p_wip_entity_id
1799          AND inventory_item_id = p_inventory_item_id
1800          AND operation_seq_num = p_operation_seq_num
1801          AND organization_id   = p_organization_id
1802       UNION ALL
1803       SELECT decode(wip_supply_type,1,'PUSH',2,'PULL',3,'PULL')
1804         FROM wip_requirement_operations
1805        WHERE p_rep_schedule_id IS NOT NULL
1806          AND wip_entity_id = p_wip_entity_id
1807          AND inventory_item_id = p_inventory_item_id
1808          AND operation_seq_num = p_operation_seq_num
1809          AND organization_id   = p_organization_id
1810          AND repetitive_schedule_id = p_rep_schedule_id;
1811 
1812     CURSOR c_discrete_dept IS
1813       SELECT wo.department_id, bd.department_code
1814         FROM wip_operations wo, bom_departments bd
1815        WHERE wo.wip_entity_id = p_wip_entity_id
1816          AND wo.organization_id = p_organization_id
1817          AND wo.operation_seq_num = p_operation_seq_num
1818          AND bd.department_id = wo.department_id;
1819 
1820     CURSOR c_repetitive_dept IS
1821       SELECT wo.department_id, bd.department_code
1822         FROM wip_operations wo, bom_departments bd
1823        WHERE wo.wip_entity_id = p_wip_entity_id
1824          AND wo.organization_id = p_organization_id
1825          AND wo.operation_seq_num = p_operation_seq_num
1826          AND wo.repetitive_schedule_id = p_rep_schedule_id
1827          AND bd.department_id = wo.department_id;
1828 
1829     CURSOR c_flow_dept IS
1830       SELECT bos.department_id, bd.department_code
1831         FROM bom_departments bd
1832            , bom_operation_sequences bos
1833            , bom_operational_routings bor
1834            , wip_flow_schedules wfs
1835        WHERE wfs.wip_entity_id = p_wip_entity_id
1836          AND wfs.organization_id = p_organization_id
1837          AND bor.assembly_item_id = wfs.primary_item_id
1838          AND bor.organization_id = wfs.organization_id
1839          AND (bor.alternate_routing_designator = wfs.alternate_routing_designator
1840               OR (wfs.alternate_routing_designator IS NULL
1841                   AND bor.alternate_routing_designator IS NULL))
1842          AND bos.routing_sequence_id = bor.routing_sequence_id
1843          AND bos.operation_type = 1
1844          AND bos.effectivity_date >= SYSDATE
1845          AND bd.department_id = bos.department_id;
1846 
1847     l_debug NUMBER := NVL(FND_PROFILE.VALUE('INV_DEBUG_TRACE'),0);
1848 
1849   BEGIN
1850     x_return_status := fnd_api.g_ret_sts_success;
1851 
1852     -- Entity type
1853     OPEN c_wip_entity_type;
1854     FETCH c_wip_entity_type INTO x_wip_entity_type;
1855     IF c_wip_entity_type%NOTFOUND THEN
1856       IF (l_debug = 1) THEN
1857          print_debug('Couldnt determine Entity Type for EntityID = '|| p_wip_entity_id, 'UPDATE_MMTT_FOR_WIP');
1858       END IF;
1859       CLOSE c_wip_entity_type;
1860       RAISE fnd_api.g_exc_unexpected_error;
1861     END IF;
1862     CLOSE c_wip_entity_type;
1863 
1864     -- Departments
1865     IF x_wip_entity_type IN (1,5,6) THEN
1866       OPEN c_discrete_dept;
1867       FETCH c_discrete_dept INTO x_department_id, x_department_code;
1868       CLOSE c_discrete_dept;
1869     ELSIF x_wip_entity_type = 2 THEN
1870       OPEN c_repetitive_dept;
1871       FETCH c_repetitive_dept INTO x_department_id, x_department_code;
1872       CLOSE c_repetitive_dept;
1873     ELSIF x_wip_entity_type = 4 THEN
1874       OPEN c_flow_dept;
1875       FETCH c_flow_dept INTO x_department_id, x_department_code;
1876       CLOSE c_flow_dept;
1877     END IF;
1878 
1879     -- Repetitive Line ID
1880     IF p_transaction_type_id = INV_GLOBALS.G_TYPE_XFER_ORDER_WIP_ISSUE THEN
1881       IF x_wip_entity_type = 2 THEN
1882         IF p_rep_schedule_id IS NULL THEN
1883           IF (l_debug = 1) THEN
1884              print_debug('Repetitive Schedule ID cannot be null for Entity Type 2', 'UPDATE_MMTT_FOR_WIP');
1885           END IF;
1886           RAISE fnd_api.g_exc_unexpected_error;
1887         ELSE
1888           OPEN c_repetitive_line_id;
1889           FETCH c_repetitive_line_id INTO x_repetitive_line_id;
1890           IF c_repetitive_line_id%NOTFOUND THEN
1891             IF (l_debug = 1) THEN
1892                print_debug('Unable to determine RepLineID for RepSchID '||p_rep_schedule_id, 'UPDATE_MMTT_FOR_WIP');
1893             END IF;
1894             RAISE fnd_api.g_exc_unexpected_error;
1895           END IF;
1896           CLOSE c_repetitive_line_id;
1897         END IF;
1898       END IF;
1899     END IF;
1900 
1901     -- Supply Type
1902     IF x_wip_entity_type IN (1, 2, 5, 6) THEN
1903       OPEN c_push_vs_pull;
1904       FETCH c_push_vs_pull INTO x_push_vs_pull;
1905       CLOSE c_push_vs_pull;
1906     ELSIF x_wip_entity_type = 4 THEN
1907       x_push_vs_pull := 'PULL';
1908     END IF;
1909 
1910     -- Pick Slip Number
1911     IF p_get_pick_slip_number THEN
1912       SELECT WSH_PICK_SLIP_NUMBERS_S.NEXTVAL INTO x_pick_slip_number FROM DUAL;
1913     END IF;
1914   EXCEPTION
1915     WHEN OTHERS THEN
1916       x_return_status := fnd_api.g_ret_sts_error;
1917   END get_wip_attributes;
1918 
1919   FUNCTION get_mo_alloc_stat RETURN VARCHAR2 IS
1920     l_mo_alloc_stat  VARCHAR2(1) := g_not_allocated;
1921     l_debug          NUMBER      := NVL(FND_PROFILE.VALUE('INV_DEBUG_TRACE'),0);
1922     l_first_line_id  NUMBER      := 0;
1923     l_last_line_id   NUMBER      := 0;
1924     l_cur_line_id    NUMBER      := 0;
1925 
1926     l_num_success    NUMBER      := 0;
1927     l_num_partial    NUMBER      := 0;
1928     l_num_no_alloc   NUMBER      := 0;
1929   BEGIN
1930     l_first_line_id := g_mo_line_stat_tbl.FIRST;
1931     l_last_line_id  := g_mo_line_stat_tbl.LAST;
1932 
1933     IF l_debug = 1 THEN
1934        print_debug('First line ID: '  || to_char(l_first_line_id) || ', Last line ID: ' || to_char(l_last_line_id), 'GET_MO_ALLOC_STAT');
1935     END IF;
1936 
1937     l_cur_line_id := l_first_line_id;
1938     LOOP
1939       IF l_debug = 1 THEN
1940          print_debug('Line ID: ' || to_char(l_cur_line_id) || ', Line alloc stat: ' || g_mo_line_stat_tbl(l_cur_line_id), 'GET_MO_ALLOC_STAT');
1941       END IF;
1942 
1943       IF g_mo_line_stat_tbl(l_cur_line_id) = g_completely_allocated THEN
1944          l_num_success := l_num_success + 1;
1945       ELSIF g_mo_line_stat_tbl(l_cur_line_id) = g_partially_allocated THEN
1946          l_num_partial := l_num_partial + 1;
1947       ELSIF g_mo_line_stat_tbl(l_cur_line_id) = g_not_allocated THEN
1948          l_num_no_alloc := l_num_no_alloc + 1;
1949       END IF;
1950 
1951       IF l_cur_line_id = l_last_line_id THEN
1952          EXIT;
1953       END IF;
1954 
1955       l_cur_line_id := g_mo_line_stat_tbl.NEXT(l_cur_line_id);
1956     END LOOP;
1957 
1958     -- Bug 5469486: Add the number of lines where MOL creation failed
1959     l_num_no_alloc := l_num_no_alloc + NVL(g_mol_fail_count,0);
1960 
1961     IF l_debug = 1 THEN
1962        print_debug('Line status counts:: Successes: ' || l_num_success ||', Partial: ' || l_num_partial  ||', None: '    || l_num_no_alloc, 'GET_MO_ALLOC_STAT');
1963     END IF;
1964 
1965     IF l_num_success > 0 AND l_num_partial = 0 AND l_num_no_alloc = 0 THEN
1966        l_mo_alloc_stat := g_completely_allocated;
1967     ELSIF l_num_partial > 0 OR (l_num_success > 0 AND l_num_no_alloc > 0) THEN
1968        l_mo_alloc_stat := g_partially_allocated;
1969     ELSE
1970        l_mo_alloc_stat := g_not_allocated;
1971     END IF;
1972 
1973     IF l_debug = 1 THEN
1974        print_debug('Overall status: ' || l_mo_alloc_stat, 'GET_MO_ALLOC_STAT');
1975     END IF;
1976 
1977     RETURN l_mo_alloc_stat;
1978   EXCEPTION
1979     WHEN OTHERS THEN
1980       IF l_debug = 1 THEN
1981          print_debug('Error: ' || SQLCODE || ', ' || SQLERRM , 'GET_MO_ALLOC_STAT');
1982       END IF;
1983       RETURN g_not_allocated;
1984   END get_mo_alloc_stat;
1985 
1986 END inv_wip_picking_pvt;