DBA Data[Home] [Help]

PACKAGE BODY: APPS.PO_PDOI_LINE_PROCESS_PVT

Source


1 PACKAGE BODY PO_PDOI_LINE_PROCESS_PVT AS
2 /* $Header: PO_PDOI_LINE_PROCESS_PVT.plb 120.46.12010000.4 2008/12/18 07:49:51 mugoel ship $ */
3 
4 d_pkg_name CONSTANT VARCHAR2(50) :=
5   PO_LOG.get_package_base('PO_PDOI_LINE_PROCESS_PVT');
6 
7 --------------------------------------------------------------------------
8 ---------------------- PRIVATE PROCEDURES PROTOTYPE ----------------------
9 --------------------------------------------------------------------------
10 
11 -- bug5684695
12 -- removed derive_po_header_id procedure
13 
14 
15 PROCEDURE derive_item_id
16 (
17   p_key                    IN po_session_gt.key%TYPE,
18   p_index_tbl              IN DBMS_SQL.NUMBER_TABLE,
19   p_vendor_id_tbl          IN PO_TBL_NUMBER,
20   p_intf_header_id_tbl     IN PO_TBL_NUMBER,
21   p_intf_line_id_tbl       IN PO_TBL_NUMBER,
22   p_vendor_product_num_tbl IN PO_TBL_VARCHAR30,
23   p_category_id_tbl        IN PO_TBL_NUMBER,            --bug 7374337
24   p_item_tbl               IN PO_TBL_VARCHAR2000,
25   x_item_id_tbl            IN OUT NOCOPY PO_TBL_NUMBER,
26   x_error_flag_tbl         IN OUT NOCOPY PO_TBL_VARCHAR1
27 );
28 
29 PROCEDURE derive_item_revision
30 (
31   p_key                    IN po_session_gt.key%TYPE,
32   p_item_id_tbl            IN PO_TBL_NUMBER,
33   x_item_revision_tbl      IN OUT NOCOPY PO_TBL_VARCHAR5
34 );
35 
36 PROCEDURE derive_job_business_group_id
37 (
38   p_key                            IN po_session_gt.key%TYPE,
39   p_index_tbl                      IN DBMS_SQL.NUMBER_TABLE,
40   p_job_business_group_name_tbl    IN PO_TBL_VARCHAR2000,
41   x_job_business_group_id_tbl      IN OUT NOCOPY PO_TBL_NUMBER
42 );
43 
44 PROCEDURE derive_job_id
45 (
46   p_key                            IN po_session_gt.key%TYPE,
47   p_index_tbl                      IN DBMS_SQL.NUMBER_TABLE,
48   p_file_line_language_tbl         IN PO_TBL_VARCHAR5,
49   p_job_business_group_name_tbl    IN PO_TBL_VARCHAR2000,
50   p_job_name_tbl                   IN PO_TBL_VARCHAR2000,
51   x_job_business_group_id_tbl      IN OUT NOCOPY PO_TBL_NUMBER,
52   x_job_id_tbl                     IN OUT NOCOPY PO_TBL_NUMBER
53 );
54 
55 PROCEDURE derive_category_id
56 (
57   p_key                  IN po_session_gt.key%TYPE,
58   p_category_tbl         IN PO_TBL_VARCHAR2000,
59   x_category_id_tbl      IN OUT NOCOPY PO_TBL_NUMBER
60 );
61 
62 PROCEDURE derive_ip_category_id
63 (
64   p_key                    IN po_session_gt.key%TYPE,
65   p_index_tbl              IN DBMS_SQL.NUMBER_TABLE,
66   p_file_line_language_tbl IN PO_TBL_VARCHAR5,
67   p_ip_category_tbl        IN PO_TBL_VARCHAR2000,
68   x_ip_category_id_tbl     IN OUT NOCOPY PO_TBL_NUMBER
69 );
70 
71 PROCEDURE derive_unit_of_measure
72 (
73   p_key                  IN po_session_gt.key%TYPE,
74   p_index_tbl            IN DBMS_SQL.NUMBER_TABLE,
75   p_uom_code_tbl         IN PO_TBL_VARCHAR5,
76   x_unit_of_measure_tbl  IN OUT NOCOPY PO_TBL_VARCHAR30
77 );
78 
79 PROCEDURE derive_line_type_id
80 (
81   p_key                    IN po_session_gt.key%TYPE,
82   p_index_tbl              IN DBMS_SQL.NUMBER_TABLE,
83   p_file_line_language_tbl IN PO_TBL_VARCHAR5,
84   p_line_type_tbl          IN PO_TBL_VARCHAR30,
85   x_line_type_id_tbl       IN OUT NOCOPY PO_TBL_NUMBER
86 );
87 
88 PROCEDURE derive_un_number_id
89 (
90   p_key                  IN po_session_gt.key%TYPE,
91   p_index_tbl            IN DBMS_SQL.NUMBER_TABLE,
92   p_un_number_tbl        IN PO_TBL_VARCHAR30,
93   x_un_number_id_tbl     IN OUT NOCOPY PO_TBL_NUMBER
94 );
95 
96 PROCEDURE derive_hazard_class_id
97 (
98   p_key                  IN po_session_gt.key%TYPE,
99   p_index_tbl            IN DBMS_SQL.NUMBER_TABLE,
100   p_hazard_class_tbl     IN PO_TBL_VARCHAR100,
101   x_hazard_class_id_tbl  IN OUT NOCOPY PO_TBL_NUMBER
102 );
103 
104 PROCEDURE derive_template_id
105 (
106   p_key                  IN po_session_gt.key%TYPE,
107   p_index_tbl            IN DBMS_SQL.NUMBER_TABLE,
108   p_template_name_tbl    IN PO_TBL_VARCHAR30,
109   x_template_id_tbl      IN OUT NOCOPY PO_TBL_NUMBER
110 );
111 
112 PROCEDURE default_info_from_line_type
113 (
114   p_key                        IN po_session_gt.key%TYPE,
115   p_index_tbl                  IN DBMS_SQL.NUMBER_TABLE,
116   p_line_type_id_tbl           IN PO_TBL_NUMBER,
117   x_order_type_lookup_code_tbl IN OUT NOCOPY PO_TBL_VARCHAR30,
118   x_purchase_basis_tbl         IN OUT NOCOPY PO_TBL_VARCHAR30,
119   x_matching_basis_tbl         IN OUT NOCOPY PO_TBL_VARCHAR30,
120   x_category_id_tbl            OUT NOCOPY PO_TBL_NUMBER,
121   x_unit_of_measure_tbl        OUT NOCOPY PO_TBL_VARCHAR30,
122   x_unit_price_tbl             OUT NOCOPY PO_TBL_NUMBER
123 );
124 
125 PROCEDURE default_info_from_item
126 (
127   p_key                        IN po_session_gt.key%TYPE,
128   p_index_tbl                  IN DBMS_SQL.NUMBER_TABLE,
129   p_item_id_tbl                IN PO_TBL_NUMBER,
130   x_item_desc_tbl              OUT NOCOPY PO_TBL_VARCHAR2000,
131   x_unit_of_measure_tbl        OUT NOCOPY PO_TBL_VARCHAR30,
132   x_unit_price_tbl             OUT NOCOPY PO_TBL_NUMBER,
133   x_category_id_tbl            OUT NOCOPY PO_TBL_NUMBER,
134   x_un_number_id_tbl           OUT NOCOPY PO_TBL_NUMBER,
135   x_hazard_class_id_tbl        OUT NOCOPY PO_TBL_NUMBER,
136   x_market_price_tbl           OUT NOCOPY PO_TBL_NUMBER,
137   x_secondary_unit_of_meas_tbl OUT NOCOPY PO_TBL_VARCHAR30
138 );
139 
140 PROCEDURE default_info_from_job
141 (
142   p_key                        IN po_session_gt.key%TYPE,
143   p_index_tbl                  IN DBMS_SQL.NUMBER_TABLE,
144   p_job_id_tbl                 IN PO_TBL_NUMBER,
145   x_item_desc_tbl              OUT NOCOPY PO_TBL_VARCHAR2000,
146   x_category_id_tbl            OUT NOCOPY PO_TBL_NUMBER
147 );
148 
149 PROCEDURE default_po_cat_id_from_ip
150 (
151   p_key                        IN po_session_gt.key%TYPE,
152   p_index_tbl                  IN DBMS_SQL.NUMBER_TABLE,
153   p_ip_category_id_tbl         IN PO_TBL_NUMBER,
154   x_po_category_id_tbl         IN OUT NOCOPY PO_TBL_NUMBER
155 );
156 
157 PROCEDURE default_ip_cat_id_from_po
158 (
159   p_key                        IN po_session_gt.key%TYPE,
160   p_index_tbl                  IN DBMS_SQL.NUMBER_TABLE,
161   p_po_category_id_tbl         IN PO_TBL_NUMBER,
162   x_ip_category_id_tbl         IN OUT NOCOPY PO_TBL_NUMBER
163 );
164 
165 PROCEDURE default_hc_id_from_un_number
166 (
167   p_key                        IN po_session_gt.key%TYPE,
168   p_index_tbl                  IN DBMS_SQL.NUMBER_TABLE,
169   p_un_number_tbl              IN PO_TBL_VARCHAR30,
170   x_hazard_class_id_tbl        IN OUT NOCOPY PO_TBL_NUMBER
171 );
172 
173 PROCEDURE match_lines_on_line_num
174 (
175   p_index_tbl     IN DBMS_SQL.NUMBER_TABLE,
176   x_lines         IN OUT NOCOPY PO_PDOI_TYPES.lines_rec_type
177 );
178 
179 PROCEDURE match_lines_on_item_info
180 (
181   x_lines         IN OUT NOCOPY PO_PDOI_TYPES.lines_rec_type
182 );
183 
184 PROCEDURE copy_lines
185 (
186   p_source_lines     IN PO_PDOI_TYPES.lines_rec_type,
187   p_source_index_tbl IN DBMS_SQL.NUMBER_TABLE,
188   x_target_lines     IN OUT NOCOPY PO_PDOI_TYPES.lines_rec_type
189 );
190 
191 PROCEDURE uniqueness_check_on_desc
192 (
193   p_key                 IN po_session_gt.key%TYPE,
194   p_group_num           IN NUMBER,
195   x_processing_row_tbl  IN OUT NOCOPY DBMS_SQL.NUMBER_TABLE,
196   x_lines               IN OUT NOCOPY PO_PDOI_TYPES.lines_rec_type
197 );
198 
199 PROCEDURE uniqueness_check_on_item
200 (
201   p_key                 IN po_session_gt.key%TYPE,
202   p_group_num           IN NUMBER,
203   x_processing_row_tbl  IN OUT NOCOPY DBMS_SQL.NUMBER_TABLE,
204   x_lines               IN OUT NOCOPY PO_PDOI_TYPES.lines_rec_type
205 );
206 
207 PROCEDURE uniqueness_check_on_vpn
208 (
209   p_key                 IN po_session_gt.key%TYPE,
210   p_group_num           IN NUMBER,
211   x_processing_row_tbl  IN OUT NOCOPY DBMS_SQL.NUMBER_TABLE,
212   x_lines               IN OUT NOCOPY PO_PDOI_TYPES.lines_rec_type
213 );
214 
215 PROCEDURE uniqueness_check_on_job
216 (
217   p_key                 IN po_session_gt.key%TYPE,
218   p_group_num           IN NUMBER,
219   x_processing_row_tbl  IN OUT NOCOPY DBMS_SQL.NUMBER_TABLE,
220   x_lines               IN OUT NOCOPY PO_PDOI_TYPES.lines_rec_type
221 );
222 
223 PROCEDURE uniqueness_check_on_line_num
224 (
225   p_key                 IN po_session_gt.key%TYPE,
226   p_group_num           IN NUMBER,
227   x_processing_row_tbl  IN OUT NOCOPY DBMS_SQL.NUMBER_TABLE,
228   x_lines               IN OUT NOCOPY PO_PDOI_TYPES.lines_rec_type
229 );
230 
231 
232 PROCEDURE set_action_add
233 (
234   p_key                   IN po_session_gt.key%TYPE,
235   p_group_num             IN NUMBER,
236   p_target_lines_index_tbl IN PO_TBL_NUMBER,
237   p_check_line_num_assign IN VARCHAR2,
238   x_processing_row_tbl    IN OUT NOCOPY DBMS_SQL.NUMBER_TABLE,
239   x_lines                 IN OUT NOCOPY PO_PDOI_TYPES.lines_rec_type
240 );
241 
242 
243 PROCEDURE validate_attr_tlp
244 (
245   x_lines IN OUT NOCOPY PO_PDOI_TYPES.lines_rec_type
246 );
247 
248 PROCEDURE populate_error_flag
249 (
250   x_results           IN     po_validation_results_type,
251   x_lines             IN OUT NOCOPY PO_PDOI_TYPES.lines_rec_type
252 );
253 
254 PROCEDURE handle_err_tolerance
255 (
256   x_lines       IN OUT NOCOPY PO_PDOI_TYPES.lines_rec_type
257 );
258 
259 --------------------------------------------------------------------------
260 ---------------------- PUBLIC PROCEDURES ---------------------------------
261 --------------------------------------------------------------------------
262 
263 -----------------------------------------------------------------------
264 --Start of Comments
265 --Name: reject_dup_lines_for_spo
266 --Function: standard po lines cannot be updated. So if the new line in
267 --          interface table has the same line num as existing lines in
268 --          same document, these new lines will be regarded as intention
269 --          to update existing standard po records thus rejected.
270 --Parameters:
271 --IN:
272 --IN OUT:
273 --OUT:
274 --End of Comments
275 ------------------------------------------------------------------------
276 PROCEDURE reject_dup_lines_for_spo IS
277 
278   d_api_name CONSTANT VARCHAR2(30) := 'reject_dup_lines_for_spo';
279   d_module   CONSTANT VARCHAR2(255) := d_pkg_name || d_api_name || '.';
280   d_position NUMBER;
281 
282   -- select lines which have same line num as lines in txn table
283   CURSOR c_dup_lines_in_txn(p_request_processing_id NUMBER,
284                             p_request_processing_round_num NUMBER) IS
285   SELECT intf_headers.interface_header_id,
286          intf_lines.interface_line_id,
287          intf_lines.line_num
288   FROM   po_lines_interface intf_lines,
289          po_headers_interface intf_headers,
290          po_lines txn_lines
291   WHERE  intf_lines.interface_header_id = intf_headers.interface_header_id
292   AND    intf_headers.po_header_id = txn_lines.po_header_id
293   AND    intf_lines.processing_id = p_request_processing_id
294   AND    intf_headers.processing_round_num = p_request_processing_round_num
295   AND    intf_headers.processing_id = p_request_processing_id
296   AND    intf_lines.line_num = txn_lines.line_num
297   AND    intf_headers.action = PO_PDOI_CONSTANTS.g_ACTION_UPDATE;
298 
299   -- select lines which have same line num as lines in draft table
300   CURSOR c_dup_lines_in_draft(p_request_processing_id NUMBER,
301                               p_request_processing_round_num NUMBER) IS
302   SELECT intf_headers.interface_header_id,
303          intf_lines.interface_line_id,
304          intf_lines.line_num
305   FROM   po_headers_interface intf_headers,
306          po_lines_interface intf_lines,
307          po_lines_draft_all draft_lines
308   WHERE  intf_lines.interface_header_id = intf_headers.interface_header_id
309   AND    intf_headers.draft_id = draft_lines.draft_id
310   AND    intf_headers.po_header_id = draft_lines.po_header_id
311   AND    intf_lines.processing_id = p_request_processing_id
312   AND    intf_headers.processing_round_num = p_request_processing_round_num
313   AND    intf_headers.processing_id = p_request_processing_id
314   AND    intf_lines.line_num = draft_lines.line_num
315   AND    intf_headers.action = PO_PDOI_CONSTANTS.g_ACTION_UPDATE;
316 
317   -- duplicate lines in interface table
318   l_dup_intf_header_id_tbl PO_TBL_NUMBER;
319   l_dup_intf_line_id_tbl   PO_TBL_NUMBER;
320   l_dup_intf_line_num_tbl  PO_TBL_NUMBER;
321 
322   -- number of duplicate lines retrieved in each batch
323   l_count NUMBER;
324 BEGIN
325   d_position := 0;
326 
327   IF (PO_LOG.d_proc) THEN
328     PO_LOG.proc_begin(d_module);
329   END IF;
330 
331   -- first reject lines which are duplicate in txn table
332   OPEN c_dup_lines_in_txn(PO_PDOI_PARAMS.g_processing_id,
333                         PO_PDOI_PARAMS.g_current_round_num);
334 
335   d_position := 10;
336 
337   LOOP
338     -- retrieve identifiers of duplicate lines
339     FETCH c_dup_lines_in_txn
340     BULK COLLECT INTO
341       l_dup_intf_header_id_tbl,
342       l_dup_intf_line_id_tbl,
343       l_dup_intf_line_num_tbl
344     LIMIT PO_PDOI_CONSTANTS.g_DEF_BATCH_SIZE;
345 
346     d_position := 20;
347 
348     l_count := l_dup_intf_line_id_tbl.COUNT;
349 
350     IF (PO_LOG.d_stmt) THEN
351       PO_LOG.stmt(d_module, d_position, 'duplicate count against txn table', l_count);
352     END IF;
353 
354     EXIT WHEN l_count = 0;
355 
356     -- add error if a duplicate line is found
357     FOR i IN 1..l_count
358     LOOP
359       d_position := 30;
360 
361       IF (PO_LOG.d_stmt) THEN
362         PO_LOG.stmt(d_module, d_position, 'duplicate interface line id(txn)',
363                     l_dup_intf_line_id_tbl(i));
364       END IF;
365 
366       PO_PDOI_ERR_UTL.add_fatal_error
367       (
368         p_interface_header_id  => l_dup_intf_header_id_tbl(i),
369         p_interface_line_id    => l_dup_intf_line_id_tbl(i),
370         p_error_message_name   => 'PO_PDOI_STD_PO_LINE_NUM_EXISTS',
371         p_table_name           => 'PO_LINES_INTERFACE',
372         p_column_name          => 'LINE_NUM',
373         p_column_value         => l_dup_intf_line_num_tbl(i),
374         p_token1_name          => 'VALUE',
375         p_token1_value         => l_dup_intf_line_num_tbl(i)
376       );
377     END LOOP;
378 
379     d_position := 40;
380 
381     -- reject the lines and the lower level entities associated with it
382     PO_PDOI_UTL.reject_lines_intf
383     (
384       p_id_param_type           => PO_PDOI_CONSTANTS.g_INTERFACE_LINE_ID,
385       p_id_tbl                  => l_dup_intf_line_id_tbl,
386       p_cascade                 => FND_API.g_TRUE
387     );
388 
389     d_position := 50;
390 
391     IF (l_count < PO_PDOI_CONSTANTS.g_DEF_BATCH_SIZE) THEN
392       EXIT;
393     END IF;
394   END LOOP;
395 
396   CLOSE c_dup_lines_in_txn;
397 
398   d_position := 60;
399 
400   -- next, reject lines which are duplicate of lines in draft table
401   OPEN c_dup_lines_in_draft(PO_PDOI_PARAMS.g_processing_id,
402                           PO_PDOI_PARAMS.g_current_round_num);
403 
404   d_position := 70;
405 
406   LOOP
407     -- check duplicate lines in draft table
408     FETCH c_dup_lines_in_draft
409     BULK COLLECT INTO
410       l_dup_intf_header_id_tbl,
411       l_dup_intf_line_id_tbl,
412       l_dup_intf_line_num_tbl
413     LIMIT PO_PDOI_CONSTANTS.g_DEF_BATCH_SIZE;
414 
415     d_position := 80;
416 
417     l_count := l_dup_intf_line_id_tbl.COUNT;
418 
419     IF (PO_LOG.d_stmt) THEN
420       PO_LOG.stmt(d_module, d_position, 'duplicate count against draft table ', l_count);
421     END IF;
422 
423     EXIT WHEN l_count = 0;
424 
425     -- add error if a duplicate line is found
426     FOR i IN 1..l_count
427     LOOP
428       d_position := 90;
429 
430       IF (PO_LOG.d_stmt) THEN
431         PO_LOG.stmt(d_module, d_position, 'duplicate interface line id(draft)',
432                     l_dup_intf_line_id_tbl(i));
433       END IF;
434 
435       PO_PDOI_ERR_UTL.add_fatal_error
436       (
437         p_interface_header_id  => l_dup_intf_header_id_tbl(i),
438         p_interface_line_id    => l_dup_intf_line_id_tbl(i),
439         p_error_message_name   => 'PO_PDOI_STD_PO_LINE_NUM_EXISTS',
440         p_table_name           => 'PO_LINES_INTERFACE',
441         p_column_name          => 'LINE_NUM',
442         p_column_value         => l_dup_intf_line_num_tbl(i),
443         p_token1_name          => 'VALUE',
444         p_token1_value         => l_dup_intf_line_num_tbl(i)
445       );
446     END LOOP;
447 
448     d_position := 100;
449 
450     -- reject the lines and the lower level entities associated with it
451     PO_PDOI_UTL.reject_lines_intf
452     (
453       p_id_param_type           => PO_PDOI_CONSTANTS.g_INTERFACE_LINE_ID,
454       p_id_tbl                  => l_dup_intf_line_id_tbl,
455       p_cascade                 => FND_API.g_TRUE
456     );
457 
458     d_position := 110;
459 
460     IF (l_count < PO_PDOI_CONSTANTS.g_DEF_BATCH_SIZE) THEN
461       EXIT;
462     END IF;
463   END LOOP;
464 
465   CLOSE c_dup_lines_in_draft;
466 
467   d_position := 120;
468 
469   IF (PO_LOG.d_proc) THEN
470     PO_LOG.proc_end (d_module);
471   END IF;
472 
473 EXCEPTION
474   WHEN OTHERS THEN
475     PO_MESSAGE_S.add_exc_msg
476     (
477       p_pkg_name => d_pkg_name,
478       p_procedure_name => d_api_name || '.' || d_position
479     );
480     RAISE;
481 END reject_dup_lines_for_spo;
482 
483 -----------------------------------------------------------------------
484 --Start of Comments
485 --Name: reject_invalid_action_lines
486 --Function: The valid value of line level action is NULL or 'ADD' when
487 --          user issues a PDOI request. System will reject lines with
488 --          invalid action values.
489 --Parameters:
490 --IN:
491 --IN OUT:
492 --OUT:
493 --End of Comments
494 ------------------------------------------------------------------------
495 PROCEDURE reject_invalid_action_lines IS
496 
497   d_api_name CONSTANT VARCHAR2(30) := 'reject_invalid_action_lines';
498   d_module   CONSTANT VARCHAR2(255) := d_pkg_name || d_api_name || '.';
499   d_position NUMBER;
500 
501   -- select lines with invalid line level action value
502   CURSOR c_invalid_action_lines(p_request_processing_id NUMBER,
503                                 p_request_processing_round_num NUMBER) IS
504   SELECT intf_lines.interface_line_id,
505          intf_headers.interface_header_id,
506          intf_lines.action
507   FROM   po_lines_interface intf_lines,
508          po_headers_interface intf_headers
509   WHERE  intf_lines.interface_header_id = intf_headers.interface_header_id
510   AND    intf_lines.processing_id = p_request_processing_id
511   AND    intf_headers.processing_round_num = p_request_processing_round_num
512   AND    intf_headers.processing_id = p_request_processing_id
513   AND    NVL(intf_lines.action, PO_PDOI_CONSTANTS.g_ACTION_ADD) <>
514          PO_PDOI_CONSTANTS.g_ACTION_ADD;
515 
516   -- interface line id of lines that need to be rejected
517   l_rej_intf_line_id_tbl   PO_TBL_NUMBER;
518   l_rej_intf_header_id_tbl PO_TBL_NUMBER;
519   l_rej_line_action_tbl    PO_TBL_VARCHAR30;
520 
521 BEGIN
522   d_position := 0;
523 
524   IF (PO_LOG.d_proc) THEN
525     PO_LOG.proc_begin(d_module);
526   END IF;
527 
528   -- get all invalid lines from cursor
529   OPEN c_invalid_action_lines(PO_PDOI_PARAMS.g_processing_id,
530                               PO_PDOI_PARAMS.g_current_round_num);
531 
532   d_position := 10;
533 
534   FETCH c_invalid_action_lines
535   BULK COLLECT INTO
536     l_rej_intf_line_id_tbl, l_rej_intf_header_id_tbl, l_rej_line_action_tbl;
537 
538   d_position := 20;
539 
540   IF (PO_LOG.d_stmt) THEN
541     PO_LOG.stmt(d_module, d_position, 'count of lines with invalid actions',
542               l_rej_intf_line_id_tbl.COUNT);
543   END IF;
544 
545   -- add error if an invalid line is found
546   FOR i IN 1..l_rej_intf_line_id_tbl.COUNT
547   LOOP
548     d_position := 30;
549 
550     IF (PO_LOG.d_stmt) THEN
551       PO_LOG.stmt(d_module, d_position, 'rejected interface line id',
552                   l_rej_intf_line_id_tbl(i));
553     END IF;
554 
555     PO_PDOI_ERR_UTL.add_fatal_error
556     (
557       p_interface_header_id  => l_rej_intf_header_id_tbl(i),
558       p_interface_line_id    => l_rej_intf_line_id_tbl(i),
559       p_error_message_name   => 'PO_PDOI_INVALID_ACTION',
560       p_table_name           => 'PO_LINES_INTERFACE',
561       p_column_name          => 'ACTION',
562       p_column_value         => l_rej_line_action_tbl(i),
563       p_token1_name          => 'VALUE',
564       p_token1_value         => l_rej_line_action_tbl(i)
565     );
566   END LOOP;
567 
568   d_position := 40;
569 
570   -- reject the lines and the lower level entities associated with it
571   PO_PDOI_UTL.reject_lines_intf
572   (
573     p_id_param_type           => PO_PDOI_CONSTANTS.g_INTERFACE_LINE_ID,
574     p_id_tbl                  => l_rej_intf_line_id_tbl,
575     p_cascade                 => FND_API.g_TRUE
576   );
577 
578   d_position := 50;
579 
580   CLOSE c_invalid_action_lines;
581 
582   IF (PO_LOG.d_proc) THEN
583     PO_LOG.proc_end (d_module);
584   END IF;
585 
586 EXCEPTION
587   WHEN OTHERS THEN
588     PO_MESSAGE_S.add_exc_msg
589     (
590       p_pkg_name => d_pkg_name,
591       p_procedure_name => d_api_name || '.' || d_position
592     );
593     RAISE;
594 END reject_invalid_action_lines;
595 
596 -----------------------------------------------------------------------
597 --Start of Comments
598 --Name: open_lines
599 --Function: open the correct cursor to retrieve line records
600 --Parameters:
601 --IN:
602 --  p_data_set_type
603 --    flag to indicate what kind of lines should be retrieved
604 --  p_max_intf_line_id
605 --    maximal interface_line_id processed in previous batches
606 --IN OUT:
607 --  x_lines_csr
608 --    cursor to point to the first record in the result batch
609 --OUT:
610 --End of Comments
611 ------------------------------------------------------------------------
612 PROCEDURE open_lines
613 (
614   p_data_set_type      IN NUMBER,
615   p_max_intf_line_id   IN NUMBER,
616   x_lines_csr          OUT NOCOPY PO_PDOI_TYPES.intf_cursor_type
617 ) IS
618 
619   d_api_name CONSTANT VARCHAR2(30) := 'open_lines';
620   d_module   CONSTANT VARCHAR2(255) := d_pkg_name || d_api_name || '.';
621   d_position NUMBER;
622 
623 BEGIN
624   d_position := 0;
625 
626   IF (PO_LOG.d_proc) THEN
627     PO_LOG.proc_begin(d_module, 'p_data_set_type', p_data_set_type);
628     PO_LOG.proc_begin(d_module, 'p_max_intf_line_id', p_max_intf_line_id);
629   END IF;
630 
631   -- bug5107324
632   -- cursor now selects NULL into allow_desc_update_flag_tbl as well
633 
634   IF (p_data_set_type = PO_PDOI_CONSTANTS.g_LINE_CSR_ADD) THEN
635     d_position := 10;
636 
637     OPEN x_lines_csr FOR
638       SELECT intf_lines.interface_line_id,
639              intf_lines.interface_header_id,
640              intf_lines.po_header_id,
641              NULL, -- intf_lines.po_line_id,
642              intf_lines.action,
643              intf_lines.document_num,
644              intf_lines.item,
645              intf_lines.vendor_product_num,
646              intf_lines.supplier_part_auxid,
647              intf_lines.item_id,
648              intf_lines.item_revision,
649              intf_lines.job_business_group_name,
650              intf_lines.job_business_group_id,
651              intf_lines.job_name,
652              intf_lines.job_id,
653              intf_lines.category,
654              intf_lines.category_id,
655              intf_lines.ip_category_name,
656              intf_lines.ip_category_id,
657              intf_lines.uom_code,
658              intf_lines.unit_of_measure,
659              intf_lines.line_type,
660              intf_lines.line_type_id,
661              intf_lines.un_number,
662              intf_lines.un_number_id,
663              intf_lines.hazard_class,
664              intf_lines.hazard_class_id,
665              intf_lines.template_name,
666              intf_lines.template_id,
667              intf_lines.item_description,
668              intf_lines.unit_price,
669              intf_lines.base_unit_price,
670              intf_lines.from_header_id,
671              intf_lines.from_line_id,
672              intf_lines.list_price_per_unit,
673              intf_lines.market_price,
674              intf_lines.capital_expense_flag,
675              intf_lines.min_release_amount,
676              intf_lines.allow_price_override_flag,
677              intf_lines.price_type,
678              intf_lines.price_break_lookup_code,
679              intf_lines.closed_code,
680              intf_lines.quantity,
681              intf_lines.line_num,
682              intf_lines.shipment_num,
683              intf_lines.price_chg_accept_flag,
684              intf_lines.effective_date,
685              intf_lines.expiration_date,
686              intf_lines.line_attribute14,
687              intf_lines.price_update_tolerance,
688              intf_lines.line_loc_populated_flag,
689              intf_lines.negotiated_by_preparer_flag,
690              intf_lines.amount,
691              intf_lines.contractor_last_name,
692              intf_lines.contractor_first_name,
693              intf_lines.over_tolerance_error_flag,
694              intf_lines.not_to_exceed_price,
695              intf_lines.po_release_id,
696              intf_lines.release_num,
697              intf_lines.source_shipment_id,
698              intf_lines.contract_num,
699              intf_lines.contract_id,
700              intf_lines.type_1099,
701              intf_lines.closed_by,
702              intf_lines.closed_date,
703              intf_lines.committed_amount,
704              intf_lines.qty_rcv_exception_code,
705              intf_lines.weight_uom_code,
706              intf_lines.volume_uom_code,
707              intf_lines.secondary_unit_of_measure,
708              intf_lines.secondary_quantity,
709              intf_lines.preferred_grade,
710              intf_lines.process_code,
711              NULL, -- parent_interface_line_id -- bug5149827
712              intf_lines.file_line_language, -- bug 5489942
713 
714              -- standard who columns
715              intf_lines.last_updated_by,
716              intf_lines.last_update_date,
717              intf_lines.last_update_login,
718              intf_lines.creation_date,
719              intf_lines.created_by,
720              intf_lines.request_id,
721              intf_lines.program_application_id,
722              intf_lines.program_id,
723              intf_lines.program_update_date,
724 
725              -- attributes read from headers
726              intf_headers.draft_id,
727              intf_headers.action,
728              intf_headers.po_header_id,
729              draft_headers.vendor_id,
730              draft_headers.min_release_amount,
731              draft_headers.start_date,
732              draft_headers.end_date,
733              draft_headers.global_agreement_flag,
734              draft_headers.currency_code,
735              draft_headers.created_language,
736              draft_headers.style_id,
737              draft_headers.rate_type,
738 
739              -- txn table columns
740              NULL, -- order_type_lookup_code
741              NULL, -- purchase_basis
742              NULL, -- matching_basis
743              NULL, -- unordered_flag
744              NULL, -- cancel_flag
745              NULL, -- quantity_committed
746              NULL, -- tax_attribute_update_code
747 
748              DECODE(intf_lines.process_code,
749                     PO_PDOI_CONSTANTS.g_PROCESS_CODE_VAL_AND_REJECT,
750                     FND_API.g_TRUE, FND_API.g_FALSE), -- error_flag_tbl
751              FND_API.g_FALSE,                    -- need_to_reject_flag_tbl
752              FND_API.g_FALSE,                    -- create_line_loc_tbl
753              -1,                                 -- group_num
754              NULL,                               -- origin_line_num
755              FND_API.g_FALSE,                    -- match_line_found
756              NULL                                -- allow_desc_update_flag_tbl
757       FROM   po_lines_interface intf_lines,
758              po_headers_interface intf_headers,
759              po_headers_draft_all draft_headers
760       WHERE  intf_lines.interface_header_id = intf_headers.interface_header_id
761       AND    intf_headers.draft_id = draft_headers.draft_id
762       AND    intf_headers.po_header_id = draft_headers.po_header_id
763       AND    intf_lines.processing_id = PO_PDOI_PARAMS.g_processing_id
764       AND    intf_headers.processing_round_num = PO_PDOI_PARAMS.g_current_round_num
765       AND    intf_headers.processing_id = PO_PDOI_PARAMS.g_processing_id
766       AND    intf_lines.interface_line_id > p_max_intf_line_id
767       AND    intf_headers.action IN (PO_PDOI_CONSTANTS.g_ACTION_ORIGINAL,
768                                      PO_PDOI_CONSTANTS.g_ACTION_REPLACE)
769 
770       UNION ALL
771 
772       SELECT intf_lines.interface_line_id,
773              intf_lines.interface_header_id,
774              intf_lines.po_header_id,
775              NULL, -- intf_lines.po_line_id,
776              intf_lines.action,
777              intf_lines.document_num,
778              intf_lines.item,
779              intf_lines.vendor_product_num,
780              intf_lines.supplier_part_auxid,
781              intf_lines.item_id,
782              intf_lines.item_revision,
783              intf_lines.job_business_group_name,
784              intf_lines.job_business_group_id,
785              intf_lines.job_name,
786              intf_lines.job_id,
787              intf_lines.category,
788              intf_lines.category_id,
789              intf_lines.ip_category_name,
790              intf_lines.ip_category_id,
791              intf_lines.uom_code,
792              intf_lines.unit_of_measure,
793              intf_lines.line_type,
794              intf_lines.line_type_id,
795              intf_lines.un_number,
796              intf_lines.un_number_id,
797              intf_lines.hazard_class,
798              intf_lines.hazard_class_id,
799              intf_lines.template_name,
800              intf_lines.template_id,
801              intf_lines.item_description,
802              intf_lines.unit_price,
803              intf_lines.base_unit_price,
804              intf_lines.from_header_id,
805              intf_lines.from_line_id,
806              intf_lines.list_price_per_unit,
807              intf_lines.market_price,
808              intf_lines.capital_expense_flag,
809              intf_lines.min_release_amount,
810              intf_lines.allow_price_override_flag,
811              intf_lines.price_type,
812              intf_lines.price_break_lookup_code,
813              intf_lines.closed_code,
814              intf_lines.quantity,
815              intf_lines.line_num,
816              intf_lines.shipment_num,
817              intf_lines.price_chg_accept_flag,
818              intf_lines.effective_date,
819              intf_lines.expiration_date,
820              intf_lines.line_attribute14,
821              intf_lines.price_update_tolerance,
822              intf_lines.line_loc_populated_flag,
823              intf_lines.negotiated_by_preparer_flag,
824              intf_lines.amount,
825              intf_lines.contractor_last_name,
826              intf_lines.contractor_first_name,
827              intf_lines.over_tolerance_error_flag,
828              intf_lines.not_to_exceed_price,
829              intf_lines.po_release_id,
830              intf_lines.release_num,
831              intf_lines.source_shipment_id,
832              intf_lines.contract_num,
833              intf_lines.contract_id,
834              intf_lines.type_1099,
835              intf_lines.closed_by,
836              intf_lines.closed_date,
837              intf_lines.committed_amount,
838              intf_lines.qty_rcv_exception_code,
839              intf_lines.weight_uom_code,
840              intf_lines.volume_uom_code,
841              intf_lines.secondary_unit_of_measure,
842              intf_lines.secondary_quantity,
843              intf_lines.preferred_grade,
844              intf_lines.process_code,
845              NULL, -- parent_interface_line_id -- bug5149827
846              intf_lines.file_line_language, -- bug 5489942
847 
848              -- standard who columns
849              intf_lines.last_updated_by,
850              intf_lines.last_update_date,
851              intf_lines.last_update_login,
852              intf_lines.creation_date,
853              intf_lines.created_by,
854              intf_lines.request_id,
855              intf_lines.program_application_id,
856              intf_lines.program_id,
857              intf_lines.program_update_date,
858 
859              -- attributes read from header
860              intf_headers.draft_id,
861              intf_headers.action,
862              intf_headers.po_header_id,
863              txn_headers.vendor_id,
864              txn_headers.min_release_amount,
865              txn_headers.start_date,
866              txn_headers.end_date,
867              txn_headers.global_agreement_flag,
868              txn_headers.currency_code,
869              txn_headers.created_language,
870              txn_headers.style_id,
871              txn_headers.rate_type,
872 
873              -- txn table columns
874              NULL, -- order_type_lookup_code
875              NULL, -- purchase_basis
876              NULL, -- matching_basis
877              NULL, -- unordered_flag
878              NULL, -- cancel_flag
879              NULL, -- quantity_committed
880              NULL, -- tax_attribute_update_code
881 
882              DECODE(intf_lines.process_code, PO_PDOI_CONSTANTS.g_PROCESS_CODE_VAL_AND_REJECT,
883                FND_API.g_TRUE, FND_API.g_FALSE),  -- error_flag_tbl
884              FND_API.G_FALSE,                     -- need_to_reject_flag_tbl
885        FND_API.g_FALSE,                     -- create_line_loc_tbl
886              -1,                                  -- group_num
887              NULL,                               -- origin_line_num
888              FND_API.g_FALSE,                    -- match_line_found
889              NULL                                -- allow_desc_update_flag_tbl
890       FROM   po_lines_interface intf_lines,
891              po_headers_interface intf_headers,
892              po_headers txn_headers
893       WHERE  intf_lines.interface_header_id = intf_headers.interface_header_id
894       AND    intf_headers.po_header_id = txn_headers.po_header_id
895       AND    intf_lines.processing_id = PO_PDOI_PARAMS.g_processing_id
896       AND    intf_headers.processing_round_num = PO_PDOI_PARAMS.g_current_round_num
897       AND    intf_headers.processing_id = PO_PDOI_PARAMS.g_processing_id
898       AND    intf_lines.interface_line_id > p_max_intf_line_id
899       AND    intf_headers.action = PO_PDOI_CONSTANTS.g_ACTION_UPDATE
900       AND    PO_PDOI_PARAMS.g_request.document_type = PO_PDOI_CONSTANTS.g_DOC_TYPE_STANDARD
901       ORDER BY 1;
902   ELSIF (p_data_set_type = PO_PDOI_CONSTANTS.g_LINE_CSR_FORCE_ADD) THEN
903     d_position := 20;
904 
905     OPEN x_lines_csr FOR
906       SELECT intf_lines.interface_line_id,
907              intf_lines.interface_header_id,
908              intf_lines.po_header_id,
909              NULL, -- intf_lines.po_line_id,
910              intf_lines.action,
911              intf_lines.document_num,
912              intf_lines.item,
913              intf_lines.vendor_product_num,
914              intf_lines.supplier_part_auxid,
915              intf_lines.item_id,
916              intf_lines.item_revision,
917              intf_lines.job_business_group_name,
918              intf_lines.job_business_group_id,
919              intf_lines.job_name,
920              intf_lines.job_id,
921              intf_lines.category,
922              intf_lines.category_id,
923              intf_lines.ip_category_name,
924              intf_lines.ip_category_id,
925              intf_lines.uom_code,
926              intf_lines.unit_of_measure,
927              intf_lines.line_type,
928              intf_lines.line_type_id,
929              intf_lines.un_number,
930              intf_lines.un_number_id,
931              intf_lines.hazard_class,
932              intf_lines.hazard_class_id,
933              intf_lines.template_name,
934              intf_lines.template_id,
935              intf_lines.item_description,
936              intf_lines.unit_price,
937              intf_lines.base_unit_price,
938              intf_lines.from_header_id,
939              intf_lines.from_line_id,
940              intf_lines.list_price_per_unit,
941              intf_lines.market_price,
942              intf_lines.capital_expense_flag,
943              intf_lines.min_release_amount,
944              intf_lines.allow_price_override_flag,
945              intf_lines.price_type,
946              intf_lines.price_break_lookup_code,
947              intf_lines.closed_code,
948              intf_lines.quantity,
949              intf_lines.line_num,
950              intf_lines.shipment_num,
951              intf_lines.price_chg_accept_flag,
952              intf_lines.effective_date,
953              intf_lines.expiration_date,
954              intf_lines.line_attribute14,
955              intf_lines.price_update_tolerance,
956              intf_lines.line_loc_populated_flag,
957              intf_lines.negotiated_by_preparer_flag,
958              intf_lines.amount,
959              intf_lines.contractor_last_name,
960              intf_lines.contractor_first_name,
961              intf_lines.over_tolerance_error_flag,
962              intf_lines.not_to_exceed_price,
963              intf_lines.po_release_id,
964              intf_lines.release_num,
965              intf_lines.source_shipment_id,
966              intf_lines.contract_num,
967              intf_lines.contract_id,
968              intf_lines.type_1099,
969              intf_lines.closed_by,
970              intf_lines.closed_date,
971              intf_lines.committed_amount,
972              intf_lines.qty_rcv_exception_code,
973              intf_lines.weight_uom_code,
974              intf_lines.volume_uom_code,
975              intf_lines.secondary_unit_of_measure,
976              intf_lines.secondary_quantity,
977              intf_lines.preferred_grade,
978              intf_lines.process_code,
979              NULL, -- parent_interface_line_id -- bug5149827
980              intf_lines.file_line_language, -- bug 5489942
981 
982              -- standard who columns
983              intf_lines.last_updated_by,
984              intf_lines.last_update_date,
985              intf_lines.last_update_login,
986              intf_lines.creation_date,
987              intf_lines.created_by,
988              intf_lines.request_id,
989              intf_lines.program_application_id,
990              intf_lines.program_id,
991              intf_lines.program_update_date,
992 
993              -- attributes read from header
994              intf_headers.draft_id,
995              intf_headers.action,
996              intf_headers.po_header_id,
997              txn_headers.vendor_id,
998              txn_headers.min_release_amount,
999              txn_headers.start_date,
1000              txn_headers.end_date,
1001              txn_headers.global_agreement_flag,
1002              txn_headers.currency_code,
1003              txn_headers.created_language,
1004              txn_headers.style_id,
1005              txn_headers.rate_type,
1006 
1007              -- txn table columns
1008              NULL, -- order_type_lookup_code
1009              NULL, -- purchase_basis
1010              NULL, -- matching_basis
1011              NULL, -- unordered_flag
1012              NULL, -- cancel_flag
1013              NULL, -- quantity_committed
1014              NULL, -- tax_attribute_update_code
1015 
1016              DECODE(intf_lines.process_code, PO_PDOI_CONSTANTS.g_PROCESS_CODE_VAL_AND_REJECT,
1017                FND_API.g_TRUE, FND_API.g_FALSE),   -- error_flag_tbl
1018              FND_API.G_FALSE,                      -- need_to_reject_flag_tbl
1019        FND_API.g_FALSE,                      -- create_line_loc_tbl
1020              -1,                                   -- group_num
1021              NULL,                                 -- origin_line_num
1022              FND_API.g_FALSE,                      -- match_line_found
1023              NULL                                 -- allow_desc_update_flag_tbl
1024       FROM   po_lines_interface intf_lines,
1025              po_headers_interface intf_headers,
1026              po_headers txn_headers
1027       WHERE  intf_lines.interface_header_id = intf_headers.interface_header_id
1028       AND    intf_headers.po_header_id = txn_headers.po_header_id
1029       AND    intf_lines.processing_id = PO_PDOI_PARAMS.g_processing_id
1030       AND    intf_headers.processing_round_num = PO_PDOI_PARAMS.g_current_round_num
1031       AND    intf_headers.processing_id = PO_PDOI_PARAMS.g_processing_id
1032       AND    intf_lines.interface_line_id > p_max_intf_line_id
1033       AND    intf_headers.action = PO_PDOI_CONSTANTS.g_ACTION_UPDATE
1034       AND    PO_PDOI_PARAMS.g_request.document_type IN
1035                (PO_PDOI_CONSTANTS.g_DOC_TYPE_BLANKET,
1036                 PO_PDOI_CONSTANTS.g_DOC_TYPE_QUOTATION)
1037       AND    intf_lines.action = PO_PDOI_CONSTANTS.g_ACTION_ADD
1038       ORDER BY intf_lines.interface_line_id;
1039   ELSIF (p_data_set_type = PO_PDOI_CONSTANTS.g_LINE_CSR_SYNC) THEN
1040     d_position := 30;
1041 
1042     OPEN x_lines_csr FOR
1043       SELECT intf_lines.interface_line_id,
1044              intf_lines.interface_header_id,
1045              intf_lines.po_header_id,
1046              NULL, -- intf_lines.po_line_id,
1047              intf_lines.action,
1048              intf_lines.document_num,
1049              intf_lines.item,
1050              intf_lines.vendor_product_num,
1051              intf_lines.supplier_part_auxid,
1052              intf_lines.item_id,
1053              intf_lines.item_revision,
1054              intf_lines.job_business_group_name,
1055              intf_lines.job_business_group_id,
1056              intf_lines.job_name,
1057              intf_lines.job_id,
1058              intf_lines.category,
1059              intf_lines.category_id,
1060              intf_lines.ip_category_name,
1061              intf_lines.ip_category_id,
1062              intf_lines.uom_code,
1063              intf_lines.unit_of_measure,
1064              intf_lines.line_type,
1065              intf_lines.line_type_id,
1066              intf_lines.un_number,
1067              intf_lines.un_number_id,
1068              intf_lines.hazard_class,
1069              intf_lines.hazard_class_id,
1070              intf_lines.template_name,
1071              intf_lines.template_id,
1072              intf_lines.item_description,
1073              intf_lines.unit_price,
1074              intf_lines.base_unit_price,
1075              intf_lines.from_header_id,
1076              intf_lines.from_line_id,
1077              intf_lines.list_price_per_unit,
1078              intf_lines.market_price,
1079              intf_lines.capital_expense_flag,
1080              intf_lines.min_release_amount,
1081              intf_lines.allow_price_override_flag,
1082              intf_lines.price_type,
1083              intf_lines.price_break_lookup_code,
1084              intf_lines.closed_code,
1085              intf_lines.quantity,
1086              intf_lines.line_num,
1087              intf_lines.shipment_num,
1088              intf_lines.price_chg_accept_flag,
1089              intf_lines.effective_date,
1090              intf_lines.expiration_date,
1091              intf_lines.line_attribute14,
1092              intf_lines.price_update_tolerance,
1093              intf_lines.line_loc_populated_flag,
1094              intf_lines.negotiated_by_preparer_flag,
1095              intf_lines.amount,
1096              intf_lines.contractor_last_name,
1097              intf_lines.contractor_first_name,
1098              intf_lines.over_tolerance_error_flag,
1099              intf_lines.not_to_exceed_price,
1100              intf_lines.po_release_id,
1101              intf_lines.release_num,
1102              intf_lines.source_shipment_id,
1103              intf_lines.contract_num,
1104              intf_lines.contract_id,
1105              intf_lines.type_1099,
1106              intf_lines.closed_by,
1107              intf_lines.closed_date,
1108              intf_lines.committed_amount,
1109              intf_lines.qty_rcv_exception_code,
1110              intf_lines.weight_uom_code,
1111              intf_lines.volume_uom_code,
1112              intf_lines.secondary_unit_of_measure,
1113              intf_lines.secondary_quantity,
1114              intf_lines.preferred_grade,
1115              intf_lines.process_code,
1116              NULL, -- parent_interface_line_id -- bug5149827
1117              intf_lines.file_line_language, -- bug 5489942
1118 
1119              -- standard who columns
1120              intf_lines.last_updated_by,
1121              intf_lines.last_update_date,
1122              intf_lines.last_update_login,
1123              intf_lines.creation_date,
1124              intf_lines.created_by,
1125              intf_lines.request_id,
1126              intf_lines.program_application_id,
1127              intf_lines.program_id,
1128              intf_lines.program_update_date,
1129 
1130              -- attributes read from header
1131              intf_headers.draft_id,
1132              intf_headers.action,
1133              intf_headers.po_header_id,
1134              txn_headers.vendor_id,
1135              txn_headers.min_release_amount,
1136              txn_headers.start_date,
1137              txn_headers.end_date,
1138              txn_headers.global_agreement_flag,
1139              txn_headers.currency_code,
1140              txn_headers.created_language,
1141              txn_headers.style_id,
1142              txn_headers.rate_type,
1143 
1144              -- txn table columns
1145              NULL, -- order_type_lookup_code
1146              NULL, -- purchase_basis
1147              NULL, -- matching_basis
1148              NULL, -- unordered_flag
1149              NULL, -- cancel_flag
1150              NULL, -- quantity_committed
1151              NULL, -- tax_attribute_update_code
1152 
1153              DECODE(intf_lines.process_code, PO_PDOI_CONSTANTS.g_PROCESS_CODE_VAL_AND_REJECT,
1154                FND_API.g_TRUE, FND_API.g_FALSE),   -- error_flag_tbl
1155              FND_API.G_FALSE,                      -- need_to_reject_flag_tbl
1156              FND_API.g_FALSE,                      -- create_line_loc_tbl
1157              -1,                                   -- group_num
1158              NULL,                                 -- origin_line_num
1159              FND_API.g_FALSE,                      -- match_line_found
1160              NULL                                -- allow_desc_update_flag_tbl
1161       FROM   po_lines_interface intf_lines,
1162              po_headers_interface intf_headers,
1163              po_headers txn_headers
1164       WHERE  intf_lines.interface_header_id = intf_headers.interface_header_id
1165       AND    intf_headers.po_header_id = txn_headers.po_header_id
1166       AND    intf_lines.processing_id = PO_PDOI_PARAMS.g_processing_id
1167       AND    intf_headers.processing_round_num = PO_PDOI_PARAMS.g_current_round_num
1168       AND    intf_headers.processing_id = PO_PDOI_PARAMS.g_processing_id
1169       AND    intf_lines.interface_line_id > p_max_intf_line_id
1170       AND    intf_headers.action = PO_PDOI_CONSTANTS.g_ACTION_UPDATE
1171       AND    PO_PDOI_PARAMS.g_request.document_type IN
1172                (PO_PDOI_CONSTANTS.g_DOC_TYPE_BLANKET,
1173                 PO_PDOI_CONSTANTS.g_DOC_TYPE_QUOTATION)
1174       AND    intf_lines.action IS NULL
1175       AND    NOT (intf_lines.item IS NULL AND
1176                   intf_lines.vendor_product_num IS NULL AND
1177                   intf_lines.job_name IS NULL AND
1178                   intf_lines.item_description IS NOT NULL)
1179       ORDER BY intf_lines.interface_line_id;
1180   ELSIF (p_data_set_type = PO_PDOI_CONSTANTS.g_LINE_CSR_SYNC_ON_DESC) THEN
1181     d_position := 40;
1182 
1183     OPEN x_lines_csr FOR
1184       SELECT intf_lines.interface_line_id,
1185              intf_lines.interface_header_id,
1186              intf_lines.po_header_id,
1187              NULL, -- intf_lines.po_line_id,
1188              intf_lines.action,
1189              intf_lines.document_num,
1190              intf_lines.item,
1191              intf_lines.vendor_product_num,
1192              intf_lines.supplier_part_auxid,
1193              intf_lines.item_id,
1194              intf_lines.item_revision,
1195              intf_lines.job_business_group_name,
1196              intf_lines.job_business_group_id,
1197              intf_lines.job_name,
1198              intf_lines.job_id,
1199              intf_lines.category,
1200              intf_lines.category_id,
1201              intf_lines.ip_category_name,
1202              intf_lines.ip_category_id,
1203              intf_lines.uom_code,
1204              intf_lines.unit_of_measure,
1205              intf_lines.line_type,
1206              intf_lines.line_type_id,
1207              intf_lines.un_number,
1208              intf_lines.un_number_id,
1209              intf_lines.hazard_class,
1210              intf_lines.hazard_class_id,
1211              intf_lines.template_name,
1212              intf_lines.template_id,
1213              intf_lines.item_description,
1214              intf_lines.unit_price,
1215              intf_lines.base_unit_price,
1216              intf_lines.from_header_id,
1217              intf_lines.from_line_id,
1218              intf_lines.list_price_per_unit,
1219              intf_lines.market_price,
1220              intf_lines.capital_expense_flag,
1221              intf_lines.min_release_amount,
1222              intf_lines.allow_price_override_flag,
1223              intf_lines.price_type,
1224              intf_lines.price_break_lookup_code,
1225              intf_lines.closed_code,
1226              intf_lines.quantity,
1227              intf_lines.line_num,
1228              intf_lines.shipment_num,
1229              intf_lines.price_chg_accept_flag,
1230              intf_lines.effective_date,
1231              intf_lines.expiration_date,
1232              intf_lines.line_attribute14,
1233              intf_lines.price_update_tolerance,
1234              intf_lines.line_loc_populated_flag,
1235              intf_lines.negotiated_by_preparer_flag,
1236              intf_lines.amount,
1237              intf_lines.contractor_last_name,
1238              intf_lines.contractor_first_name,
1239              intf_lines.over_tolerance_error_flag,
1240              intf_lines.not_to_exceed_price,
1241              intf_lines.po_release_id,
1242              intf_lines.release_num,
1243              intf_lines.source_shipment_id,
1244              intf_lines.contract_num,
1245              intf_lines.contract_id,
1246              intf_lines.type_1099,
1247              intf_lines.closed_by,
1248              intf_lines.closed_date,
1249              intf_lines.committed_amount,
1250              intf_lines.qty_rcv_exception_code,
1251              intf_lines.weight_uom_code,
1252              intf_lines.volume_uom_code,
1253              intf_lines.secondary_unit_of_measure,
1254              intf_lines.secondary_quantity,
1255              intf_lines.preferred_grade,
1256              intf_lines.process_code,
1257              NULL, -- parent_interface_line_id -- bug5149827
1258              intf_lines.file_line_language, -- bug 5489942
1259 
1260              -- standard who columns
1261              intf_lines.last_updated_by,
1262              intf_lines.last_update_date,
1263              intf_lines.last_update_login,
1264              intf_lines.creation_date,
1265              intf_lines.created_by,
1266              intf_lines.request_id,
1267              intf_lines.program_application_id,
1268              intf_lines.program_id,
1269              intf_lines.program_update_date,
1270 
1271              -- attributes read from header
1272              intf_headers.draft_id,
1273              intf_headers.action,
1274              intf_headers.po_header_id,
1275              txn_headers.vendor_id,
1276              txn_headers.min_release_amount,
1277              txn_headers.start_date,
1278              txn_headers.end_date,
1279              txn_headers.global_agreement_flag,
1280              txn_headers.currency_code,
1281              txn_headers.created_language,
1282              txn_headers.style_id,
1283              txn_headers.rate_type,
1284 
1285              -- txn table columns
1286              NULL, -- order_type_lookup_code
1287              NULL, -- purchase_basis
1288              NULL, -- matching_basis
1289              NULL, -- unordered_flag
1290              NULL, -- cancel_flag
1291              NULL, -- quantity_committed
1292              NULL, -- tax_attribute_update_code
1293 
1294              DECODE(intf_lines.process_code, PO_PDOI_CONSTANTS.g_PROCESS_CODE_VAL_AND_REJECT,
1295                FND_API.g_TRUE, FND_API.g_FALSE),   -- error_flag_tbl
1296              FND_API.G_FALSE,                      -- need_to_reject_flag_tbl
1297              FND_API.g_FALSE,                      -- create_line_loc_tbl
1298              -1,                                   -- group_num
1299              NULL,                                 -- origin_line_num
1300              FND_API.g_FALSE,                      -- match_line_found
1301              NULL                                -- allow_desc_update_flag_tbl
1302       FROM   po_lines_interface intf_lines,
1303              po_headers_interface intf_headers,
1304              po_headers txn_headers
1305       WHERE  intf_lines.interface_header_id = intf_headers.interface_header_id
1306       AND    intf_headers.po_header_id = txn_headers.po_header_id
1307       AND    intf_lines.processing_id = PO_PDOI_PARAMS.g_processing_id
1308       AND    intf_headers.processing_round_num = PO_PDOI_PARAMS.g_current_round_num
1309       AND    intf_headers.processing_id = PO_PDOI_PARAMS.g_processing_id
1310       AND    intf_lines.interface_line_id > p_max_intf_line_id
1311       AND    intf_headers.action = PO_PDOI_CONSTANTS.g_ACTION_UPDATE
1312       AND    PO_PDOI_PARAMS.g_request.document_type IN
1313                (PO_PDOI_CONSTANTS.g_DOC_TYPE_BLANKET,
1314                 PO_PDOI_CONSTANTS.g_DOC_TYPE_QUOTATION)
1315       AND    intf_lines.action IS NULL
1316       AND    intf_lines.item IS NULL
1317       AND    intf_lines.vendor_product_num IS NULL
1318       AND    intf_lines.job_name IS NULL
1319       AND    intf_lines.item_description IS NOT NULL
1320       ORDER BY intf_lines.interface_line_id;
1321   ELSE
1322     d_position := 50;
1323 
1324     NULL;
1325   END IF;
1326 
1327   IF (PO_LOG.d_proc) THEN
1328     PO_LOG.proc_end (d_module);
1329   END IF;
1330 
1331 EXCEPTION
1332   WHEN OTHERS THEN
1333     PO_MESSAGE_S.add_exc_msg
1334     (
1335       p_pkg_name => d_pkg_name,
1336       p_procedure_name => d_api_name || '.' || d_position
1337     );
1338     RAISE;
1339 END open_lines;
1340 
1341 -----------------------------------------------------------------------
1342 --Start of Comments
1343 --Name: fetch_lines
1344 --Function: fetch the line records based on batch size
1345 --Parameters:
1346 --IN:
1347 --IN OUT:
1348 --  x_lines_csr
1349 --    cursor to point to the first record in the result batch
1350 --  x_lines
1351 --    record to store all the line rows within the batch
1352 --OUT:
1353 --End of Comments
1354 ------------------------------------------------------------------------
1355 PROCEDURE fetch_lines
1356 (
1357   x_lines_csr   IN OUT NOCOPY PO_PDOI_TYPES.intf_cursor_type,
1358   x_lines       OUT NOCOPY PO_PDOI_TYPES.lines_rec_type
1359 ) IS
1360 
1361   d_api_name CONSTANT VARCHAR2(30) := 'fetch_lines';
1362   d_module   CONSTANT VARCHAR2(255) := d_pkg_name || d_api_name || '.';
1363   d_position NUMBER;
1364 
1365 BEGIN
1366   d_position := 0;
1367 
1368   IF (PO_LOG.d_proc) THEN
1369     PO_LOG.proc_begin(d_module);
1370   END IF;
1371 
1372   FETCH x_lines_csr BULK COLLECT INTO
1373     x_lines.intf_line_id_tbl,
1374     x_lines.intf_header_id_tbl,
1375     x_lines.po_header_id_tbl,
1376     x_lines.po_line_id_tbl,
1377     x_lines.action_tbl,
1378     x_lines.document_num_tbl,
1379     x_lines.item_tbl,
1380     x_lines.vendor_product_num_tbl,
1381     x_lines.supplier_part_auxid_tbl,
1382     x_lines.item_id_tbl,
1383     x_lines.item_revision_tbl,
1384     x_lines.job_business_group_name_tbl,
1385     x_lines.job_business_group_id_tbl,
1386     x_lines.job_name_tbl,
1387     x_lines.job_id_tbl,
1388     x_lines.category_tbl,
1389     x_lines.category_id_tbl,
1390     x_lines.ip_category_tbl,
1391     x_lines.ip_category_id_tbl,
1392     x_lines.uom_code_tbl,
1393     x_lines.unit_of_measure_tbl,
1394     x_lines.line_type_tbl,
1395     x_lines.line_type_id_tbl,
1396     x_lines.un_number_tbl,
1397     x_lines.un_number_id_tbl,
1398     x_lines.hazard_class_tbl,
1399     x_lines.hazard_class_id_tbl,
1400     x_lines.template_name_tbl,
1401     x_lines.template_id_tbl,
1402     x_lines.item_desc_tbl,
1403     x_lines.unit_price_tbl,
1404     x_lines.base_unit_price_tbl,
1405     x_lines.from_header_id_tbl,
1406     x_lines.from_line_id_tbl,
1407     x_lines.list_price_per_unit_tbl,
1408     x_lines.market_price_tbl,
1409     x_lines.capital_expense_flag_tbl,
1410     x_lines.min_release_amount_tbl,
1411     x_lines.allow_price_override_flag_tbl,
1412     x_lines.price_type_tbl,
1413     x_lines.price_break_lookup_code_tbl,
1414     x_lines.closed_code_tbl,
1415     x_lines.quantity_tbl,
1416     x_lines.line_num_tbl,
1417     x_lines.shipment_num_tbl,
1418     x_lines.price_chg_accept_flag_tbl,
1419     x_lines.effective_date_tbl,
1420     x_lines.expiration_date_tbl,
1421     x_lines.attribute14_tbl,
1422     x_lines.price_update_tolerance_tbl,
1423     x_lines.line_loc_populated_flag_tbl,
1424     x_lines.negotiated_flag_tbl,
1425     x_lines.amount_tbl,
1426     x_lines.contractor_last_name_tbl,
1427     x_lines.contractor_first_name_tbl,
1428     x_lines.over_tolerance_err_flag_tbl,
1429     x_lines.not_to_exceed_price_tbl,
1430     x_lines.po_release_id_tbl,
1431     x_lines.release_num_tbl,
1432     x_lines.source_shipment_id_tbl,
1433     x_lines.contract_num_tbl,
1434     x_lines.contract_id_tbl,
1435     x_lines.type_1099_tbl,
1436     x_lines.closed_by_tbl,
1437     x_lines.closed_date_tbl,
1438     x_lines.committed_amount_tbl,
1439     x_lines.qty_rcv_exception_code_tbl,
1440     x_lines.weight_uom_code_tbl,
1441     x_lines.volume_uom_code_tbl,
1442     x_lines.secondary_unit_of_meas_tbl,
1443     x_lines.secondary_quantity_tbl,
1444     x_lines.preferred_grade_tbl,
1445     x_lines.process_code_tbl,
1446     x_lines.parent_interface_line_id_tbl, -- bug5149827
1447     x_lines.file_line_language_tbl, -- bug 5489942
1448 
1449     -- standard who columns
1450     x_lines.last_updated_by_tbl,
1451     x_lines.last_update_date_tbl,
1452     x_lines.last_update_login_tbl,
1453     x_lines.creation_date_tbl,
1454     x_lines.created_by_tbl,
1455     x_lines.request_id_tbl,
1456     x_lines.program_application_id_tbl,
1457     x_lines.program_id_tbl,
1458     x_lines.program_update_date_tbl,
1459 
1460     -- attributes read from headers
1461     x_lines.draft_id_tbl,
1462     x_lines.hd_action_tbl,
1463     x_lines.hd_po_header_id_tbl,
1464     x_lines.hd_vendor_id_tbl,
1465     x_lines.hd_min_release_amount_tbl,
1466     x_lines.hd_start_date_tbl,
1467     x_lines.hd_end_date_tbl,
1468     x_lines.hd_global_agreement_flag_tbl,
1469     x_lines.hd_currency_code_tbl,
1470     x_lines.hd_created_language_tbl,
1471     x_lines.hd_style_id_tbl,
1472     x_lines.hd_rate_type_tbl,
1473 
1474     -- txn table columns
1475     x_lines.order_type_lookup_code_tbl,
1476     x_lines.purchase_basis_tbl,
1477     x_lines.matching_basis_tbl,
1478     x_lines.unordered_flag_tbl,
1479     x_lines.cancel_flag_tbl,
1480     x_lines.quantity_committed_tbl,
1481     x_lines.tax_attribute_update_code_tbl,
1482 
1483     x_lines.error_flag_tbl,
1484     x_lines.need_to_reject_flag_tbl,
1485     x_lines.create_line_loc_tbl,
1486     x_lines.group_num_tbl,
1487     x_lines.origin_line_num_tbl,
1488     x_lines.match_line_found_tbl,
1489     x_lines.allow_desc_update_flag_tbl   -- bug5107324
1490   LIMIT PO_PDOI_CONSTANTS.g_DEF_BATCH_SIZE;
1491 
1492   IF (PO_LOG.d_proc) THEN
1493     PO_LOG.proc_end (d_module);
1494   END IF;
1495 
1496 EXCEPTION
1497   WHEN OTHERS THEN
1498     PO_MESSAGE_S.add_exc_msg
1499     (
1500       p_pkg_name => d_pkg_name,
1501       p_procedure_name => d_api_name || '.' || d_position
1502     );
1503     RAISE;
1504 END fetch_lines;
1505 
1506 -----------------------------------------------------------------------
1507 --Start of Comments
1508 --Name: derive_lines
1509 --Function: peform derivation logic on line attributes
1510 --Parameters:
1511 --IN:
1512 --IN OUT:
1513 --  x_lines
1514 --    record to store all the line rows within the batch;
1515 --    Derivation are performed for certain attributes only
1516 --    if their name value is populated but id value is not.
1517 --OUT:
1518 --End of Comments
1519 ------------------------------------------------------------------------
1520 PROCEDURE derive_lines
1521 (
1522   x_lines       IN OUT NOCOPY PO_PDOI_TYPES.lines_rec_type
1523 ) IS
1524 
1525   d_api_name CONSTANT VARCHAR2(30) := 'derive_lines';
1526   d_module   CONSTANT VARCHAR2(255) := d_pkg_name || d_api_name || '.';
1527   d_position NUMBER;
1528 
1529   -- key of temp table used to identify the derived result
1530   l_key po_session_gt.key%TYPE;
1531 
1532   -- table used to save the index of the each row
1533   l_index_tbl DBMS_SQL.NUMBER_TABLE;
1534 BEGIN
1535   d_position := 0;
1536 
1537   IF (PO_LOG.d_proc) THEN
1538     PO_LOG.proc_begin(d_module, 'line counts', x_lines.rec_count);
1539   END IF;
1540 
1541   PO_TIMING_UTL.start_time(PO_PDOI_CONSTANTS.g_T_LINE_DERIVE);
1542 
1543   -- assign a new key used in temporary table
1544   l_key := PO_CORE_S.get_session_gt_nextval;
1545 
1546   -- initialize table containing the row number(index)
1547   PO_PDOI_UTL.generate_ordered_num_list
1548   (
1549     p_size     => x_lines.rec_count,
1550     x_num_list => l_index_tbl
1551   );
1552 
1553   d_position := 10;
1554 
1555   -- bug5684695
1556   -- The call to derive_po_header_id has been removed
1557 
1558   -- bug 7374337
1559   -- The call to derive category id has been moved from
1560   -- bottom to top so that it can be used in deriving item id
1561   -- when vendor_product_num is passed.
1562   -- derive PO category_id from PO category_name
1563   derive_category_id
1564   (
1565     p_key                  => l_key,
1566     p_category_tbl         => x_lines.category_tbl,
1567     x_category_id_tbl      => x_lines.category_id_tbl
1568   );
1569 
1570   d_position := 20;
1571 
1572   -- derive item_id from item_num
1573   derive_item_id
1574   (
1575     p_key                    => l_key,
1576     p_index_tbl              => l_index_tbl,
1577     p_vendor_id_tbl          => x_lines.hd_vendor_id_tbl,
1578     p_intf_header_id_tbl     => x_lines.intf_header_id_tbl,
1579     p_intf_line_id_tbl       => x_lines.intf_line_id_tbl,
1580     p_vendor_product_num_tbl => x_lines.vendor_product_num_tbl,
1581     p_category_id_tbl        => x_lines.category_id_tbl,
1582 	p_item_tbl               => x_lines.item_tbl,
1583     x_item_id_tbl            => x_lines.item_id_tbl,
1584     x_error_flag_tbl         => x_lines.error_flag_tbl
1585   );
1586 
1587   d_position := 30;
1588 
1589   -- derive item_revision from item_id
1590   derive_item_revision
1591   (
1592     p_key                    => l_key,
1593     p_item_id_tbl            => x_lines.item_id_tbl,
1594     x_item_revision_tbl      => x_lines.item_revision_tbl
1595   );
1596 
1597   d_position := 40;
1598 
1599   -- derive job_business_group_id from job_business_group_name
1600   derive_job_business_group_id
1601   (
1602     p_key                            => l_key,
1603     p_index_tbl                      => l_index_tbl,
1604     p_job_business_group_name_tbl    => x_lines.job_business_group_name_tbl,
1605     x_job_business_group_id_tbl      => x_lines.job_business_group_id_tbl
1606   );
1607 
1608   d_position := 50;
1609 
1610   -- derive job_id from job_name
1611   derive_job_id
1612   (
1613     p_key                            => l_key,
1614     p_index_tbl                      => l_index_tbl,
1615     p_file_line_language_tbl         => x_lines.file_line_language_tbl,
1616     p_job_business_group_name_tbl    => x_lines.job_business_group_name_tbl,
1617     p_job_name_tbl                   => x_lines.job_name_tbl,
1618     x_job_business_group_id_tbl      => x_lines.job_business_group_id_tbl,
1619     x_job_id_tbl                     => x_lines.job_id_tbl
1620   );
1621 
1622   d_position := 60;
1623 
1624   -- derive PO category_id from PO category_name
1625   -- bug 7374337 moved above to derive item id call
1626 
1627 
1628   d_position := 70;
1629 
1630   IF (PO_PDOI_PARAMS.g_request.document_type IN
1631       (PO_PDOI_CONSTANTS.g_DOC_TYPE_BLANKET,
1632        PO_PDOI_CONSTANTS.g_DOC_TYPE_QUOTATION)) THEN
1633     -- derive IP category_id from IP category_name
1634     derive_ip_category_id
1635     (
1636       p_key                    => l_key,
1637       p_index_tbl              => l_index_tbl,
1638       p_file_line_language_tbl => x_lines.file_line_language_tbl,
1639       p_ip_category_tbl        => x_lines.ip_category_tbl,
1640       x_ip_category_id_tbl     => x_lines.ip_category_id_tbl
1641     );
1642   END IF;
1643 
1644   d_position := 80;
1645 
1646   -- derive unit_of_measure from uom_code
1647   derive_unit_of_measure
1648   (
1649     p_key                  => l_key,
1650     p_index_tbl            => l_index_tbl,
1651     p_uom_code_tbl         => x_lines.uom_code_tbl,
1652     x_unit_of_measure_tbl  => x_lines.unit_of_measure_tbl
1653   );
1654 
1655   d_position := 90;
1656 
1657   -- derive line_type_id from line_type
1658   derive_line_type_id
1659   (
1660     p_key                    => l_key,
1661     p_index_tbl              => l_index_tbl,
1662     p_file_line_language_tbl => x_lines.file_line_language_tbl,
1663     p_line_type_tbl          => x_lines.line_type_tbl,
1664     x_line_type_id_tbl       => x_lines.line_type_id_tbl
1665   );
1666 
1667   d_position := 100;
1668 
1669   -- derive un_number_id from un_number
1670   derive_un_number_id
1671   (
1672     p_key                  => l_key,
1673     p_index_tbl            => l_index_tbl,
1674     p_un_number_tbl        => x_lines.un_number_tbl,
1675     x_un_number_id_tbl     => x_lines.un_number_id_tbl
1676   );
1677 
1678   d_position := 110;
1679 
1680   -- derive hazard_calss_id from hazard_class
1681   derive_hazard_class_id
1682   (
1683     p_key                  => l_key,
1684     p_index_tbl            => l_index_tbl,
1685     p_hazard_class_tbl     => x_lines.hazard_class_tbl,
1686     x_hazard_class_id_tbl  => x_lines.hazard_class_id_tbl
1687   );
1688 
1689   d_position := 120;
1690 
1691   -- derive template_id from template_name
1692   derive_template_id
1693   (
1694     p_key                  => l_key,
1695     p_index_tbl            => l_index_tbl,
1696     p_template_name_tbl    => x_lines.template_name_tbl,
1697     x_template_id_tbl      => x_lines.template_id_tbl
1698   );
1699 
1700   d_position := 130;
1701 
1702   -- handle all derivation errors
1703   FOR i IN 1..x_lines.rec_count
1704   LOOP
1705     d_position := 140;
1706 
1707     IF (PO_LOG.d_stmt) THEN
1708       PO_LOG.stmt(d_module, d_position, 'index', i);
1709     END IF;
1710 
1711     -- bug5684695
1712     -- Removed validation for po_header_id at line level. Simply copy the
1713     -- po_header_id from whatever's set for the header
1714     x_lines.po_header_id_tbl(i) := x_lines.hd_po_header_id_tbl(i);
1715 
1716     -- derivation error for item_id
1717     IF (x_lines.item_tbl(i) IS NOT NULL AND
1718         x_lines.item_id_tbl(i) IS NULL AND
1719         PO_PDOI_PARAMS.g_request.create_items = 'N') THEN
1720       IF (PO_LOG.d_stmt) THEN
1721         PO_LOG.stmt(d_module, d_position, 'item id derivation failed');
1722         PO_LOG.stmt(d_module, d_position, 'item', x_lines.item_tbl(i));
1723       END IF;
1724 
1725       PO_PDOI_ERR_UTL.add_fatal_error
1726       (
1727         p_interface_header_id  => x_lines.intf_header_id_tbl(i),
1728         p_interface_line_id    => x_lines.intf_line_id_tbl(i),
1729         p_error_message_name   => 'PO_PDOI_DERV_PART_NUM_ERROR',
1730         p_table_name           => 'PO_LINES_INTERFACE',
1731         p_column_name          => NULL,
1732         p_column_value         => NULL,
1733         p_validation_id        => PO_VAL_CONSTANTS.c_part_num_derv,
1734         p_lines                => x_lines
1735       );
1736 
1737         x_lines.error_flag_tbl(i) := FND_API.g_TRUE;
1738     END IF;
1739 
1740     -- derivation error for job_business_group_id
1741     IF (x_lines.job_business_group_name_tbl(i) IS NOT NULL AND
1742         x_lines.job_business_group_id_tbl(i) IS NULL) THEN
1743       IF (PO_LOG.d_stmt) THEN
1744         PO_LOG.stmt(d_module, d_position, 'job business group id derivation failed');
1745         PO_LOG.stmt(d_module, d_position, 'job business group name',
1746                     x_lines.job_business_group_name_tbl(i));
1747       END IF;
1748 
1749       PO_PDOI_ERR_UTL.add_fatal_error
1750       (
1751         p_interface_header_id  => x_lines.intf_header_id_tbl(i),
1752         p_interface_line_id    => x_lines.intf_line_id_tbl(i),
1753         p_error_message_name   => 'PO_PDOI_DERV_ERROR',
1754         p_table_name           => 'PO_LINES_INTERFACE',
1755         p_column_name          => 'JOB_BUSINESS_GROUP_ID',
1756         p_column_value         => x_lines.job_business_group_id_tbl(i),
1757         p_token1_name          => 'COLUMN_NAME',
1758         p_token1_value         => 'JOB_BUSINESS_GROUP_NAME',
1759         p_token2_name          => 'VALUE',
1760         p_token2_value         => x_lines.job_business_group_name_tbl(i)
1761       );
1762 
1763       x_lines.error_flag_tbl(i) := FND_API.g_TRUE;
1764     ELSIF (x_lines.job_name_tbl(i) IS NOT NULL AND  -- derivation error for job_id
1765            x_lines.job_id_tbl(i) IS NULL) THEN
1766       IF (PO_LOG.d_stmt) THEN
1767         PO_LOG.stmt(d_module, d_position, 'job id derivation failed');
1768         PO_LOG.stmt(d_module, d_position, 'job name',
1769                     x_lines.job_name_tbl(i));
1770       END IF;
1771 
1772       PO_PDOI_ERR_UTL.add_fatal_error
1773       (
1774         p_interface_header_id  => x_lines.intf_header_id_tbl(i),
1775         p_interface_line_id    => x_lines.intf_line_id_tbl(i),
1776         p_error_message_name   => 'PO_PDOI_DERV_ERROR',
1777         p_table_name           => 'PO_LINES_INTERFACE',
1778         p_column_name          => 'JOB_ID',
1779         p_column_value         => x_lines.job_id_tbl(i),
1780         p_token1_name          => 'COLUMN_NAME',
1781         p_token1_value         => 'JOB_NAME',
1782         p_token2_name          => 'VALUE',
1783         p_token2_value         => x_lines.job_name_tbl(i),
1784         p_validation_id        => PO_VAL_CONSTANTS.c_job_name_derv,
1785         p_lines                => x_lines
1786       );
1787 
1788       x_lines.error_flag_tbl(i) := FND_API.g_TRUE;
1789     END IF;
1790 
1791     -- derivation error for category_id
1792     IF (x_lines.category_tbl(i) IS NOT NULL AND
1793         x_lines.category_id_tbl(i) IS NULL) THEN
1794       IF (PO_LOG.d_stmt) THEN
1795         PO_LOG.stmt(d_module, d_position, 'category id derivation failed');
1796         PO_LOG.stmt(d_module, d_position, 'category name',
1797                     x_lines.category_tbl(i));
1798       END IF;
1799 
1800       PO_PDOI_ERR_UTL.add_fatal_error
1801       (
1802         p_interface_header_id  => x_lines.intf_header_id_tbl(i),
1803         p_interface_line_id    => x_lines.intf_line_id_tbl(i),
1804         p_error_message_name   => 'PO_PDOI_DERV_ERROR',
1805         p_table_name           => 'PO_LINES_INTERFACE',
1806         p_column_name          => 'CATEGORY_ID',
1807         p_column_value         => x_lines.category_id_tbl(i),
1808         p_token1_name          => 'COLUMN_NAME',
1809         p_token1_value         => 'CATEGORY',
1810         p_token2_name          => 'VALUE',
1811         p_token2_value         => x_lines.category_tbl(i),
1812         p_validation_id        => PO_VAL_CONSTANTS.c_category_derv,
1813         p_lines                => x_lines
1814       );
1815 
1816       x_lines.error_flag_tbl(i) := FND_API.g_TRUE;
1817     END IF;
1818 
1819     -- derivation error for ip_category_id
1820     IF (PO_PDOI_PARAMS.g_request.document_type IN
1821         (PO_PDOI_CONSTANTS.g_DOC_TYPE_BLANKET,
1822          PO_PDOI_CONSTANTS.g_DOC_TYPE_QUOTATION)) THEN
1823       IF (x_lines.ip_category_tbl(i) IS NOT NULL AND
1824           x_lines.ip_category_id_tbl(i) IS NULL) THEN
1825         IF (PO_LOG.d_stmt) THEN
1826           PO_LOG.stmt(d_module, d_position, 'ip category id derivation failed');
1827           PO_LOG.stmt(d_module, d_position, 'ip category name',
1828                       x_lines.ip_category_tbl(i));
1829         END IF;
1830 
1831         PO_PDOI_ERR_UTL.add_fatal_error
1832         (
1833           p_interface_header_id  => x_lines.intf_header_id_tbl(i),
1834           p_interface_line_id    => x_lines.intf_line_id_tbl(i),
1835           p_error_message_name   => 'PO_PDOI_DERV_ERROR',
1836           p_table_name           => 'PO_LINES_INTERFACE',
1837           p_column_name          => 'IP_CATEGORY_ID',
1838           p_column_value         => x_lines.ip_category_id_tbl(i),
1839           p_token1_name          => 'COLUMN_NAME',
1840           p_token1_value         => 'IP_CATEGORY',
1841           p_token2_name          => 'VALUE',
1842           p_token2_value         => x_lines.ip_category_tbl(i),
1843           p_validation_id        => PO_VAL_CONSTANTS.c_ip_category_derv,
1844           p_lines                => x_lines
1845         );
1846 
1847         x_lines.error_flag_tbl(i) := FND_API.g_TRUE;
1848       END IF;
1849     END IF;
1850 
1851     -- derivation error for unit_of_measure
1852     IF (x_lines.uom_code_tbl(i) IS NOT NULL AND
1853         x_lines.unit_of_measure_tbl(i) IS NULL) THEN
1854       IF (PO_LOG.d_stmt) THEN
1855         PO_LOG.stmt(d_module, d_position, 'unit of measure derivation failed');
1856         PO_LOG.stmt(d_module, d_position, 'uom code',
1857                     x_lines.uom_code_tbl(i));
1858       END IF;
1859 
1860       PO_PDOI_ERR_UTL.add_fatal_error
1861       (
1862         p_interface_header_id  => x_lines.intf_header_id_tbl(i),
1863         p_interface_line_id    => x_lines.intf_line_id_tbl(i),
1864         p_error_message_name   => 'PO_PDOI_DERV_ERROR',
1865         p_table_name           => 'PO_LINES_INTERFACE',
1866         p_column_name          => 'UNIT_OF_MEASURE',
1867         p_column_value         => x_lines.unit_of_measure_tbl(i),
1868         p_token1_name          => 'COLUMN_NAME',
1869         p_token1_value         => 'UOM_CODE',
1870         p_token2_name          => 'VALUE',
1871         p_token2_value         => x_lines.uom_code_tbl(i),
1872         p_validation_id        => PO_VAL_CONSTANTS.c_uom_code_derv,
1873         p_lines                => x_lines
1874       );
1875 
1876       x_lines.error_flag_tbl(i) := FND_API.g_TRUE;
1877     END IF;
1878 
1879     -- derivation error for line_type_id
1880     IF (x_lines.line_type_tbl(i) IS NOT NULL AND
1881         x_lines.line_type_id_tbl(i) IS NULL) THEN
1882       IF (PO_LOG.d_stmt) THEN
1883         PO_LOG.stmt(d_module, d_position, 'line type id derivation failed');
1884         PO_LOG.stmt(d_module, d_position, 'line type',
1885                     x_lines.line_type_tbl(i));
1886       END IF;
1887 
1888       PO_PDOI_ERR_UTL.add_fatal_error
1889       (
1890         p_interface_header_id  => x_lines.intf_header_id_tbl(i),
1891         p_interface_line_id    => x_lines.intf_line_id_tbl(i),
1892         p_error_message_name   => 'PO_PDOI_DERV_ERROR',
1893         p_table_name           => 'PO_LINES_INTERFACE',
1894         p_column_name          => 'LINE_TYPE_ID',
1895         p_column_value         => x_lines.line_type_id_tbl(i),
1896         p_token1_name          => 'COLUMN_NAME',
1897         p_token1_value         => 'LINE_TYPE',
1898         p_token2_name          => 'VALUE',
1899         p_token2_value         => x_lines.line_type_tbl(i),
1900         p_validation_id        => PO_VAL_CONSTANTS.c_line_type_derv,
1901         p_lines                => x_lines
1902       );
1903 
1904       x_lines.error_flag_tbl(i) := FND_API.g_TRUE;
1905     END IF;
1906 
1907     -- derivation error for un_number_id
1908     IF (x_lines.un_number_tbl(i) IS NOT NULL AND
1909         x_lines.un_number_id_tbl(i) IS NULL) THEN
1910       IF (PO_LOG.d_stmt) THEN
1911         PO_LOG.stmt(d_module, d_position, 'un number id derivation failed');
1912         PO_LOG.stmt(d_module, d_position, 'un number',
1913                     x_lines.un_number_tbl(i));
1914       END IF;
1915 
1916       PO_PDOI_ERR_UTL.add_fatal_error
1917       (
1918         p_interface_header_id  => x_lines.intf_header_id_tbl(i),
1919         p_interface_line_id    => x_lines.intf_line_id_tbl(i),
1920         p_error_message_name   => 'PO_PDOI_DERV_ERROR',
1921         p_table_name           => 'PO_LINES_INTERFACE',
1922         p_column_name          => 'UN_NUMBER_ID',
1923         p_column_value         => x_lines.un_number_id_tbl(i),
1924         p_token1_name          => 'COLUMN_NAME',
1925         p_token1_value         => 'UN_NUMBER',
1926         p_token2_name          => 'VALUE',
1927         p_token2_value         => x_lines.un_number_tbl(i)
1928       );
1929 
1930       x_lines.error_flag_tbl(i) := FND_API.g_TRUE;
1931     END IF;
1932 
1933     -- derivation error for hazard_class_id
1934     IF (x_lines.hazard_class_tbl(i) IS NOT NULL AND
1935         x_lines.hazard_class_id_tbl(i) IS NULL) THEN
1936       IF (PO_LOG.d_stmt) THEN
1937         PO_LOG.stmt(d_module, d_position, 'hazard class id derivation failed');
1938         PO_LOG.stmt(d_module, d_position, 'hazard class',
1939                     x_lines.hazard_class_tbl(i));
1940       END IF;
1941 
1942       PO_PDOI_ERR_UTL.add_fatal_error
1943       (
1944         p_interface_header_id  => x_lines.intf_header_id_tbl(i),
1945         p_interface_line_id    => x_lines.intf_line_id_tbl(i),
1946         p_error_message_name   => 'PO_PDOI_DERV_ERROR',
1947         p_table_name           => 'PO_LINES_INTERFACE',
1948         p_column_name          => 'HAZARD_CLASS_ID',
1949         p_column_value         => x_lines.hazard_class_id_tbl(i),
1950         p_token1_name          => 'COLUMN_NAME',
1951         p_token1_value         => 'HAZARD_CLASS',
1952         p_token2_name          => 'VALUE',
1953         p_token2_value         => x_lines.hazard_class_tbl(i)
1954       );
1955 
1956       x_lines.error_flag_tbl(i) := FND_API.g_TRUE;
1957     END IF;
1958 
1959     -- derivation error for template_id
1960     IF (x_lines.template_name_tbl(i) IS NOT NULL AND
1961         x_lines.template_id_tbl(i) IS NULL) THEN
1962       IF (PO_LOG.d_stmt) THEN
1963         PO_LOG.stmt(d_module, d_position, 'template id derivation failed');
1964         PO_LOG.stmt(d_module, d_position, 'template name',
1965                     x_lines.template_name_tbl(i));
1966       END IF;
1967 
1968       PO_PDOI_ERR_UTL.add_fatal_error
1969       (
1970         p_interface_header_id  => x_lines.intf_header_id_tbl(i),
1971         p_interface_line_id    => x_lines.intf_line_id_tbl(i),
1972         p_error_message_name   => 'PO_PDOI_DERV_ERROR',
1973         p_table_name           => 'PO_LINES_INTERFACE',
1974         p_column_name          => 'TEMPLATE_ID',
1975         p_column_value         => x_lines.template_id_tbl(i),
1976         p_token1_name          => 'COLUMN_NAME',
1977         p_token1_value         => 'TEMPLATE_NAME',
1978         p_token2_name          => 'VALUE',
1979         p_token2_value         => x_lines.template_name_tbl(i)
1980       );
1981 
1982       x_lines.error_flag_tbl(i) := FND_API.g_TRUE;
1983     END IF;
1984   END LOOP;
1985 
1986   PO_TIMING_UTL.stop_time(PO_PDOI_CONSTANTS.g_T_LINE_DERIVE);
1987 
1988   IF (PO_LOG.d_proc) THEN
1989     PO_LOG.proc_end (d_module);
1990   END IF;
1991 
1992 EXCEPTION
1993   WHEN OTHERS THEN
1994     PO_MESSAGE_S.add_exc_msg
1995     (
1996       p_pkg_name => d_pkg_name,
1997       p_procedure_name => d_api_name || '.' || d_position
1998     );
1999     RAISE;
2000 END derive_lines;
2001 
2002 -----------------------------------------------------------------------
2003 --Start of Comments
2004 --Name: derive_lines_for_update
2005 --Function: peform derivation logic on line attributes when the
2006 --          line level action is 'UPDATE'. The attributes include
2007 --          unit_of_measure, po_category_id and ip_category_id
2008 --Parameters:
2009 --IN:
2010 --IN OUT:
2011 --  x_lines
2012 --    record to store all the line rows within the batch;
2013 --    Derivation are performed for certain attributes only
2014 --    if their name value is populated but id value is not.
2015 --OUT:
2016 --End of Comments
2017 ------------------------------------------------------------------------
2018 PROCEDURE derive_lines_for_update
2019 (
2020   x_lines       IN OUT NOCOPY PO_PDOI_TYPES.lines_rec_type
2021 ) IS
2022 
2023   d_api_name CONSTANT VARCHAR2(30) := 'derive_lines_for_update';
2024   d_module   CONSTANT VARCHAR2(255) := d_pkg_name || d_api_name || '.';
2025   d_position NUMBER;
2026 
2027   -- key of temp table used to identify the derived result
2028   l_key po_session_gt.key%TYPE;
2029 
2030   -- table used to save the index of the each row
2031   l_index_tbl DBMS_SQL.NUMBER_TABLE;
2032 BEGIN
2033   d_position := 0;
2034 
2035   IF (PO_LOG.d_proc) THEN
2036     PO_LOG.proc_begin(d_module, 'line counts', x_lines.rec_count);
2037   END IF;
2038 
2039   PO_TIMING_UTL.start_time(PO_PDOI_CONSTANTS.g_T_LINE_DERIVE);
2040 
2041   -- assign a new key used in temporary table
2042   l_key := PO_CORE_S.get_session_gt_nextval;
2043 
2044   -- initialize table containing the row number(index)
2045   PO_PDOI_UTL.generate_ordered_num_list
2046   (
2047     p_size     => x_lines.rec_count,
2048     x_num_list => l_index_tbl
2049   );
2050 
2051   d_position := 10;
2052 
2053   -- derive PO category_id from PO category_name
2054   derive_category_id
2055   (
2056     p_key                  => l_key,
2057     p_category_tbl         => x_lines.category_tbl,
2058     x_category_id_tbl      => x_lines.category_id_tbl
2059   );
2060 
2061   d_position := 20;
2062 
2063   IF (PO_PDOI_PARAMS.g_request.document_type IN
2064       (PO_PDOI_CONSTANTS.g_DOC_TYPE_BLANKET,
2065        PO_PDOI_CONSTANTS.g_DOC_TYPE_QUOTATION)) THEN
2066     -- derive IP category_id from IP category_name
2067     derive_ip_category_id
2068     (
2069       p_key                    => l_key,
2070       p_index_tbl              => l_index_tbl,
2071       p_file_line_language_tbl => x_lines.file_line_language_tbl,
2072       p_ip_category_tbl        => x_lines.ip_category_tbl,
2073       x_ip_category_id_tbl     => x_lines.ip_category_id_tbl
2074     );
2075 
2076     d_position := 22;
2077 
2078     -- Bug 7577670: Derive ip_category_id from po_category_id
2079     -- if ip_category_id is null and po_category_id is not null
2080     default_ip_cat_id_from_po(p_key                 => l_key,
2081                               p_index_tbl           => l_index_tbl,
2082                               p_po_category_id_tbl  => x_lines.category_id_tbl,
2083                               x_ip_category_id_tbl  => x_lines.ip_category_id_tbl);
2084 
2085     d_position := 25;
2086 
2087     -- Bug 7577670: Derive po_category_id from ip_category_id
2088     -- if po_category_id is null and ip_category_id is not null
2089     default_po_cat_id_from_ip(p_key                 => l_key,
2090                               p_index_tbl           => l_index_tbl,
2091                               p_ip_category_id_tbl  => x_lines.ip_category_id_tbl,
2092                               x_po_category_id_tbl  => x_lines.category_id_tbl);
2093   END IF;
2094 
2095   d_position := 30;
2096 
2097   -- derive unit_of_measure from uom_code
2098   derive_unit_of_measure
2099   (
2100     p_key                  => l_key,
2101     p_index_tbl            => l_index_tbl,
2102     p_uom_code_tbl         => x_lines.uom_code_tbl,
2103     x_unit_of_measure_tbl  => x_lines.unit_of_measure_tbl
2104   );
2105 
2106   d_position := 40;
2107 
2108   -- handle all derivation errors
2109   FOR i IN 1..x_lines.rec_count
2110   LOOP
2111     d_position := 50;
2112 
2113     IF (PO_LOG.d_stmt) THEN
2114       PO_LOG.stmt(d_module, d_position, 'index', i);
2115     END IF;
2116 
2117     -- derivation error for category_id
2118     IF (x_lines.category_tbl(i) IS NOT NULL AND
2119         x_lines.category_id_tbl(i) IS NULL) THEN
2120       IF (PO_LOG.d_stmt) THEN
2121         PO_LOG.stmt(d_module, d_position, 'category id derivation failed');
2122         PO_LOG.stmt(d_module, d_position, 'category name',
2123                     x_lines.category_tbl(i));
2124       END IF;
2125 
2126       PO_PDOI_ERR_UTL.add_fatal_error
2127       (
2128         p_interface_header_id  => x_lines.intf_header_id_tbl(i),
2129         p_interface_line_id    => x_lines.intf_line_id_tbl(i),
2130         p_error_message_name   => 'PO_PDOI_DERV_ERROR',
2131         p_table_name           => 'PO_LINES_INTERFACE',
2132         p_column_name          => 'CATEGORY_ID',
2133         p_column_value         => x_lines.category_id_tbl(i),
2134         p_token1_name          => 'COLUMN_NAME',
2135         p_token1_value         => 'CATEGORY',
2136         p_token2_name          => 'VALUE',
2137         p_token2_value         => x_lines.category_tbl(i)
2138       );
2139 
2140       x_lines.error_flag_tbl(i) := FND_API.g_TRUE;
2141     END IF;
2142 
2143     -- derivation error for ip_category_id
2144     IF (PO_PDOI_PARAMS.g_request.document_type IN
2145         (PO_PDOI_CONSTANTS.g_DOC_TYPE_BLANKET,
2146          PO_PDOI_CONSTANTS.g_DOC_TYPE_QUOTATION)) THEN
2147       IF (x_lines.ip_category_tbl(i) IS NOT NULL AND
2148           x_lines.ip_category_id_tbl(i) IS NULL) THEN
2149         IF (PO_LOG.d_stmt) THEN
2150           PO_LOG.stmt(d_module, d_position, 'ip category id derivation failed');
2151           PO_LOG.stmt(d_module, d_position, 'ip category name',
2152                       x_lines.ip_category_tbl(i));
2153         END IF;
2154 
2155         PO_PDOI_ERR_UTL.add_fatal_error
2156         (
2157           p_interface_header_id  => x_lines.intf_header_id_tbl(i),
2158           p_interface_line_id    => x_lines.intf_line_id_tbl(i),
2159           p_error_message_name   => 'PO_PDOI_DERV_ERROR',
2160           p_table_name           => 'PO_LINES_INTERFACE',
2161           p_column_name          => 'IP_CATEGORY_ID',
2162           p_column_value         => x_lines.ip_category_id_tbl(i),
2163           p_token1_name          => 'COLUMN_NAME',
2164           p_token1_value         => 'IP_CATEGORY',
2165           p_token2_name          => 'VALUE',
2166           p_token2_value         => x_lines.ip_category_tbl(i)
2167         );
2168 
2169         x_lines.error_flag_tbl(i) := FND_API.g_TRUE;
2170       END IF;
2171     END IF;
2172 
2173     -- derivation error for unit_of_measure
2174     IF (x_lines.uom_code_tbl(i) IS NOT NULL AND
2175         x_lines.unit_of_measure_tbl(i) IS NULL) THEN
2176       IF (PO_LOG.d_stmt) THEN
2177         PO_LOG.stmt(d_module, d_position, 'unit of measure derivation failed');
2178         PO_LOG.stmt(d_module, d_position, 'uom code',
2179                     x_lines.uom_code_tbl(i));
2180       END IF;
2181 
2182       PO_PDOI_ERR_UTL.add_fatal_error
2183       (
2184         p_interface_header_id  => x_lines.intf_header_id_tbl(i),
2185         p_interface_line_id    => x_lines.intf_line_id_tbl(i),
2186         p_error_message_name   => 'PO_PDOI_DERV_ERROR',
2187         p_table_name           => 'PO_LINES_INTERFACE',
2188         p_column_name          => 'UNIT_OF_MEASURE',
2189         p_column_value         => x_lines.unit_of_measure_tbl(i),
2190         p_token1_name          => 'COLUMN_NAME',
2191         p_token1_value         => 'UOM_CODE',
2192         p_token2_name          => 'VALUE',
2193         p_token2_value         => x_lines.uom_code_tbl(i)
2194       );
2195 
2196       x_lines.error_flag_tbl(i) := FND_API.g_TRUE;
2197     END IF;
2198   END LOOP;
2199 
2200   PO_TIMING_UTL.stop_time(PO_PDOI_CONSTANTS.g_T_LINE_DERIVE);
2201 
2202   IF (PO_LOG.d_proc) THEN
2203     PO_LOG.proc_end (d_module);
2204   END IF;
2205 
2206 EXCEPTION
2207   WHEN OTHERS THEN
2208     PO_MESSAGE_S.add_exc_msg
2209     (
2210       p_pkg_name => d_pkg_name,
2211       p_procedure_name => d_api_name || '.' || d_position
2212     );
2213     RAISE;
2214 END derive_lines_for_update;
2215 -----------------------------------------------------------------------
2216 --Start of Comments
2217 --Name: default_lines
2218 --Function: perform defaulting logic on line attributes
2219 --Parameters:
2220 --IN:
2221 --IN OUT:
2222 --  x_lines
2223 --    record to store all the line rows within the batch;
2224 --    defaulting are performed for certain attributes only
2225 --    if their value is empty.
2226 --OUT:
2227 --End of Comments
2228 ------------------------------------------------------------------------
2229 PROCEDURE default_lines
2230 (
2231   x_lines IN OUT NOCOPY PO_PDOI_TYPES.lines_rec_type
2232 ) IS
2233 
2234   d_api_name CONSTANT VARCHAR2(30) := 'default_lines';
2235   d_module   CONSTANT VARCHAR2(255) := d_pkg_name || d_api_name || '.';
2236   d_position NUMBER;
2237 
2238   -- key of temp table used to identify the derived result
2239   l_key po_session_gt.key%TYPE;
2240 
2241   -- table used to save the index of the each row
2242   l_index_tbl DBMS_SQL.NUMBER_TABLE;
2243 
2244   -- information defaulted from line type
2245   l_li_category_id_tbl     PO_TBL_NUMBER;
2246   l_li_unit_of_measure_tbl PO_TBL_VARCHAR30;
2247   l_li_unit_price_tbl      PO_TBL_NUMBER;
2248 
2249   -- information defaulted from item
2250   l_it_item_desc_tbl       PO_TBL_VARCHAR2000;
2251   l_it_unit_of_measure_tbl PO_TBL_VARCHAR30;
2252   l_it_unit_price_tbl      PO_TBL_NUMBER;
2253   l_it_category_id_tbl     PO_TBL_NUMBER;
2254   l_it_un_number_id_tbl    PO_TBL_NUMBER;
2255   l_it_hazard_class_id_tbl PO_TBL_NUMBER;
2256   l_it_market_price_tbl    PO_TBL_NUMBER;
2257   l_it_secondary_uom_tbl   PO_TBL_VARCHAR30;
2258 
2259   -- information defaulted from job
2260   l_job_item_desc_tbl      PO_TBL_VARCHAR2000;
2261   l_job_category_id_tbl    PO_TBL_NUMBER;
2262 
2263   -- information defaulted from ip category
2264   l_ic_category_id_tbl     PO_TBL_NUMBER; -- bug5130037
2265 
2266 
2267 BEGIN
2268   d_position := 0;
2269 
2270   IF (PO_LOG.d_proc) THEN
2271     PO_LOG.proc_begin(d_module);
2272   END IF;
2273 
2274   PO_TIMING_UTL.start_time(PO_PDOI_CONSTANTS.g_T_LINE_DEFAULT);
2275 
2276   -- get key value to identify rows in po_session_gt table
2277   l_key := PO_CORE_S.get_session_gt_nextval;
2278 
2279   -- default line_type_id that will be used in other defaulting logic;
2280   -- l_index_tbl table is initialized as well
2281   FOR i IN 1..x_lines.rec_count
2282   LOOP
2283     d_position := 10;
2284 
2285     -- set default value for line_type_id
2286     IF (x_lines.line_type_id_tbl(i) IS NULL) THEN
2287       IF (PO_LOG.d_stmt) THEN
2288         PO_LOG.stmt(d_module, d_position, 'set default line type id on line index', i);
2289       END IF;
2290 
2291       x_lines.line_type_id_tbl(i) := PO_PDOI_PARAMS.g_sys.line_type_id;
2292     END IF;
2293 
2294     -- initialize l_index_tbl
2295     l_index_tbl(i) := i;
2296   END LOOP;
2297 
2298   -- get default info from line type definition,
2299   -- the attributes we can default from line type include:
2300   -- order_type_lookup_code, purchasing_basis, matching_basis, category_id,
2301   -- unit_of_measure, unit_price
2302   default_info_from_line_type
2303   (
2304     p_key                        => l_key,
2305     p_index_tbl                  => l_index_tbl,
2306     p_line_type_id_tbl           => x_lines.line_type_id_tbl,
2307     x_order_type_lookup_code_tbl => x_lines.order_type_lookup_code_tbl,
2308     x_purchase_basis_tbl         => x_lines.purchase_basis_tbl,
2309     x_matching_basis_tbl         => x_lines.matching_basis_tbl,
2310     x_category_id_tbl            => l_li_category_id_tbl,
2311     x_unit_of_measure_tbl        => l_li_unit_of_measure_tbl,
2312     x_unit_price_tbl             => l_li_unit_price_tbl
2313   );
2314 
2315   d_position := 20;
2316 
2317   -- get default info from item definition
2318   -- the attributes we can default from item include:
2319   -- item_description, unit_of_measure, unit_price, category_id,
2320   -- un_number_id, hazard_class_id, market_price, secondary_unit_of_measure
2321   default_info_from_item
2322   (
2323     p_key                        => l_key,
2324     p_index_tbl                  => l_index_tbl,
2325     p_item_id_tbl                => x_lines.item_id_tbl,
2326     x_item_desc_tbl              => l_it_item_desc_tbl,
2327     x_unit_of_measure_tbl        => l_it_unit_of_measure_tbl,
2328     x_unit_price_tbl             => l_it_unit_price_tbl,
2329     x_category_id_tbl            => l_it_category_id_tbl,
2330     x_un_number_id_tbl           => l_it_un_number_id_tbl,
2331     x_hazard_class_id_tbl        => l_it_hazard_class_id_tbl,
2332     x_market_price_tbl           => l_it_market_price_tbl,
2333     x_secondary_unit_of_meas_tbl => l_it_secondary_uom_tbl
2334   );
2335 
2336   d_position := 30;
2337 
2338   -- get default info from job
2339   -- the attributes we can default from job include:
2340   -- item_description, and category_id
2341   default_info_from_job
2342   (
2343     p_key                        => l_key,
2344     p_index_tbl                  => l_index_tbl,
2345     p_job_id_tbl                 => x_lines.job_id_tbl,
2346     x_item_desc_tbl              => l_job_item_desc_tbl,
2347     x_category_id_tbl            => l_job_category_id_tbl
2348   );
2349 
2350   d_position := 40;
2351 
2352   l_ic_category_id_tbl := PO_TBL_NUMBER();
2353   l_ic_category_id_tbl.EXTEND(x_lines.rec_count);
2354 
2355   IF (PO_PDOI_PARAMS.g_request.document_type IN
2356       (PO_PDOI_CONSTANTS.g_DOC_TYPE_BLANKET,
2357        PO_PDOI_CONSTANTS.g_DOC_TYPE_QUOTATION)) THEN
2358 
2359     d_position := 50;
2360 
2361     -- get default po category ids from ip category ids
2362     default_po_cat_id_from_ip
2363     (
2364       p_key                        => l_key,
2365       p_index_tbl                  => l_index_tbl,
2366       p_ip_category_id_tbl         => x_lines.ip_category_id_tbl,
2367       x_po_category_id_tbl         => l_ic_category_id_tbl -- bug5130037
2368     );
2369   END IF;
2370 
2371 
2372   -- default attributes for each line
2373   FOR i IN 1..x_lines.rec_count
2374   LOOP
2375     d_position := 60;
2376 
2377     IF (PO_LOG.d_stmt) THEN
2378       PO_LOG.stmt(d_module, d_position, 'index', i);
2379     END IF;
2380 
2381     -- bug5307208
2382     -- Effective and Expiration date should get truncated.
2383     x_lines.effective_date_tbl(i) := TRUNC(x_lines.effective_date_tbl(i));
2384     x_lines.expiration_date_tbl(i) := TRUNC(x_lines.expiration_date_tbl(i));
2385 
2386 
2387     -- default item_description
2388     x_lines.item_desc_tbl(i) :=
2389       COALESCE(x_lines.item_desc_tbl(i), l_it_item_desc_tbl(i),
2390                l_job_item_desc_tbl(i));
2391 
2392     -- default unit_of_measure
2393     x_lines.unit_of_measure_tbl(i) :=
2394       COALESCE(x_lines.unit_of_measure_tbl(i), l_it_unit_of_measure_tbl(i),
2395                l_li_unit_of_measure_tbl(i));
2396 
2397     -- default unit_price when:
2398     -- 1. unit_price value is null and
2399     -- 2. order_type_lookup_code is not 'FIXED PRICE' and
2400     IF (x_lines.unit_price_tbl(i) IS NULL AND
2401         x_lines.order_type_lookup_code_tbl(i) <> 'FIXED PRICE') THEN
2402       IF (x_lines.order_type_lookup_code_tbl(i) = 'AMOUNT') THEN
2403         IF (PO_LOG.d_stmt) THEN
2404           PO_LOG.stmt(d_module, d_position, 'set price when order type is AMOUNT',
2405                       l_li_unit_price_tbl(i));
2406         END IF;
2407 
2408         x_lines.unit_price_tbl(i) := l_li_unit_price_tbl(i);
2409       ELSE
2410         IF (x_lines.item_id_tbl(i) IS NOT NULL) THEN
2411           IF (PO_LOG.d_stmt) THEN
2412             PO_LOG.stmt(d_module, d_position, 'set price when item id is not empty',
2413                         l_it_unit_price_tbl(i));
2414           END IF;
2415 
2416           x_lines.unit_price_tbl(i) := l_it_unit_price_tbl(i);
2417         ELSE
2418           IF (PO_LOG.d_stmt) THEN
2419             PO_LOG.stmt(d_module, d_position, 'set price when item id is empty',
2420                         NVL(l_li_unit_price_tbl(i), 0));
2421           END IF;
2422 
2423           x_lines.unit_price_tbl(i) := NVL(l_li_unit_price_tbl(i), 0);
2424         END IF;
2425       END IF;
2426     END IF;
2427 
2428     -- default base_unit_price
2429     IF (x_lines.base_unit_price_tbl(i) IS NULL AND
2430         x_lines.order_type_lookup_code_tbl(i) <> 'FIXED PRICE') THEN
2431       x_lines.base_unit_price_tbl(i) := x_lines.unit_price_tbl(i);
2432     END IF;
2433 
2434     -- default po category_id
2435     x_lines.category_id_tbl(i) :=
2436         COALESCE(x_lines.category_id_tbl(i), l_it_category_id_tbl(i),
2437                  l_job_category_id_tbl(i), l_ic_category_id_tbl(i),
2438                  l_li_category_id_tbl(i),
2439                  PO_PDOI_PARAMS.g_sys.def_category_id);
2440 
2441     IF (PO_LOG.d_stmt) THEN
2442       PO_LOG.stmt(d_module, d_position, 'default category id',
2443                   x_lines.category_id_tbl(i));
2444     END IF;
2445 
2446     -- default un_number_id and hazard_class_id from item
2447     x_lines.un_number_id_tbl(i) :=
2448         NVL(x_lines.un_number_id_tbl(i), l_it_un_number_id_tbl(i));
2449     x_lines.hazard_class_id_tbl(i) :=
2450         NVL(x_lines.hazard_class_id_tbl(i), l_it_hazard_class_id_tbl(i));
2451 
2452     -- set from_header_id and from_line_id to NULL
2453     x_lines.from_header_id_tbl(i) := NULL;
2454     x_lines.from_line_id_tbl(i) := NULL;
2455 
2456     d_position := 70;
2457 
2458     -- the following default logic is for BLANKET/STANDARD only
2459     IF (PO_PDOI_PARAMS.g_request.document_type IN
2460         (PO_PDOI_CONSTANTS.g_DOC_TYPE_BLANKET,
2461          PO_PDOI_CONSTANTS.g_DOC_TYPE_STANDARD)) THEN
2462       d_position := 80;
2463 
2464       IF (PO_LOG.d_stmt) THEN
2465         PO_LOG.stmt(d_module, d_position, 'set default value for blanket/spo');
2466       END IF;
2467 
2468       -- default list_price_per_unit
2469       IF (x_lines.list_price_per_unit_tbl(i) IS NULL) THEN
2470         IF (x_lines.item_id_tbl(i) IS NULL) THEN
2471           x_lines.list_price_per_unit_tbl(i) := x_lines.unit_price_tbl(i);
2472         ELSE
2473           x_lines.list_price_per_unit_tbl(i) := l_it_unit_price_tbl(i);
2474         END IF;
2475       END IF;
2476 
2477       -- default market_price
2478       IF (x_lines.market_price_tbl(i) IS NULL AND
2479           x_lines.item_id_tbl(i) IS NOT NULL) THEN
2480         x_lines.market_price_tbl(i) := l_it_unit_price_tbl(i);
2481       END IF;
2482 
2483       -- default capital_expense_flag,
2484       x_lines.capital_expense_flag_tbl(i) :=
2485           NVL(x_lines.capital_expense_flag_tbl(i), 'N');
2486 
2487       -- default min_release_amount, negotiated_flag and
2488       -- price_break_lookup_code for blanket
2489       IF (PO_PDOI_PARAMS.g_request.document_type =
2490           PO_PDOI_CONSTANTS.g_DOC_TYPE_BLANKET) THEN
2491         d_position := 90;
2492 
2493         IF (PO_LOG.d_stmt) THEN
2494           PO_LOG.stmt(d_module, d_position, 'set default value for blanket');
2495         END IF;
2496 
2497         -- min_release_amount
2498         x_lines.min_release_amount_tbl(i) :=
2499             NVL(x_lines.min_release_amount_tbl(i),
2500             x_lines.hd_min_release_amount_tbl(i));
2501 
2502         -- negotiated_by_preparer_flag
2503         x_lines.negotiated_flag_tbl(i) :=
2504           NVL(x_lines.negotiated_flag_tbl(i), 'Y');
2505 
2506         -- price_break_lookup_code
2507 
2508         -- bug5129112
2509         -- Do not default price break lookup code for global agreements
2510         IF (x_lines.price_break_lookup_code_tbl(i) IS NULL) THEN
2511           IF (x_lines.hd_global_agreement_flag_tbl(i) = 'Y'
2512               OR
2513               ( x_lines.order_type_lookup_code_tbl(i) = 'FIXED PRICE' AND
2514                 x_lines.purchase_basis_tbl(i) = 'SERVICES')) THEN
2515             x_lines.price_break_lookup_code_tbl(i) := NULL;
2516           ELSE
2517             x_lines.price_break_lookup_code_tbl(i) :=
2518               PO_PDOI_PARAMS.g_sys.price_break_lookup_code;
2519           END IF;
2520         END IF;
2521       ELSE
2522         -- default tax_attribute_update_code for SPO
2523         x_lines.tax_attribute_update_code_tbl(i) := 'CREATE';
2524 
2525         -- negotiated_by_preparer_flag
2526         x_lines.negotiated_flag_tbl(i) :=
2527           NVL(x_lines.negotiated_flag_tbl(i), 'N');
2528       END IF;
2529 
2530       d_position := 100;
2531 
2532       -- default allow_price_override_flag
2533       x_lines.allow_price_override_flag_tbl(i) :=
2534           NVL(x_lines.allow_price_override_flag_tbl(i), 'N');
2535 
2536       -- default price_type
2537       x_lines.price_type_tbl(i) :=
2538           NVL(x_lines.price_type_tbl(i), PO_PDOI_PARAMS.g_sys.price_type_lookup_code);
2539 
2540       -- default closed_code
2541       x_lines.closed_code_tbl(i) :=
2542           NVL(x_lines.closed_code_tbl(i), 'OPEN');
2543 
2544       -- set unordered_flag, cancel_flag
2545       x_lines.unordered_flag_tbl(i) := 'N';
2546       x_lines.cancel_flag_tbl(i) := 'N';
2547 
2548       -- set quantity_committed from quantity
2549       x_lines.quantity_committed_tbl(i) := x_lines.quantity_tbl(i);
2550 
2551       -- default secondary_unit_of_measure from item definition
2552       x_lines.secondary_unit_of_meas_tbl(i) :=
2553         NVL(x_lines.secondary_unit_of_meas_tbl(i), l_it_secondary_uom_tbl(i));
2554     END IF;
2555   END LOOP;
2556 
2557 
2558   IF (PO_PDOI_PARAMS.g_request.document_type IN
2559       (PO_PDOI_CONSTANTS.g_DOC_TYPE_BLANKET,
2560        PO_PDOI_CONSTANTS.g_DOC_TYPE_QUOTATION)) THEN
2561 
2562     -- default ip category id from po category ids after all other defaulting
2563     -- for po category ids have happened
2564 
2565     d_position := 105;
2566 
2567     -- get default ip category ids from po category ids
2568     default_ip_cat_id_from_po
2569     (
2570       p_key                        => l_key,
2571       p_index_tbl                  => l_index_tbl,
2572       p_po_category_id_tbl         => x_lines.category_id_tbl,
2573       x_ip_category_id_tbl         => x_lines.ip_category_id_tbl
2574     );
2575 
2576 
2577     -- If ip category id cannot be defaulted, set the value to -2.
2578     FOR i IN 1..x_lines.rec_count LOOP
2579 
2580       x_lines.ip_category_id_tbl(i) := NVL(x_lines.ip_category_id_tbl(i), -2);
2581 
2582     END LOOP;
2583 
2584   END IF;
2585 
2586   -- default hazard_class_id from un_number
2587   default_hc_id_from_un_number
2588   (
2589     p_key                      => l_key,
2590     p_index_tbl                => l_index_tbl,
2591     p_un_number_tbl            => x_lines.un_number_tbl,
2592     x_hazard_class_id_tbl      => x_lines.hazard_class_id_tbl
2593   );
2594 
2595   d_position := 110;
2596 
2597   -- call utility method to default standard who columns
2598   PO_PDOI_MAINPROC_UTL_PVT.default_who_columns
2599   (
2600     x_last_update_date_tbl       => x_lines.last_update_date_tbl,
2601     x_last_updated_by_tbl        => x_lines.last_updated_by_tbl,
2602     x_last_update_login_tbl      => x_lines.last_update_login_tbl,
2603     x_creation_date_tbl          => x_lines.creation_date_tbl,
2604     x_created_by_tbl             => x_lines.created_by_tbl,
2605     x_request_id_tbl             => x_lines.request_id_tbl,
2606     x_program_application_id_tbl => x_lines.program_application_id_tbl,
2607     x_program_id_tbl             => x_lines.program_id_tbl,
2608     x_program_update_date_tbl    => x_lines.program_update_date_tbl
2609   );
2610 
2611   PO_TIMING_UTL.stop_time(PO_PDOI_CONSTANTS.g_T_LINE_DEFAULT);
2612 
2613   IF (PO_LOG.d_proc) THEN
2614     PO_LOG.proc_end (d_module);
2615   END IF;
2616 
2617 EXCEPTION
2618   WHEN OTHERS THEN
2619     PO_MESSAGE_S.add_exc_msg
2620     (
2621       p_pkg_name => d_pkg_name,
2622       p_procedure_name => d_api_name || '.' || d_position
2623     );
2624     RAISE;
2625 END default_lines;
2626 
2627 -----------------------------------------------------------------------
2628 --Start of Comments
2629 --Name: default_lines_for_update
2630 --Function: default certain attribute values from draft or txn tables;
2631 --          These attributes are used in internal processing;
2632 --          The attributes include:
2633 --          order_type_lookup_code, item_id, job_id
2634 --Parameters:
2635 --IN:
2636 --IN OUT:
2637 --  x_lines
2638 --    record to store all the line rows within the batch;
2639 --    Defaulting is performed for certain attributes only.
2640 --OUT:
2641 --End of Comments
2642 ------------------------------------------------------------------------
2643 PROCEDURE default_lines_for_update
2644 (
2645   x_lines       IN OUT NOCOPY PO_PDOI_TYPES.lines_rec_type
2646 ) IS
2647 
2648   d_api_name CONSTANT VARCHAR2(30) := 'default_lines_for_update';
2649   d_module   CONSTANT VARCHAR2(255) := d_pkg_name || d_api_name || '.';
2650   d_position NUMBER;
2651 
2652   -- key of temp table used to identify the derived result
2653   l_key                    po_session_gt.key%TYPE;
2654 
2655   -- table used to save the index of the each row
2656   l_num_list               DBMS_SQL.NUMBER_TABLE;
2657 
2658   -- information defaulted from existing po line
2659   l_index_tbl              PO_TBL_NUMBER;
2660   l_order_type_tbl         PO_TBL_VARCHAR30;
2661   l_item_id_tbl            PO_TBL_NUMBER;
2662   l_job_id_tbl             PO_TBL_NUMBER;
2663 
2664   l_index                  NUMBER;
2665 BEGIN
2666   d_position := 0;
2667 
2668   IF (PO_LOG.d_proc) THEN
2669     PO_LOG.proc_begin(d_module, 'po_line_id', x_lines.po_line_id_tbl);
2670     PO_LOG.proc_begin(d_module, 'draft_id', x_lines.draft_id_tbl);
2671   END IF;
2672 
2673   PO_TIMING_UTL.start_time(PO_PDOI_CONSTANTS.g_T_LINE_DERIVE);
2674 
2675   -- assign a new key used in temporary table
2676   l_key := PO_CORE_S.get_session_gt_nextval;
2677 
2678   -- initialize table containing the row number(index)
2679   PO_PDOI_UTL.generate_ordered_num_list
2680   (
2681     p_size     => x_lines.rec_count,
2682     x_num_list => l_num_list
2683   );
2684 
2685   d_position := 10;
2686 
2687   -- get values from draft tables
2688   FORALL i IN 1..l_num_list.COUNT
2689     INSERT INTO po_session_gt(key, num1, char1, num2, num3)
2690     SELECT l_key,
2691            l_num_list(i),
2692            order_type_lookup_code,
2693            item_id,
2694            job_id
2695     FROM   po_lines_draft_all
2696     WHERE  po_line_id = x_lines.po_line_id_tbl(i)
2697     AND    draft_id = x_lines.draft_id_tbl(i);
2698 
2699   d_position := 20;
2700 
2701   -- get values from txn table if no draft line exist
2702   FORALL i IN 1..l_num_list.COUNT
2703     INSERT INTO po_session_gt(key, num1, char1, num2, num3)
2704     SELECT l_key,
2705            l_num_list(i),
2706            order_type_lookup_code,
2707            item_id,
2708            job_id
2709     FROM   po_lines_all
2710     WHERE  po_line_id = x_lines.po_line_id_tbl(i)
2711     AND    NOT EXISTS (SELECT 1
2712                        FROM   po_lines_draft_all
2713                        WHERE  po_line_id = x_lines.po_line_id_tbl(i)
2714                        AND    draft_id = x_lines.draft_id_tbl(i));
2715 
2716   d_position := 30;
2717 
2718   DELETE FROM po_session_gt
2719   WHERE key = l_key
2720   RETURNING num1, char1, num2, num3 BULK COLLECT INTO
2721     l_index_tbl, l_order_type_tbl, l_item_id_tbl, l_job_id_tbl;
2722 
2723   d_position := 40;
2724 
2725   IF (PO_LOG.d_stmt) THEN
2726     PO_LOG.stmt(d_module, d_position, 'l_index_tbl', l_index_tbl);
2727     PO_LOG.stmt(d_module, d_position, 'l_order_type_tbl', l_order_type_tbl);
2728     PO_LOG.stmt(d_module, d_position, 'l_item_id_tbl', l_item_id_tbl);
2729     PO_LOG.stmt(d_module, d_position, 'l_job_id_tbl', l_job_id_tbl);
2730   END IF;
2731 
2732   FOR i IN 1..l_index_tbl.COUNT
2733   LOOP
2734     l_index := l_index_tbl(i);
2735 
2736     x_lines.order_type_lookup_code_tbl(l_index) := l_order_type_tbl(i);
2737     x_lines.item_id_tbl(l_index) := l_item_id_tbl(i);
2738     x_lines.job_id_tbl(l_index) := l_job_id_tbl(i);
2739   END LOOP;
2740 
2741   PO_TIMING_UTL.stop_time(PO_PDOI_CONSTANTS.g_T_LINE_DERIVE);
2742 
2743   IF (PO_LOG.d_proc) THEN
2744     PO_LOG.proc_end (d_module);
2745   END IF;
2746 
2747 EXCEPTION
2748   WHEN OTHERS THEN
2749     PO_MESSAGE_S.add_exc_msg
2750     (
2751       p_pkg_name => d_pkg_name,
2752       p_procedure_name => d_api_name || '.' || d_position
2753     );
2754     RAISE;
2755 END default_lines_for_update;
2756 
2757 -----------------------------------------------------------------------
2758 --Start of Comments
2759 --Name: match_lines
2760 --Function: perform matching logic on line num and item related info;
2761 --          This procedure is called only when the document action is
2762 --          'ORIGINAL' or 'REPLACE' or 'UPDATE Standard PO'
2763 --Parameters:
2764 --IN:
2765 --IN OUT:
2766 --  x_lines
2767 --    record to store all the line rows within the batch;
2768 --OUT:
2769 --End of Comments
2770 ------------------------------------------------------------------------
2771 PROCEDURE match_lines
2772 (
2773   p_data_set_type IN NUMBER,  -- bug5129752
2774   x_lines         IN OUT NOCOPY PO_PDOI_TYPES.lines_rec_type
2775 ) IS
2776 
2777   d_api_name CONSTANT VARCHAR2(30) := 'match_lines';
2778   d_module   CONSTANT VARCHAR2(255) := d_pkg_name || d_api_name || '.';
2779   d_position NUMBER;
2780 
2781   l_index_tbl   DBMS_SQL.NUMBER_TABLE;
2782 
2783   l_create_lines PO_PDOI_TYPES.lines_rec_type;
2784   l_update_lines PO_PDOI_TYPES.lines_rec_type;
2785 
2786   l_rej_intf_line_id_tbl PO_TBL_NUMBER := PO_TBL_NUMBER();
2787 BEGIN
2788   d_position := 0;
2789 
2790   IF (PO_LOG.d_proc) THEN
2791     PO_LOG.proc_begin(d_module);
2792   END IF;
2793 
2794   PO_TIMING_UTL.start_time(PO_PDOI_CONSTANTS.g_T_LINE_MATCH);
2795 
2796   -- initialize index table
2797   PO_PDOI_UTL.generate_ordered_num_list
2798   (
2799     p_size     => x_lines.rec_count,
2800     x_num_list => l_index_tbl
2801   );
2802 
2803   d_position := 10;
2804 
2805   IF (PO_LOG.d_stmt) THEN
2806     PO_LOG.stmt(d_module, d_position, 'start to match lines based on line num');
2807   END IF;
2808 
2809   -- bug5129752
2810   -- For FORCE ALL, simply set all line action to 'ADD'
2811 
2812   IF (p_data_set_type = PO_PDOI_CONSTANTS.g_LINE_CSR_FORCE_ADD) THEN
2813     d_position := 15;
2814 
2815     FOR i IN 1..x_lines.rec_count LOOP
2816       x_lines.po_line_id_tbl(i) :=
2817         PO_PDOI_MAINPROC_UTL_PVT.get_next_po_line_id;
2818 
2819       IF (x_lines.line_num_tbl(i) IS NULL) THEN
2820         x_lines.line_num_tbl(i) :=
2821           PO_PDOI_MAINPROC_UTL_PVT.get_next_line_num
2822           (x_lines.po_header_id_tbl(i));
2823       END IF;
2824 
2825       x_lines.action_tbl(i) := PO_PDOI_CONSTANTS.g_ACTION_ADD;
2826 
2827     END LOOP;
2828 
2829   ELSE
2830 
2831     -- match lines based on line_num
2832     match_lines_on_line_num
2833     (
2834       p_index_tbl   => l_index_tbl,
2835       x_lines       => x_lines
2836     );
2837 
2838     d_position := 20;
2839 
2840     IF (PO_LOG.d_stmt) THEN
2841       PO_LOG.stmt(d_module, d_position, 'start to match lines based on item info');
2842     END IF;
2843 
2844     -- match lines based on item related info
2845     match_lines_on_item_info
2846     (
2847       x_lines       => x_lines
2848     );
2849 
2850     d_position := 30;
2851 
2852   END IF;
2853 
2854   -- check whether line location needs to be created for the line
2855   check_line_locations
2856   (
2857     x_lines       => x_lines
2858   );
2859 
2860   d_position := 40;
2861 
2862   -- split lines based on action
2863   -- all lines with action = 'UPDATE' are location lines
2864   split_lines
2865   (
2866     p_group_num      => NULL,
2867     p_lines          => x_lines,
2868     x_create_lines   => l_create_lines,
2869     x_update_lines   => l_update_lines
2870   );
2871 
2872   IF (PO_LOG.d_stmt) THEN
2873     PO_LOG.stmt(d_module, d_position, 'num of created lines', l_create_lines.rec_count);
2874     PO_LOG.stmt(d_module, d_position, 'num of updated lines', l_update_lines.rec_count);
2875   END IF;
2876 
2877   d_position := 50;
2878 
2879   -- assign l_create_lines to x_lines since it contains
2880   -- all the lines that need to be created
2881   x_lines := l_create_lines;
2882 
2883   -- update location only lines with new po_line_id and price_break_flag
2884   FORALL i IN 1..l_update_lines.rec_count
2885     UPDATE po_lines_interface
2886     SET    po_line_id = l_update_lines.po_line_id_tbl(i),
2887            price_break_flag = 'Y'
2888     WHERE  interface_line_id = l_update_lines.intf_line_id_tbl(i);
2889 
2890   d_position := 60;
2891 
2892   -- reject lines that has action=UPDATE and create_line_loc=N
2893   -- insert error message if the line is neither a po line or location
2894   FOR i IN 1..l_update_lines.rec_count
2895   LOOP
2896     IF (PO_LOG.d_stmt) THEN
2897       PO_LOG.stmt(d_module, d_position, 'index', i);
2898       PO_LOG.stmt(d_module, d_position, 'create location flag',
2899                   l_update_lines.create_line_loc_tbl(i));
2900 
2901     END IF;
2902 
2903     IF (l_update_lines.create_line_loc_tbl(i) = FND_API.g_FALSE) THEN
2904       PO_PDOI_ERR_UTL.add_fatal_error
2905       (
2906         p_interface_header_id  => l_update_lines.intf_header_id_tbl(i),
2907         p_interface_line_id    => l_update_lines.intf_line_id_tbl(i),
2908         p_error_message_name   => 'PO_PDOI_INVALID_INTER_LINE_REC',
2909         p_table_name           => 'PO_LINES_INTERFACE',
2910         p_column_name          => 'CREATE_PO_LINES_FLAG',
2911         p_column_value         => 'N',
2912         p_token1_name          => 'COLUMN_NAME',
2913         p_token1_value         => 'CREATE_PO_LINES_FLAG',
2914         p_token2_name          => 'VALUE',
2915         p_token2_value         => 'N'
2916       );
2917 
2918       l_rej_intf_line_id_tbl.EXTEND;
2919       l_rej_intf_line_id_tbl(l_rej_intf_line_id_tbl.COUNT) := l_update_lines.intf_line_id_tbl(i);
2920       IF (PO_LOG.d_stmt) THEN
2921         PO_LOG.stmt(d_module, d_position, 'to be rejected intf line id',
2922                     l_update_lines.intf_line_id_tbl(i));
2923 
2924       END IF;
2925     END IF;
2926   END LOOP;
2927 
2928   d_position := 70;
2929 
2930   PO_PDOI_UTL.reject_lines_intf
2931   (
2932     p_id_param_type   => PO_PDOI_CONSTANTS.g_INTERFACE_LINE_ID,
2933     p_id_tbl          => l_rej_intf_line_id_tbl,
2934     p_cascade         => FND_API.g_TRUE
2935   );
2936 
2937   PO_TIMING_UTL.stop_time(PO_PDOI_CONSTANTS.g_T_LINE_MATCH);
2938 
2939   IF (PO_LOG.d_proc) THEN
2940     PO_LOG.proc_end (d_module);
2941   END IF;
2942 
2943 EXCEPTION
2944   WHEN OTHERS THEN
2945     PO_MESSAGE_S.add_exc_msg
2946     (
2947       p_pkg_name => d_pkg_name,
2948       p_procedure_name => d_api_name || '.' || d_position
2949     );
2950     RAISE;
2951 END match_lines;
2952 
2953 -----------------------------------------------------------------------
2954 --Start of Comments
2955 --Name: check_line_locations
2956 --Function: At the beginning of PDOI process, if line_loc_populated_flag
2957 --          is not set, we will create a row in line_location_interface
2958 --          table and copy over the line location related attributes on
2959 --          that line no matter whether user wants to create a location
2960 --          for that po line.
2961 --          In this procedure, we will check the real intention of user
2962 --          and obsolete location lines that should not be save to txn table.
2963 --Parameters:
2964 --IN:
2965 --IN OUT:
2966 --  x_lines
2967 --    record to store all the line rows within the batch;
2968 --OUT:
2969 --End of Comments
2970 ------------------------------------------------------------------------
2971 PROCEDURE check_line_locations
2972 (
2973   x_lines       IN OUT NOCOPY PO_PDOI_TYPES.lines_rec_type
2974 ) IS
2975 
2976   d_api_name CONSTANT VARCHAR2(30) := 'check_line_locations';
2977   d_module   CONSTANT VARCHAR2(255) := d_pkg_name || d_api_name || '.';
2978   d_position NUMBER;
2979 
2980   -- table to mark which line location needs to rejected in
2981   -- line location interface table
2982   l_obsoleted_loc_tbl  PO_TBL_NUMBER := PO_TBL_NUMBER();
2983   l_obsolete_rec_count              NUMBER := 0;
2984 
2985 BEGIN
2986   d_position := 0;
2987 
2988   IF (PO_LOG.d_proc) THEN
2989     PO_LOG.proc_begin(d_module);
2990   END IF;
2991 
2992   l_obsoleted_loc_tbl.EXTEND(x_lines.rec_count);
2993 
2994   -- check whether location should be created on each line
2995   FOR i IN 1..x_lines.rec_count
2996   LOOP
2997     d_position := 10;
2998 
2999     IF (PO_LOG.d_stmt) THEN
3000       PO_LOG.stmt(d_module, d_position, 'index', i);
3001       PO_LOG.stmt(d_module, d_position, 'loc populated flag',
3002                   x_lines.line_loc_populated_flag_tbl(i));
3003     END IF;
3004 
3005     IF (x_lines.line_loc_populated_flag_tbl(i) = 'S') THEN
3006       IF (PO_LOG.d_stmt) THEN
3007         PO_LOG.stmt(d_module, d_position, 'document type',
3008                     PO_PDOI_PARAMS.g_request.document_type);
3009         PO_LOG.stmt(d_module, d_position, 'order_type_lookup_code',
3010                     x_lines.order_type_lookup_code_tbl(i));
3011         PO_LOG.stmt(d_module, d_position, 'action',
3012                     x_lines.action_tbl(i));
3013         PO_LOG.stmt(d_module, d_position, 'quantity',
3014                     x_lines.quantity_tbl(i));
3015         PO_LOG.stmt(d_module, d_position, 'shipment_num',
3016                     x_lines.shipment_num_tbl(i));
3017       END IF;
3018       -- set to TRUE in certain conditions
3019       IF (PO_PDOI_PARAMS.g_request.document_type =
3020           PO_PDOI_CONSTANTS.g_DOC_TYPE_BLANKET) THEN
3021         IF (x_lines.order_type_lookup_code_tbl(i) IN ('QUANTITY', 'RATE') AND
3022             x_lines.action_tbl(i) = PO_PDOI_CONSTANTS.g_ACTION_UPDATE AND
3023             (x_lines.quantity_tbl(i) > 0 OR x_lines.shipment_num_tbl(i) IS NOT NULL)) THEN
3024           x_lines.create_line_loc_tbl(i) := FND_API.g_TRUE;
3025         END IF;
3026       ELSIF (PO_PDOI_PARAMS.g_request.document_type =
3027              PO_PDOI_CONSTANTS.g_DOC_TYPE_STANDARD) THEN
3028         IF (x_lines.order_type_lookup_code_tbl(i) IN ('FIXED PRICE', 'RATE') OR
3029             x_lines.quantity_tbl(i) > 0) THEN
3030           x_lines.create_line_loc_tbl(i) := FND_API.g_TRUE;
3031         END IF;
3032       ELSIF (PO_PDOI_PARAMS.g_request.document_type =
3033              PO_PDOI_CONSTANTS.g_DOC_TYPE_QUOTATION) THEN
3034         IF (x_lines.order_type_lookup_code_tbl(i) = 'QUANTITY' AND
3035             (x_lines.quantity_tbl(i) > 0 OR x_lines.shipment_num_tbl(i) IS NOT NULL)) THEN
3036           x_lines.create_line_loc_tbl(i) := FND_API.g_TRUE;
3037         END IF;
3038       END IF;
3039 
3040       IF (PO_LOG.d_stmt) THEN
3041         PO_LOG.stmt(d_module, d_position, 'create_line_loc',
3042                     x_lines.create_line_loc_tbl(i));
3043       END IF;
3044 
3045       d_position := 20;
3046 
3047       -- mark down locations that need to be obsoleted after the looping
3048 
3049       IF (x_lines.create_line_loc_tbl(i) = FND_API.g_FALSE) THEN
3050         l_obsolete_rec_count := l_obsolete_rec_count + 1;
3051         l_obsoleted_loc_tbl(l_obsolete_rec_count) := x_lines.intf_line_id_tbl(i);
3052       END IF;
3053 
3054     END IF;
3055   END LOOP;
3056 
3057   -- trim the entries that were not populated
3058   l_obsoleted_loc_tbl.TRIM (l_obsoleted_loc_tbl.COUNT - l_obsolete_rec_count);
3059 
3060 
3061   d_position := 30;
3062 
3063   -- obsolete the location lines that have been marked
3064   FORALL i IN 1..l_obsoleted_loc_tbl.COUNT
3065     UPDATE po_line_locations_interface
3066     SET    process_code = PO_PDOI_CONSTANTS.g_PROCESS_CODE_OBSOLETE
3067     WHERE interface_line_id = l_obsoleted_loc_tbl(i);
3068 
3069 /*
3070   PO_PDOI_UTL.reject_line_locations_intf
3071   (
3072     p_id_param_type           => PO_PDOI_CONSTANTS.g_INTERFACE_LINE_ID,
3073     p_id_tbl                  => l_obsoleted_loc_tbl,
3074     p_cascade                 => FND_API.g_TRUE
3075   );
3076 */
3077   IF (PO_LOG.d_proc) THEN
3078     PO_LOG.proc_end (d_module);
3079   END IF;
3080 
3081 EXCEPTION
3082   WHEN OTHERS THEN
3083     PO_MESSAGE_S.add_exc_msg
3084     (
3085       p_pkg_name => d_pkg_name,
3086       p_procedure_name => d_api_name || '.' || d_position
3087     );
3088     RAISE;
3089 END check_line_locations;
3090 
3091 -----------------------------------------------------------------------
3092 --Start of Comments
3093 --Name: update_line_intf_tbl
3094 --Function: After line processing, set po_line_id, extracted line
3095 --          level action and price tolerance back to interface table
3096 --Parameters:
3097 --IN:
3098 --IN OUT:
3099 --  x_lines
3100 --    record which stores all the line rows within the batch;
3101 --OUT:
3102 --End of Comments
3103 ------------------------------------------------------------------------
3104 PROCEDURE update_line_intf_tbl
3105 (
3106   x_lines    IN OUT NOCOPY PO_PDOI_TYPES.lines_rec_type
3107 ) IS
3108 
3109   d_api_name CONSTANT VARCHAR2(30) := 'update_line_intf_tbl';
3110   d_module   CONSTANT VARCHAR2(255) := d_pkg_name || d_api_name || '.';
3111   d_position NUMBER;
3112 
3113 BEGIN
3114   d_position := 0;
3115 
3116   IF (PO_LOG.d_proc) THEN
3117     PO_LOG.proc_begin(d_module);
3118   END IF;
3119 
3120   d_position := 10;
3121 
3122   FOR i IN 1..x_lines.rec_count
3123   LOOP
3124     IF (NVL(x_lines.process_code_tbl(i), PO_PDOI_CONSTANTS.g_PROCESS_CODE_PENDING)
3125           = PO_PDOI_CONSTANTS.g_PROCESS_CODE_PENDING AND
3126         NVL(PO_PDOI_PARAMS.g_request.process_code, PO_PDOI_CONSTANTS.g_PROCESS_CODE_PENDING) =
3127           PO_PDOI_CONSTANTS.g_PROCESS_CODE_PENDING)
3128        OR
3129        (NVL(x_lines.process_code_tbl(i), PO_PDOI_CONSTANTS.g_PROCESS_CODE_PENDING)
3130           = PO_PDOI_CONSTANTS.g_PROCESS_CODE_PENDING AND
3131         NVL(PO_PDOI_PARAMS.g_request.process_code, PO_PDOI_CONSTANTS.g_PROCESS_CODE_PENDING) =
3132           PO_PDOI_CONSTANTS.g_PROCESS_CODE_NOTIFIED) THEN
3133 
3134       IF (x_lines.error_flag_tbl(i) = FND_API.g_FALSE AND
3135           x_lines.need_to_reject_flag_tbl(i) = FND_API.g_FALSE) THEN
3136         IF (PO_LOG.d_stmt) THEN
3137           PO_LOG.stmt(d_module, d_position, 'update line process code to ACCEPTED. Index = ', i);
3138         END IF;
3139 
3140         x_lines.process_code_tbl(i) := PO_PDOI_CONSTANTS.g_PROCESS_CODE_ACCEPTED;
3141       END IF;
3142     END IF;
3143   END LOOP;
3144 
3145   d_position := 20;
3146 
3147   FORALL i IN 1.. x_lines.rec_count
3148     UPDATE po_lines_interface
3149     SET    po_line_id = x_lines.po_line_id_tbl(i),
3150            price_update_tolerance = x_lines.price_update_tolerance_tbl(i),
3151            action = x_lines.action_tbl(i),
3152            price_break_flag = DECODE(x_lines.action_tbl(i), 'UPDATE',
3153                                 DECODE(x_lines.create_line_loc_tbl(i), FND_API.g_TRUE, 'Y', NULL), NULL),
3154            process_code = x_lines.process_code_tbl(i),
3155            parent_interface_line_id = x_lines.parent_interface_line_id_tbl(i) -- bug5149827
3156     WHERE  interface_line_id = x_lines.intf_line_id_tbl(i);
3157     --AND    x_lines.error_flag_tbl(i) = FND_API.g_FALSE
3158     --AND    x_lines.need_to_reject_flag_tbl(i) = FND_API.g_FALSE;
3159 
3160   IF (PO_LOG.d_proc) THEN
3161     PO_LOG.proc_end (d_module);
3162   END IF;
3163 
3164 EXCEPTION
3165   WHEN OTHERS THEN
3166     PO_MESSAGE_S.add_exc_msg
3167     (
3168       p_pkg_name => d_pkg_name,
3169       p_procedure_name => d_api_name || '.' || d_position
3170     );
3171     RAISE;
3172 END update_line_intf_tbl;
3173 
3174 -----------------------------------------------------------------------
3175 --Start of Comments
3176 --Name: uniqueness_check
3177 --Function: If document level action is 'UPDATE' on Blanket and Quotation,
3178 --          uniqueness check needs to be performed on each line to
3179 --          determine the line level action if it is not specified as
3180 --          'ADD' by the customer.
3181 --Parameters:
3182 --IN:
3183 --  p_type
3184 --    flag to determine on which attributes the check will be performed
3185 --  p_group_num
3186 --    current group number in the batch
3187 --IN OUT:
3188 --  x_processing_row_tbl
3189 --    table to indicate whether action has been determined for each row
3190 --    within the batch
3191 --  x_lines
3192 --    record which stores all the line rows within the batch
3193 --  x_expire_line_id_tbl
3194 --    table to store list of lines that are going to be expired
3195 --OUT:
3196 --End of Comments
3197 ------------------------------------------------------------------------
3198 PROCEDURE uniqueness_check
3199 (
3200   p_type                  IN NUMBER,
3201   p_group_num             IN NUMBER,
3202   x_processing_row_tbl    IN OUT NOCOPY DBMS_SQL.NUMBER_TABLE,
3203   x_lines                 IN OUT NOCOPY PO_PDOI_TYPES.lines_rec_type,
3204   x_expire_line_id_tbl    OUT NOCOPY DBMS_SQL.NUMBER_TABLE
3205 ) IS
3206 
3207   d_api_name CONSTANT VARCHAR2(30) := 'uniqueness_check';
3208   d_module   CONSTANT VARCHAR2(255) := d_pkg_name || d_api_name || '.';
3209   d_position NUMBER;
3210 
3211   -- key of temp table used to identify the records
3212   l_key                   po_session_gt.key%TYPE;
3213 
3214   -- table storing the index of records within the batch
3215   l_index_tbl             DBMS_SQL.NUMBER_TABLE;
3216   l_index                 NUMBER;
3217 
3218   -- store the index of lines that need to be expired
3219   l_expire_line_index_tbl PO_TBL_NUMBER;
3220 
3221   -- counter
3222   l_count                 NUMBER := 0;
3223 BEGIN
3224   d_position := 0;
3225 
3226   IF (PO_LOG.d_proc) THEN
3227     PO_LOG.proc_begin(d_module, 'p_type', p_type);
3228     PO_LOG.proc_begin(d_module, 'p_group_num', p_group_num);
3229 
3230     l_index := x_processing_row_tbl.FIRST;
3231     WHILE (l_index IS NOT NULL)
3232     LOOP
3233       PO_LOG.proc_begin(d_module, 'to be processed index', l_index);
3234       l_index := x_processing_row_tbl.NEXT(l_index);
3235     END LOOP;
3236   END IF;
3237 
3238   PO_TIMING_UTL.start_time(PO_PDOI_CONSTANTS.g_T_LINE_UNIQUENESS_CHECK);
3239 
3240   -- get key value for po_session_gt table
3241   l_key := PO_CORE_S.get_session_gt_nextval;
3242 
3243   -- call individual uniqueness check procedure for each unique criteria
3244   IF (p_type = PO_PDOI_CONSTANTS.g_LINE_CSR_SYNC_ON_DESC) THEN
3245     d_position := 10;
3246 
3247     uniqueness_check_on_desc
3248     (
3249       p_key                 => l_key,
3250       p_group_num           => p_group_num,
3251       x_processing_row_tbl  => x_processing_row_tbl,
3252       x_lines               => x_lines
3253     );
3254   ELSE
3255     d_position := 20;
3256 
3257     -- uniqueness check on item + revision + vendor_product_num +
3258     -- supplier_part_auxid if item is not null
3259     uniqueness_check_on_item
3260     (
3261       p_key                 => l_key,
3262       p_group_num           => p_group_num,
3263       x_processing_row_tbl  => x_processing_row_tbl,
3264       x_lines               => x_lines
3265     );
3266 
3267     d_position := 30;
3268 
3269     -- uniquess check on vendor_product_num + supplier_part_auxid if item
3270     -- is null but vendor_product_num is not null
3271     uniqueness_check_on_vpn
3272     (
3273       p_key                 => l_key,
3274       p_group_num           => p_group_num,
3275       x_processing_row_tbl  => x_processing_row_tbl,
3276       x_lines               => x_lines
3277     );
3278 
3279     d_position := 40;
3280 
3281     -- uniquess check on job_name if both item and vendor_product_num are null
3282     uniqueness_check_on_job
3283     (
3284       p_key                 => l_key,
3285       p_group_num           => p_group_num,
3286       x_processing_row_tbl  => x_processing_row_tbl,
3287       x_lines               => x_lines
3288     );
3289 
3290     d_position := 50;
3291 
3292     -- uniquess check on line_num if item, vendor_product_num and job_name
3293     -- are all null
3294     uniqueness_check_on_line_num
3295     (
3296       p_key                 => l_key,
3297       p_group_num           => p_group_num,
3298       x_processing_row_tbl  => x_processing_row_tbl,
3299       x_lines               => x_lines
3300     );
3301 
3302     -- set action to ADD for lines that does not have any
3303     -- matching attributes specified
3304     FOR i IN 1..x_lines.rec_count
3305     LOOP
3306       d_position := 60;
3307 
3308       IF (x_lines.item_tbl(i) IS NULL AND
3309           x_lines.vendor_product_num_tbl(i) IS NULL AND
3310       x_lines.job_name_tbl(i) IS NULL AND
3311           x_lines.line_num_tbl(i) IS NULL) THEN
3312 
3313         x_lines.action_tbl(i) := PO_PDOI_CONSTANTS.g_ACTION_ADD;
3314         x_lines.group_num_tbl(i) := p_group_num;
3315         x_lines.po_line_id_tbl(i) := PO_PDOI_MAINPROC_UTL_PVT.get_next_po_line_id;
3316         x_lines.line_num_tbl(i) :=
3317           PO_PDOI_MAINPROC_UTL_PVT.get_next_line_num
3318           (
3319             p_po_header_id  => x_lines.hd_po_header_id_tbl(i)
3320           );
3321         x_processing_row_tbl.DELETE(i);
3322 
3323         IF (PO_LOG.d_stmt) THEN
3324           PO_LOG.stmt(d_module, d_position, 'set action to ADD '||
3325                       'since all uniqueness criteria are empty');
3326           PO_LOG.stmt(d_module, d_position, 'index', i);
3327           PO_LOG.stmt(d_module, d_position, 'new po line id',
3328                       x_lines.po_line_id_tbl(i));
3329           PO_LOG.stmt(d_module, d_position, 'new line num',
3330                       x_lines.line_num_tbl(i));
3331         END IF;
3332       END IF;
3333     END LOOP;
3334   END IF;
3335 
3336   d_position := 70;
3337 
3338   -- If there is release shipment for a blanket line, and uom is changed,
3339   -- the existing matching line will be expired and the new line's action
3340   --  will be ADD instead of UPDATE
3341   IF (PO_PDOI_PARAMS.g_request.document_type =
3342       PO_PDOI_CONSTANTS.g_DOC_TYPE_BLANKET) THEN
3343     d_position := 80;
3344 
3345     -- derive unit_of_measure from uom_code
3346     PO_PDOI_UTL.generate_ordered_num_list
3347     (
3348       p_size     => x_lines.rec_count,
3349       x_num_list => l_index_tbl
3350     );
3351 
3352     derive_unit_of_measure
3353     (
3354       p_key                  => l_key,
3355       p_index_tbl            => l_index_tbl,
3356       p_uom_code_tbl         => x_lines.uom_code_tbl,
3357       x_unit_of_measure_tbl  => x_lines.unit_of_measure_tbl
3358     );
3359 
3360     d_position := 90;
3361 
3362     -- check whether uom changed for a line that has a release shipment
3363     FORALL i IN 1..x_lines.rec_count
3364       INSERT INTO po_session_gt(key, num1)
3365       SELECT l_key,
3366              l_index_tbl(i)
3367       FROM   po_lines txn_lines
3368       WHERE  txn_lines.po_line_id = x_lines.po_line_id_tbl(i)
3369       AND    x_lines.unit_of_measure_tbl(i) IS NOT NULL
3370       AND    txn_lines.unit_meas_lookup_code IS NOT NULL
3371       AND    txn_lines.unit_meas_lookup_code <>
3372              x_lines.unit_of_measure_tbl(i)
3373       AND    (EXISTS (SELECT 1
3374                       FROM   po_line_locations
3375                       WHERE  po_line_id = txn_lines.po_line_id
3376                       AND    shipment_type = 'BLANKET')
3377               OR
3378               EXISTS (SELECT 1
3379                       FROM   po_lines_all
3380                       WHERE  from_line_id = txn_lines.po_line_id)
3381              );
3382 
3383     DELETE FROM po_session_gt
3384     WHERE key = l_key
3385     RETURNING num1 BULK COLLECT INTO l_expire_line_index_tbl;
3386 
3387     FOR i IN 1..l_expire_line_index_tbl.COUNT
3388     LOOP
3389       l_index := l_expire_line_index_tbl(i);
3390 
3391       IF (PO_LOG.d_stmt) THEN
3392         PO_LOG.stmt(d_module, d_position, 'expire index', i);
3393         PO_LOG.stmt(d_module, d_position, 'expired line id',
3394                     x_lines.po_line_id_tbl(l_index));
3395       END IF;
3396 
3397       x_lines.action_tbl(l_index) := PO_PDOI_CONSTANTS.g_ACTION_ADD;
3398       l_count := l_count + 1;
3399       x_expire_line_id_tbl(l_count) := x_lines.po_line_id_tbl(l_index);
3400       x_lines.po_line_id_tbl(l_index) :=
3401         PO_PDOI_MAINPROC_UTL_PVT.get_next_po_line_id;
3402       IF (x_lines.origin_line_num_tbl(l_index) IS NULL OR
3403           x_lines.line_num_unique_tbl(l_index) = FND_API.g_FALSE) THEN
3404         x_lines.line_num_tbl(l_index) :=
3405           PO_PDOI_MAINPROC_UTL_PVT.get_next_line_num
3406           (
3407             p_po_header_id => x_lines.hd_po_header_id_tbl(i)
3408           );
3409 
3410         IF (PO_LOG.d_stmt) THEN
3411           PO_LOG.stmt(d_module, d_position, 'original line num',
3412                       x_lines.origin_line_num_tbl(l_index));
3413           PO_LOG.stmt(d_module, d_position, 'if line num unique',
3414                       x_lines.line_num_unique_tbl(l_index));
3415           PO_LOG.stmt(d_module, d_position, 'new line num',
3416                       x_lines.line_num_tbl(l_index));
3417         END IF;
3418       END IF;
3419     END LOOP;
3420   END IF;
3421 
3422   PO_TIMING_UTL.stop_time(PO_PDOI_CONSTANTS.g_T_LINE_UNIQUENESS_CHECK);
3423 
3424   IF (PO_LOG.d_proc) THEN
3425     PO_LOG.proc_end (d_module);
3426   END IF;
3427 
3428 EXCEPTION
3429   WHEN OTHERS THEN
3430     PO_MESSAGE_S.add_exc_msg
3431     (
3432       p_pkg_name => d_pkg_name,
3433       p_procedure_name => d_api_name || '.' || d_position
3434     );
3435     RAISE;
3436 END uniqueness_check;
3437 
3438 -----------------------------------------------------------------------
3439 --Start of Comments
3440 --Name: split_lines
3441 --Function: separate the lines within a group depending on action
3442 --Parameters:
3443 --IN:
3444 --  p_group_num
3445 --    current group number
3446 --  p_lines
3447 --    record containing all line info within the batch
3448 --IN OUT:
3449 --  x_create_lines
3450 --    record containging lines that are going to be created
3451 --  x_update_lines
3452 --    record containing lines that are going to be updated
3453 --OUT:
3454 --End of Comments
3455 ------------------------------------------------------------------------
3456 PROCEDURE split_lines
3457 (
3458   p_group_num             IN NUMBER,
3459   p_lines                 IN PO_PDOI_TYPES.lines_rec_type,
3460   x_create_lines          IN OUT NOCOPY PO_PDOI_TYPES.lines_rec_type,
3461   x_update_lines          IN OUT NOCOPY PO_PDOI_TYPES.lines_rec_type
3462 ) IS
3463 
3464   d_api_name CONSTANT VARCHAR2(30) := 'split_lines';
3465   d_module   CONSTANT VARCHAR2(255) := d_pkg_name || d_api_name || '.';
3466   d_position NUMBER;
3467 
3468   -- store index of rows to be copied to different records
3469   l_create_index_tbl   DBMS_SQL.NUMBER_TABLE;
3470   l_update_index_tbl   DBMS_SQL.NUMBER_TABLE;
3471 BEGIN
3472   d_position := 0;
3473 
3474   IF (PO_LOG.d_proc) THEN
3475     PO_LOG.proc_begin(d_module, 'p_group_num', p_group_num);
3476     PO_LOG.proc_begin(d_module, 'group_num_tbl', p_lines.group_num_tbl);
3477     PO_LOG.proc_begin(d_module, 'action_tbl', p_lines.action_tbl);
3478   END IF;
3479 
3480   FOR i IN 1..p_lines.rec_count
3481   LOOP
3482     d_position := 10;
3483 
3484     IF (p_group_num IS NULL OR p_lines.group_num_tbl(i) = p_group_num) THEN
3485       IF (p_lines.action_tbl(i) = PO_PDOI_CONSTANTS.g_ACTION_ADD) THEN
3486         IF (PO_LOG.d_stmt) THEN
3487           PO_LOG.stmt(d_module, d_position, 'lines to create', i);
3488         END IF;
3489 
3490         l_create_index_tbl(i) := i;
3491       ELSIF (p_lines.action_tbl(i) = PO_PDOI_CONSTANTS.g_ACTION_UPDATE) THEN
3492         IF (PO_LOG.d_stmt) THEN
3493           PO_LOG.stmt(d_module, d_position, 'lines to update', i);
3494         END IF;
3495 
3496         l_update_index_tbl(i) := i;
3497       END IF;
3498     END IF;
3499   END LOOP;
3500 
3501   d_position := 20;
3502 
3503   -- copy rows to insert record
3504   copy_lines
3505   (
3506     p_source_lines     => p_lines,
3507     p_source_index_tbl => l_create_index_tbl,
3508     x_target_lines     => x_create_lines
3509   );
3510 
3511   d_position := 30;
3512 
3513   -- copy rows to update record
3514   copy_lines
3515   (
3516     p_source_lines     => p_lines,
3517     p_source_index_tbl => l_update_index_tbl,
3518     x_target_lines     => x_update_lines
3519   );
3520 
3521   IF (PO_LOG.d_proc) THEN
3522     PO_LOG.proc_end(d_module);
3523   END IF;
3524 
3525 EXCEPTION
3526   WHEN OTHERS THEN
3527     PO_MESSAGE_S.add_exc_msg
3528     (
3529       p_pkg_name => d_pkg_name,
3530       p_procedure_name => d_api_name || '.' || d_position
3531     );
3532     RAISE;
3533 END split_lines;
3534 
3535 -----------------------------------------------------------------------
3536 --Start of Comments
3537 --Name: validate_lines
3538 --Function: validate line attributes; the validation of attribute values
3539 --          tlp table will be called here as well in order to track the
3540 --          number of error lines.
3541 --Parameters:
3542 --IN:
3543 --  p_action
3544 --    indicate whether the po lines are going to be created or updated;
3545 --    the values can be 'CREATE' or 'UPDATE'
3546 --IN OUT:
3547 --  x_lines
3548 --    record which stores all the line rows within the batch;
3549 --    If there is error(s) on any attribute of the location row,
3550 --    corresponding value in error_flag_tbl will be set with value
3551 --    FND_API.g_TRUE.
3552 --OUT:
3553 --End of Comments
3554 ------------------------------------------------------------------------
3555 PROCEDURE validate_lines
3556 (
3557   p_action      IN VARCHAR2 DEFAULT 'CREATE',
3558   x_lines       IN OUT NOCOPY PO_PDOI_TYPES.lines_rec_type
3559 ) IS
3560 
3561   d_api_name CONSTANT VARCHAR2(30) := 'validate_lines';
3562   d_module   CONSTANT VARCHAR2(255) := d_pkg_name || d_api_name || '.';
3563   d_position NUMBER;
3564 
3565   l_lines                 PO_LINES_VAL_TYPE := PO_LINES_VAL_TYPE();
3566   l_result_type           VARCHAR2(30);
3567   l_results               po_validation_results_type;
3568   l_parameter_name_tbl    PO_TBL_VARCHAR2000 := PO_TBL_VARCHAR2000();
3569   l_parameter_value_tbl   PO_TBL_VARCHAR2000 := PO_TBL_VARCHAR2000();
3570   l_inventory_org_id_tbl  PO_TBL_NUMBER := PO_TBL_NUMBER();
3571 
3572 BEGIN
3573   d_position := 0;
3574 
3575   IF (PO_LOG.d_proc) THEN
3576     PO_LOG.proc_begin(d_module, 'action', p_action);
3577   END IF;
3578 
3579   PO_TIMING_UTL.start_time(PO_PDOI_CONSTANTS.g_T_LINE_VALIDATE);
3580 
3581   l_lines.interface_id                    := x_lines.intf_line_id_tbl;
3582   l_lines.over_tolerance_error_flag       := x_lines.over_tolerance_err_flag_tbl;
3583   l_lines.expiration_date                 := x_lines.expiration_date_tbl;
3584   l_lines.hdr_start_date                  := x_lines.hd_start_date_tbl;
3585   l_lines.hdr_end_date                    := x_lines.hd_end_date_tbl;
3586   l_lines.global_agreement_flag           := x_lines.hd_global_agreement_flag_tbl;
3587   l_lines.purchase_basis                  := x_lines.purchase_basis_tbl;
3588   l_lines.line_type_id                    := x_lines.line_type_id_tbl;
3589   l_lines.amount                          := x_lines.amount_tbl;
3590   l_lines.contractor_last_name            := x_lines.contractor_last_name_tbl;
3591   l_lines.contractor_first_name           := x_lines.contractor_first_name_tbl;
3592   l_lines.job_id                          := x_lines.job_id_tbl;
3593   l_lines.job_business_group_id           := x_lines.job_business_group_id_tbl;
3594   l_lines.capital_expense_flag            := x_lines.capital_expense_flag_tbl;
3595   l_lines.un_number_id                    := x_lines.un_number_id_tbl;
3596   l_lines.hazard_class_id                 := x_lines.hazard_class_id_tbl;
3597   l_lines.item_id                         := x_lines.item_id_tbl;
3598   l_lines.order_type_lookup_code          := x_lines.order_type_lookup_code_tbl;
3599   l_lines.item_description                := x_lines.item_desc_tbl;
3600   l_lines.unit_meas_lookup_code           := x_lines.unit_of_measure_tbl;
3601   l_lines.item_revision                   := x_lines.item_revision_tbl;
3602   l_lines.category_id                     := x_lines.category_id_tbl;
3603   l_lines.ip_category_id                  := x_lines.ip_category_id_tbl;
3604   l_lines.unit_price                      := x_lines.unit_price_tbl;
3605   l_lines.quantity                        := x_lines.quantity_tbl;
3606   l_lines.po_header_id                    := x_lines.po_header_id_tbl;
3607   l_lines.po_line_id                      := x_lines.po_line_id_tbl;
3608   l_lines.line_num                        := x_lines.line_num_tbl;
3609   l_lines.price_type_lookup_code          := x_lines.price_type_tbl;
3610   l_lines.start_date                      := x_lines.effective_date_tbl;
3611   l_lines.expiration_date                 := x_lines.expiration_date_tbl;
3612   l_lines.not_to_exceed_price             := x_lines.not_to_exceed_price_tbl;
3613   l_lines.release_num                     := x_lines.release_num_tbl;
3614   l_lines.po_release_id                   := x_lines.po_release_id_tbl;
3615   l_lines.source_shipment_id              := x_lines.source_shipment_id_tbl;
3616   l_lines.contract_num                    := x_lines.contract_num_tbl;
3617   l_lines.contract_id                     := x_lines.contract_id_tbl;
3618   l_lines.type_1099                       := x_lines.type_1099_tbl;
3619   l_lines.closed_code                     := x_lines.closed_code_tbl;
3620   l_lines.closed_date                     := x_lines.closed_date_tbl;
3621   l_lines.closed_by                       := x_lines.closed_by_tbl;
3622   l_lines.market_price                    := x_lines.market_price_tbl;
3623   l_lines.committed_amount                := x_lines.committed_amount_tbl;
3624   l_lines.shipment_num                    := x_lines.shipment_num_tbl;
3625   l_lines.capital_expense_flag            := x_lines.capital_expense_flag_tbl;
3626   l_lines.min_release_amount              := x_lines.min_release_amount_tbl;
3627   l_lines.allow_price_override_flag       := x_lines.allow_price_override_flag_tbl;
3628   l_lines.negotiated_by_preparer_flag     := x_lines.negotiated_flag_tbl;
3629   l_lines.secondary_unit_of_measure       := x_lines.secondary_unit_of_meas_tbl;
3630   l_lines.secondary_quantity              := x_lines.secondary_quantity_tbl;
3631   l_lines.preferred_grade                 := x_lines.preferred_grade_tbl;
3632   l_lines.item                            := x_lines.item_tbl;
3633   l_lines.hdr_style_id                    := x_lines.hd_style_id_tbl;
3634   l_lines.price_break_lookup_code         := x_lines.price_break_lookup_code_tbl; -- bug5016163
3635   l_lines.draft_id                        := x_lines.draft_id_tbl; -- bug5258790
3636   l_lines.hdr_rate_type                   := x_lines.hd_rate_type_tbl; -- bug 5451908
3637 
3638   d_position := 10;
3639 
3640   l_inventory_org_id_tbl.EXTEND(x_lines.intf_line_id_tbl.COUNT);
3641 
3642   FOR i IN 1..x_lines.intf_line_id_tbl.COUNT LOOP
3643      l_inventory_org_id_tbl(i) := PO_PDOI_PARAMS.g_sys.master_inv_org_id;
3644   END LOOP;
3645   l_lines.inventory_org_id   := l_inventory_org_id_tbl;
3646 
3647   d_position := 20;
3648 
3649   l_parameter_name_tbl.EXTEND(3);
3650   l_parameter_value_tbl.EXTEND(3);
3651   l_parameter_name_tbl(1)                 := 'CREATE_OR_UPDATE_ITEM';
3652   l_parameter_value_tbl(1)                := PO_PDOI_PARAMS.g_request.create_items;
3653   l_parameter_name_tbl(2)                 := 'INVENTORY_ORG_ID';
3654   l_parameter_value_tbl(2)                := PO_PDOI_PARAMS.g_sys.def_inv_org_id; -- bug5601416
3655   l_parameter_name_tbl(3)                 := 'DOC_TYPE';
3656   l_parameter_value_tbl(3)                := PO_PDOI_PARAMS.g_request.document_type;
3657 
3658   d_position := 30;
3659 
3660   PO_VALIDATIONS.validate_pdoi
3661   (
3662     p_lines                => l_lines,
3663     p_doc_type             => PO_PDOI_PARAMS.g_request.document_type,
3664     p_action               => p_action,
3665     p_parameter_name_tbl   => l_parameter_name_tbl,
3666     p_parameter_value_tbl  => l_parameter_value_tbl,
3667     x_result_type          => l_result_type,
3668     x_results              => l_results
3669   );
3670 
3671   d_position := 40;
3672 
3673   IF (l_result_type = po_validations.c_result_type_failure) THEN
3674     IF (PO_LOG.d_stmt) THEN
3675       PO_LOG.stmt(d_module, d_position, 'vaidate lines return failure');
3676     END IF;
3677 
3678     PO_PDOI_ERR_UTL.process_val_type_errors
3679     (
3680       x_results    => l_results,
3681       p_table_name => 'PO_LINES_INTERFACE',
3682       p_lines      => x_lines
3683     );
3684 
3685     d_position := 50;
3686 
3687     populate_error_flag
3688     (
3689       x_results  => l_results,
3690       x_lines    => x_lines
3691     );
3692   END IF;
3693 
3694   d_position := 60;
3695 
3696   IF l_result_type = po_validations.c_result_type_fatal THEN
3697     IF (PO_LOG.d_stmt) THEN
3698       PO_LOG.stmt(d_module, d_position, 'vaidate lines return fatal');
3699     END IF;
3700 
3701     RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
3702   END IF;
3703 
3704   d_position := 70;
3705 
3706   -- validate tlp table in advance for tracking of num of error lines.
3707   IF (p_action = 'CREATE') THEN
3708     IF (PO_LOG.d_stmt) THEN
3709       PO_LOG.stmt(d_module, d_position, 'start to validate attribute tlp table');
3710     END IF;
3711 
3712     d_position := 80;
3713 
3714     validate_attr_tlp
3715     (
3716       x_lines => x_lines
3717     );
3718   END IF;
3719 
3720   d_position := 90;
3721 
3722   handle_err_tolerance
3723   (
3724     x_lines => x_lines
3725   );
3726 
3727   d_position := 100;
3728 
3729   PO_TIMING_UTL.stop_time(PO_PDOI_CONSTANTS.g_T_LINE_VALIDATE);
3730 
3731   IF (PO_LOG.d_proc) THEN
3732     PO_LOG.proc_end(d_module, 'result_type', l_result_type);
3733   END IF;
3734 
3735 EXCEPTION
3736   WHEN OTHERS THEN
3737     PO_MESSAGE_S.add_exc_msg
3738     (
3739       p_pkg_name => d_pkg_name,
3740       p_procedure_name => d_api_name || '.' || d_position
3741     );
3742     RAISE;
3743 END validate_lines;
3744 
3745 ------------------------------------------------------------------------
3746 -------------------- PRIVATE PROCEDURES --------------------------------
3747 ------------------------------------------------------------------------
3748 
3749 -- bug5684695
3750 -- removed the content for procedure derive_po_header_id
3751 
3752 -----------------------------------------------------------------------
3753 --Start of Comments
3754 --Name: derive_item_id
3755 --Function: derive item_id from item or vendor_product_num
3756 --Parameters:
3757 --IN:
3758 --  p_key
3759 --    key used to identify rows in po_session_gt
3760 --  p_index_tbl
3761 --    table containging the indexes of all rows
3762 --  p_vendor_id_tbl
3763 --    list of vendor_ids read from the header
3764 --  p_intf_header_id_tbl
3765 --    identifiers of interface headers
3766 --  p_intf_line_id_tbl
3767 --    identifiers of interface lines
3768 --  p_vendor_product_num_tbl
3769 --    list of vendor_product_nums read within the batch
3770 --  p_category_id_tbl
3771 --    list of category_ids read within the batch
3772 --  p_item_tbl
3773 --    list of items read within the batch
3774 --IN OUT:
3775 --  x_item_id_tbl
3776 --    list of item_ids read within the batch;
3777 --    derived result will be saved here as well;
3778 --  x_error_flag_tbl
3779 --    table to mark whether there is error on each row
3780 --OUT:
3781 --End of Comments
3782 ------------------------------------------------------------------------
3783 PROCEDURE derive_item_id
3784 (
3785   p_key                    IN po_session_gt.key%TYPE,
3786   p_index_tbl              IN DBMS_SQL.NUMBER_TABLE,
3787   p_vendor_id_tbl          IN PO_TBL_NUMBER,
3788   p_intf_header_id_tbl     IN PO_TBL_NUMBER,
3789   p_intf_line_id_tbl       IN PO_TBL_NUMBER,
3790   p_vendor_product_num_tbl IN PO_TBL_VARCHAR30,
3791   p_category_id_tbl        IN PO_TBL_NUMBER,            --bug 7374337
3792   p_item_tbl               IN PO_TBL_VARCHAR2000,
3793   x_item_id_tbl            IN OUT NOCOPY PO_TBL_NUMBER,
3794   x_error_flag_tbl         IN OUT NOCOPY PO_TBL_VARCHAR1
3795 ) IS
3796 
3797   d_api_name CONSTANT VARCHAR2(30) := 'derive_item_id';
3798   d_module   CONSTANT VARCHAR2(255) := d_pkg_name || d_api_name || '.';
3799   d_position NUMBER;
3800 
3801   -- tables to store the derived result
3802   l_index_tbl        PO_TBL_NUMBER;
3803   l_result_tbl       PO_TBL_NUMBER;
3804 
3805   -- variable to hold index of the current processing row
3806   l_index            NUMBER;
3807 
3808   -- variables to indicate whether multiple_buyer_part error is already inserted
3809   l_error_exist_tbl  DBMS_SQL.NUMBER_TABLE;
3810 BEGIN
3811   d_position := 0;
3812 
3813   IF (PO_LOG.d_proc) THEN
3814     PO_LOG.proc_begin(d_module, 'p_vendor_id_tbl', p_vendor_id_tbl);
3815     PO_LOG.proc_begin(d_module, 'p_intf_header_id_tbl', p_intf_header_id_tbl);
3816     PO_LOG.proc_begin(d_module, 'p_intf_line_id_tbl', p_intf_line_id_tbl);
3817     PO_LOG.proc_begin(d_module, 'p_vendor_product_num_tbl', p_vendor_product_num_tbl);
3818     PO_LOG.proc_begin(d_module, 'p_category_id_tbl', p_category_id_tbl);
3819     PO_LOG.proc_begin(d_module, 'p_item_tbl', p_item_tbl);
3820     PO_LOG.proc_begin(d_module, 'x_item_id_tbl', x_item_id_tbl);
3821     PO_LOG.proc_begin(d_module, 'x_error_flag_tbl', x_error_flag_tbl);
3822   END IF;
3823 
3824   -- derive based on item_num
3825   FORALL i IN 1..p_index_tbl.COUNT
3826     INSERT INTO po_session_gt(key, num1, num2)
3827     SELECT p_key,
3828            p_index_tbl(i),
3829            inventory_item_id
3830     FROM   mtl_system_items_kfv
3831     WHERE  p_item_tbl(i) IS NOT NULL
3832     AND    x_item_id_tbl(i) IS NULL
3833     AND    concatenated_segments = p_item_tbl(i)
3834     AND    organization_id = PO_PDOI_PARAMS.g_sys.def_inv_org_id;
3835 
3836   d_position := 10;
3837 
3838   -- derive based on vendor_product_num
3839   -- bug 7374337 Added an AND condidtion in the below
3840   -- sql so that matched category for the vendor product number
3841   -- item id will be derived.
3842 
3843   FORALL i IN 1.. p_index_tbl.COUNT
3844     INSERT INTO po_session_gt(key, num1, num2)
3845     SELECT DISTINCT
3846            p_key,
3847            p_index_tbl(i),
3848            txn_lines.item_id
3849     FROM   po_headers txn_headers, po_lines txn_lines
3850     WHERE  txn_headers.po_header_id = txn_lines.po_header_id
3851     AND    p_item_tbl(i) IS NULL
3852     AND    x_item_id_tbl(i) IS NULL
3853     AND    p_vendor_product_num_tbl(i) IS NOT NULL
3854     AND    txn_lines.vendor_product_num = p_vendor_product_num_tbl(i)
3855     AND    txn_headers.vendor_id = p_vendor_id_tbl(i)
3856     AND    txn_lines.item_id IS NOT NULL
3857     AND    ( (p_category_id_tbl(i) IS NOT NULL                   --bug 7374337 <S>
3858             AND txn_lines.category_id = p_category_id_tbl(i))
3859             OR (p_category_id_tbl(i) IS NULL )                   --bug 7374337 <E>
3860            );
3861 
3862   d_position := 20;
3863 
3864   -- read result from temp table, and delete the records from temp table
3865   DELETE FROM po_session_gt
3866   WHERE  key = p_key
3867   RETURNING num1, num2 BULK COLLECT INTO l_index_tbl, l_result_tbl;
3868 
3869   d_position := 30;
3870 
3871   -- push the result back to x_item_ids
3872   FOR i IN 1..l_index_tbl.COUNT
3873   LOOP
3874     l_index := l_index_tbl(i);
3875 
3876     IF (PO_LOG.d_stmt) THEN
3877       PO_LOG.stmt(d_module, d_position, 'index', l_index);
3878       PO_LOG.stmt(d_module, d_position, 'result item id',
3879                   l_result_tbl(i));
3880     END IF;
3881 
3882     IF (NOT l_error_exist_tbl.EXISTS(l_index)) THEN
3883       IF (x_item_id_tbl(l_index) IS NULL) THEN
3884         x_item_id_tbl(l_index) := l_result_tbl(i);
3885       ELSE
3886         x_item_id_tbl(l_index) := NULL;
3887         x_error_flag_tbl(l_index) := FND_API.G_TRUE;
3888         l_error_exist_tbl(l_index) := l_index;
3889         -- insert error
3890         PO_PDOI_ERR_UTL.add_fatal_error
3891         (
3892           p_interface_header_id  => p_intf_header_id_tbl(l_index),
3893           p_interface_line_id    => p_intf_line_id_tbl(l_index),
3894           p_error_message_name   => 'PO_PDOI_MULT_BUYER_PART',
3895           p_table_name           => 'PO_LINES_INTERFACE',
3896           p_column_name          => 'VENDOR_PRODUCT_NUM',
3897           p_column_value         => p_vendor_product_num_tbl(l_index),
3898           p_token2_name          => 'VALUE',
3899           p_token2_value         => p_vendor_product_num_tbl(l_index)
3900         );
3901       END IF;
3902     END IF;
3903   END LOOP;
3904 
3905   IF (PO_LOG.d_proc) THEN
3906     PO_LOG.proc_end(d_module);
3907   END IF;
3908 
3909 EXCEPTION
3910   WHEN OTHERS THEN
3911     PO_MESSAGE_S.add_exc_msg
3912     (
3913       p_pkg_name => d_pkg_name,
3914       p_procedure_name => d_api_name || '.' || d_position
3915     );
3916     RAISE;
3917 END derive_item_id;
3918 
3919 -----------------------------------------------------------------------
3920 --Start of Comments
3921 --Name: derive_item_revision
3922 --Function: reset item_revision based on item_id
3923 --          and create_item parameter value
3924 --Parameters:
3925 --IN:
3926 --  p_key
3927 --    key used to identify rows in po_session_gt
3928 --  p_item_id_tbl
3929 --    list of item_ids read within the batch
3930 --IN OUT:
3931 --  x_item_revision_tbl
3932 --    list of item_revisions read within the batch;
3933 --    derived result will be saved here as well;
3934 --OUT:
3935 --End of Comments
3936 ------------------------------------------------------------------------
3937 PROCEDURE derive_item_revision
3938 (
3939   p_key                    IN po_session_gt.key%TYPE,
3940   p_item_id_tbl            IN PO_TBL_NUMBER,
3941   x_item_revision_tbl      IN OUT NOCOPY PO_TBL_VARCHAR5
3942 ) IS
3943 
3944   d_api_name CONSTANT VARCHAR2(30) := 'derive_item_revision';
3945   d_module   CONSTANT VARCHAR2(255) := d_pkg_name || d_api_name || '.';
3946   d_position NUMBER;
3947 
3948 BEGIN
3949   d_position := 0;
3950 
3951   IF (PO_LOG.d_proc) THEN
3952     PO_LOG.proc_begin(d_module, 'p_item_id_tbl', p_item_id_tbl);
3953     PO_LOG.proc_begin(d_module, 'x_item_revision_tbl', x_item_revision_tbl);
3954   END IF;
3955 
3956   FOR i IN 1..p_item_id_tbl.COUNT
3957   LOOP
3958     IF (p_item_id_tbl(i) IS NULL AND
3959         X_item_revision_tbl(i) IS NOT NULL AND
3960         PO_PDOI_PARAMS.g_request.create_items = 'Y') THEN
3961       IF (PO_LOG.d_stmt) THEN
3962         PO_LOG.stmt(d_module, d_position, 'index', i);
3963         PO_LOG.stmt(d_module, d_position, 'new item revision set to empty');
3964       END IF;
3965 
3966       x_item_revision_tbl(i) := NULL;
3967     END IF;
3968   END LOOP;
3969 
3970   IF (PO_LOG.d_proc) THEN
3971     PO_LOG.proc_end(d_module);
3972   END IF;
3973 
3974 EXCEPTION
3975   WHEN OTHERS THEN
3976     PO_MESSAGE_S.add_exc_msg
3977     (
3978       p_pkg_name => d_pkg_name,
3979       p_procedure_name => d_api_name || '.' || d_position
3980     );
3981     RAISE;
3982 END derive_item_revision;
3983 
3984 -----------------------------------------------------------------------
3985 --Start of Comments
3986 --Name: derive_job_business_group_id
3987 --Function: derive job_business_group_id from
3988 --          job_business_group_name
3989 --Parameters:
3990 --IN:
3991 --  p_key
3992 --    key used to identify rows in po_session_gt
3993 --  p_index_tbl
3994 --    table containging the indexes of all rows
3995 --  p_job_business_group_name_tbl
3996 --    list of job_business_group_names read within the batch
3997 --IN OUT:
3998 --  x_job_business_group_id_tbl
3999 --    list of job_business_group_ids read within the batch;
4000 --    derived result will be saved here as well;
4001 --    derivation will only occur when job_business_group_name
4002 --    is provided but job_business_group_id is not;
4003 --OUT:
4004 --End of Comments
4005 ------------------------------------------------------------------------
4006 PROCEDURE derive_job_business_group_id
4007 (
4008   p_key                            IN po_session_gt.key%TYPE,
4009   p_index_tbl                      IN DBMS_SQL.NUMBER_TABLE,
4010   p_job_business_group_name_tbl    IN PO_TBL_VARCHAR2000,
4011   x_job_business_group_id_tbl      IN OUT NOCOPY PO_TBL_NUMBER
4012 ) IS
4013 
4014   d_api_name CONSTANT VARCHAR2(30) := 'derive_job_business_group_id';
4015   d_module   CONSTANT VARCHAR2(255) := d_pkg_name || d_api_name || '.';
4016   d_position NUMBER;
4017 
4018   -- tables to store the derived result
4019   l_index_tbl        PO_TBL_NUMBER;
4020   l_result_tbl       PO_TBL_NUMBER;
4021 BEGIN
4022   d_position := 0;
4023 
4024   IF (PO_LOG.d_proc) THEN
4025     PO_LOG.proc_begin(d_module, 'p_job_business_group_name_tbl',
4026                       p_job_business_group_name_tbl);
4027     PO_LOG.proc_begin(d_module, 'x_job_business_group_id_tbl',
4028                       x_job_business_group_id_tbl);
4029   END IF;
4030 
4031   -- derive id from name
4032   FORALL i IN 1.. p_index_tbl.COUNT
4033     INSERT INTO po_session_gt(key, num1, num2)
4034     SELECT p_key,
4035            p_index_tbl(i),
4036            business_group_id
4037     FROM   per_business_groups_perf
4038     WHERE  p_job_business_group_name_tbl(i) IS NOT NULL
4039     AND    x_job_business_group_id_tbl(i) IS NULL
4040     AND    name = p_job_business_group_name_tbl(i)
4041     AND    TRUNC(sysdate) BETWEEN TRUNC(NVL(date_from, sysdate))
4042            AND TRUNC(NVL(date_to, sysdate));
4043 
4044   d_position := 10;
4045 
4046   -- read result from temp table, and delete the records from temp table
4047   DELETE FROM po_session_gt
4048   WHERE  key = p_key
4049   RETURNING num1, num2 BULK COLLECT INTO l_index_tbl, l_result_tbl;
4050 
4051   d_position := 20;
4052 
4053   -- push the result back to x_job_business_group_id_tbl
4054   FOR i IN 1..l_index_tbl.COUNT
4055   LOOP
4056     IF (PO_LOG.d_stmt) THEN
4057       PO_LOG.stmt(d_module, d_position, 'new business group id',
4058                   l_result_tbl(i));
4059     END IF;
4060 
4061     x_job_business_group_id_tbl(l_index_tbl(i)) := l_result_tbl(i);
4062   END LOOP;
4063 
4064   IF (PO_LOG.d_proc) THEN
4065     PO_LOG.proc_end(d_module);
4066   END IF;
4067 
4068 EXCEPTION
4069   WHEN OTHERS THEN
4070     PO_MESSAGE_S.add_exc_msg
4071     (
4072       p_pkg_name => d_pkg_name,
4073       p_procedure_name => d_api_name || '.' || d_position
4074     );
4075     RAISE;
4076 END derive_job_business_group_id;
4077 
4078 -----------------------------------------------------------------------
4079 --Start of Comments
4080 --Name: derive_job_id
4081 --Function: derive job_id from job_business_group_name and job_name
4082 --Parameters:
4083 --IN:
4084 --  p_key
4085 --    key used to identify rows in po_session_gt
4086 --  p_index_tbl
4087 --    table containging the indexes of all rows
4088 --  p_file_line_language_tbl
4089 --    list of line level languages
4090 --  p_job_business_group_name_tbl
4091 --    list of job_business_group_names read within the batch
4092 --  p_job_name_tbl
4093 --    list of job_names read within the batch
4094 --IN OUT:
4095 --  x_job_business_group_id_tbl
4096 --    list of job_business_group_ids read within the batch;
4097 --    derived result will be saved here as well;
4098 --  x_job_id_tbl
4099 --    list of job_ids read within the batch;
4100 --    derived result will be saved here as well;
4101 --    derivation will only occur when job_name
4102 --    is provided but job_id is not;
4103 --OUT:
4104 --End of Comments
4105 ------------------------------------------------------------------------
4106 PROCEDURE derive_job_id
4107 (
4108   p_key                            IN po_session_gt.key%TYPE,
4109   p_index_tbl                      IN DBMS_SQL.NUMBER_TABLE,
4110   p_file_line_language_tbl         IN PO_TBL_VARCHAR5,
4111   p_job_business_group_name_tbl    IN PO_TBL_VARCHAR2000,
4112   p_job_name_tbl                   IN PO_TBL_VARCHAR2000,
4113   x_job_business_group_id_tbl      IN OUT NOCOPY PO_TBL_NUMBER,
4114   x_job_id_tbl                     IN OUT NOCOPY PO_TBL_NUMBER
4115 ) IS
4116 
4117   d_api_name CONSTANT VARCHAR2(30) := 'derive_job_id';
4118   d_module   CONSTANT VARCHAR2(255) := d_pkg_name || d_api_name || '.';
4119   d_position NUMBER;
4120 
4121   -- tables to store the derived result
4122   l_index_tbl        PO_TBL_NUMBER;
4123   l_result_tbl       PO_TBL_NUMBER;
4124 
4125   -- debug variables
4126   d_group_id         NUMBER;
4127   d_job_id_tbl       PO_TBL_NUMBER;
4128   d_job_name_tbl     PO_TBL_VARCHAR2000;
4129   d_bg_id_tbl        PO_TBL_NUMBER;
4130 
4131 BEGIN
4132   d_position := 0;
4133 
4134   IF (PO_LOG.d_proc) THEN
4135     PO_LOG.proc_begin(d_module, 'p_file_line_language_tbl',
4136                       p_file_line_language_tbl);
4137     PO_LOG.proc_begin(d_module, 'p_job_business_group_name_tbl',
4138                       p_job_business_group_name_tbl);
4139     PO_LOG.proc_begin(d_module, 'p_job_name_tbl', p_job_name_tbl);
4140     PO_LOG.proc_begin(d_module, 'x_job_business_group_id_tbl',
4141                       x_job_business_group_id_tbl);
4142     PO_LOG.proc_begin(d_module, 'x_job_id_tbl', x_job_id_tbl);
4143   END IF;
4144 
4145   -- execute different queries to derive job_id depending on profile and
4146   -- value of job_business_group_id
4147   IF (PO_LOG.d_stmt) THEN
4148     PO_LOG.stmt(d_module, d_position, 'business group profile value',
4149                 PO_PDOI_PARAMS.g_profile.xbg);
4150     PO_LOG.stmt(d_module, d_position, 'fsp business_group_id',
4151                 PO_PDOI_PARAMS.g_sys.def_business_group_id);
4152   END IF;
4153 
4154   -- bug 5489942: derive job_id from job_name based on
4155   --              line level language
4156   IF (NVL(PO_PDOI_PARAMS.g_profile.xbg, 'N') = 'N') THEN
4157     d_position := 10;
4158 
4159     -- derive job_id from job_name
4160     FORALL i IN 1..p_index_tbl.COUNT
4161       INSERT INTO po_session_gt(key, num1, num2)
4162       SELECT p_key,
4163              p_index_tbl(i),
4164              jobs_b.job_id
4165       FROM   per_jobs jobs_b,
4166              per_jobs_tl jobs_tl
4167       WHERE  p_job_name_tbl(i) IS NOT NULL
4168       AND    x_job_id_tbl(i) IS NULL
4169       AND    jobs_b.job_id = jobs_tl.job_id
4170       AND    jobs_tl.language = NVL(p_file_line_language_tbl(i), userenv('LANG'))
4171       AND    jobs_tl.name = p_job_name_tbl(i)
4172       AND    jobs_b.business_group_id = PO_PDOI_PARAMS.g_sys.def_business_group_id
4173       AND    PO_PDOI_PARAMS.g_sys.def_business_group_id =
4174                DECODE(p_job_business_group_name_tbl(i), NULL,
4175                DECODE(x_job_business_group_id_tbl(i), NULL,
4176                PO_PDOI_PARAMS.g_sys.def_business_group_id,
4177                x_job_business_group_id_tbl(i)), x_job_business_group_id_tbl(i))
4178       AND    TRUNC(sysdate) BETWEEN TRUNC(NVL(jobs_b.date_from, sysdate))
4179              AND TRUNC(NVL(jobs_b.date_to, sysdate));
4180   ELSE
4181     d_position := 20;
4182 
4183     /*  -- START OF info added for debugging purpose
4184 
4185     select job_id, name, business_group_id
4186     bulk collect into d_job_id_tbl, d_job_name_tbl, d_bg_id_tbl
4187     from per_jobs_vl
4188     where TRUNC(sysdate) BETWEEN TRUNC(NVL(date_from, sysdate))
4189              AND TRUNC(NVL(date_to, sysdate));
4190 
4191     IF (PO_LOG.d_stmt) THEN
4192       PO_LOG.stmt(d_module, d_position, 'debug: d_job_id_tbl',
4193                   d_job_id_tbl);
4194       PO_LOG.stmt(d_module, d_position, 'debug: d_job_name_tbl',
4195                   d_job_name_tbl);
4196       PO_LOG.stmt(d_module, d_position, 'debug: d_bg_id_tbl',
4197                   d_bg_id_tbl);
4198       PO_LOG.stmt(d_module, d_position, 'debug: default bg id',
4199                   PO_PDOI_PARAMS.g_sys.def_business_group_id);
4200     END IF;
4201 
4202     -- END OF info added for debugging purpose */
4203 
4204     -- derive job_id for lines with job_business_group_id = null
4205     FORALL i IN 1..p_index_tbl.COUNT
4206       INSERT INTO po_session_gt(key, num1, num2)
4207       SELECT p_key,
4208              p_index_tbl(i),
4209              jobs_b.job_id
4210       FROM   per_jobs jobs_b,
4211              per_jobs_tl jobs_tl
4212       WHERE  p_job_name_tbl(i) IS NOT NULL
4213       AND    x_job_id_tbl(i) IS NULL
4214       AND    x_job_business_group_id_tbl(i) IS NULL
4215       AND    jobs_b.job_id = jobs_tl.job_id
4216       AND    jobs_tl.language = NVL(p_file_line_language_tbl(i), userenv('LANG'))
4217       AND    jobs_tl.name = p_job_name_tbl(i)
4218       AND    jobs_b.business_group_id = PO_PDOI_PARAMS.g_sys.def_business_group_id
4219       AND    PO_PDOI_PARAMS.g_sys.def_business_group_id =
4220                DECODE(p_job_business_group_name_tbl(i), NULL,
4221                PO_PDOI_PARAMS.g_sys.def_business_group_id,
4222                x_job_business_group_id_tbl(i))
4223       AND    TRUNC(sysdate) BETWEEN TRUNC(NVL(jobs_b.date_from, sysdate))
4224              AND TRUNC(NVL(jobs_b.date_to, sysdate));
4225 
4226     d_position := 30;
4227 
4228     -- derive job_id for lines with job_business_group_id <> null
4229     FORALL i IN 1..p_index_tbl.COUNT
4230       INSERT INTO po_session_gt(key, num1, num2)
4231       SELECT p_key,
4232              p_index_tbl(i),
4233              jobs_b.job_id
4234       FROM   per_jobs jobs_b,
4235              per_jobs_tl jobs_tl,
4236              per_business_groups_perf groups
4237       WHERE  p_job_name_tbl(i) IS NOT NULL
4238       AND    x_job_id_tbl(i) IS NULL
4239       AND    x_job_business_group_id_tbl(i) IS NOT NULL
4240       AND    jobs_b.job_id = jobs_tl.job_id
4241       AND    jobs_tl.language = NVL(p_file_line_language_tbl(i), userenv('LANG'))
4242       AND    jobs_tl.name = p_job_name_tbl(i)
4243       AND    jobs_b.business_group_id = x_job_business_group_id_tbl(i)
4244       AND    jobs_b.business_group_id = groups.business_group_id
4245       AND    TRUNC(sysdate) BETWEEN NVL(jobs_b.date_from, TRUNC(sysdate))
4246              AND NVL(jobs_b.date_to, TRUNC(sysdate))
4247       AND    TRUNC(sysdate) BETWEEN NVL(groups.date_from, TRUNC(sysdate))
4248              AND NVL(groups.date_to, TRUNC(sysdate));
4249   END IF;
4250 
4251   d_position := 40;
4252 
4253   -- retrive result from temp table and delete the records in temp table
4254   DELETE FROM po_session_gt
4255   WHERE  key = p_key
4256   RETURNING num1, num2 BULK COLLECT INTO l_index_tbl, l_result_tbl;
4257 
4258   d_position := 50;
4259 
4260   IF (PO_LOG.d_stmt) THEN
4261     PO_LOG.stmt(d_module, d_position, 'derived result: l_index_tbl',
4262                 l_index_tbl);
4263     PO_LOG.stmt(d_module, d_position, 'derived result: l_result_tbl',
4264                 l_result_tbl);
4265   END IF;
4266 
4267   -- set job_business_group_id if both job_business_group_id
4268   -- and job_business_group_name is empty
4269   FOR i IN 1..p_index_tbl.COUNT
4270   LOOP
4271     IF (p_job_name_tbl(i) IS NOT NULL AND
4272         X_job_id_tbl(i) IS NULL AND
4273         p_job_business_group_name_tbl(i) IS NULL AND
4274         x_job_business_group_id_tbl(i) IS NULL) THEN
4275       x_job_business_group_id_tbl(i) :=
4276              PO_PDOI_PARAMS.g_sys.def_business_group_id;
4277     END IF;
4278   END LOOP;
4279 
4280   d_position := 60;
4281 
4282   -- set job_id from derived values
4283   FOR i IN 1..l_index_tbl.COUNT
4284   LOOP
4285     IF (PO_LOG.d_stmt) THEN
4286       PO_LOG.stmt(d_module, d_position, 'index', l_index_tbl(i));
4287       PO_LOG.stmt(d_module, d_position, 'new job id', l_result_tbl(i));
4288     END IF;
4289 
4290     x_job_id_tbl(l_index_tbl(i)) := l_result_tbl(i);
4291   END LOOP;
4292 
4293   IF (PO_LOG.d_proc) THEN
4294     PO_LOG.proc_end(d_module);
4295   END IF;
4296 
4297 EXCEPTION
4298   WHEN OTHERS THEN
4299     PO_MESSAGE_S.add_exc_msg
4300     (
4301       p_pkg_name => d_pkg_name,
4302       p_procedure_name => d_api_name || '.' || d_position
4303     );
4304     RAISE;
4305 END derive_job_id;
4306 
4307 -----------------------------------------------------------------------
4308 --Start of Comments
4309 --Name: derive_category_id
4310 --Function: derive po category_id from po category name
4311 --Parameters:
4312 --IN:
4313 --  p_key
4314 --    key used to identify rows in po_session_gt
4315 --  p_category_tbl
4316 --    list of categories read within the batch
4317 --IN OUT:
4318 --  x_category_id_tbl
4319 --    list of category_ids read within the batch;
4320 --    derived result will be saved here as well;
4321 --    derivation will only occur when category
4322 --    is provided but category_id is not;
4323 --OUT:
4324 --End of Comments
4325 ------------------------------------------------------------------------
4326 PROCEDURE derive_category_id
4327 (
4328   p_key                  IN po_session_gt.key%TYPE,
4329   p_category_tbl         IN PO_TBL_VARCHAR2000,
4330   x_category_id_tbl      IN OUT NOCOPY PO_TBL_NUMBER
4331 ) IS
4332 
4333   d_api_name CONSTANT VARCHAR2(30) := 'derive_category_id';
4334   d_module   CONSTANT VARCHAR2(255) := d_pkg_name || d_api_name || '.';
4335   d_position NUMBER;
4336 
4337   l_result NUMBER;
4338 BEGIN
4339   d_position := 0;
4340 
4341   IF (PO_LOG.d_proc) THEN
4342     PO_LOG.proc_begin(d_module, 'p_category_tbl', p_category_tbl);
4343     PO_LOG.proc_begin(d_module, 'x_category_id_tbl', x_category_id_tbl);
4344   END IF;
4345 
4346   -- category id is derived by an API provided by FND.
4347   -- so we have to call the APPI multiple times
4348   FOR i IN 1.. p_category_tbl.COUNT
4349   LOOP
4350     IF (p_category_tbl(i) IS NOT NULL AND
4351         x_category_id_tbl(i) IS NULL) THEN
4352       d_position := 10;
4353 
4354       l_result :=
4355            FND_FLEX_EXT.GET_CCID('INV', 'MCAT',
4356                         PO_PDOI_PARAMS.g_sys.def_structure_id,
4357                         to_char(sysdate,'YYYY/MM/DD HH24:MI:SS'),
4358                         p_category_tbl(i));
4359 
4360       IF (PO_LOG.d_stmt) THEN
4361         PO_LOG.stmt(d_module, d_position, 'index', i);
4362         PO_LOG.stmt(d_module, d_position, 'result', l_result);
4363       END IF;
4364 
4365       IF (l_result IS NOT NULL AND l_result <> 0) THEN
4366         x_category_id_tbl(i) := l_result;
4367       END IF;
4368     END IF;
4369   END LOOP;
4370 
4371   IF (PO_LOG.d_proc) THEN
4372     PO_LOG.proc_end(d_module);
4373   END IF;
4374 
4375 EXCEPTION
4376   WHEN OTHERS THEN
4377     PO_MESSAGE_S.add_exc_msg
4378     (
4379       p_pkg_name => d_pkg_name,
4380       p_procedure_name => d_api_name || '.' || d_position
4381     );
4382     RAISE;
4383 END derive_category_id;
4384 
4385 -----------------------------------------------------------------------
4386 --Start of Comments
4387 --Name: derive_ip_category_id
4388 --Function: derive po category_id from po category name
4389 --Parameters:
4390 --IN:
4391 --  p_key
4392 --    key used to identify rows in po_session_gt
4393 --  p_index_tbl
4394 --    table containging the indexes of all rows
4395 --  p_file_line_language_tbl
4396 --    list of line level languages
4397 --  p_ip_category_tbl
4398 --    list of ip_categories read within the batch
4399 --IN OUT:
4400 --  x_ip_category_id_tbl
4401 --    list of ip_category_ids read within the batch;
4402 --    derived result will be saved here as well;
4403 --    derivation will only occur when ip_category
4404 --    is provided but ip_category_id is not;
4405 --OUT:
4406 --End of Comments
4407 ------------------------------------------------------------------------
4408 PROCEDURE derive_ip_category_id
4409 (
4410   p_key                    IN po_session_gt.key%TYPE,
4411   p_index_tbl              IN DBMS_SQL.NUMBER_TABLE,
4412   p_file_line_language_tbl IN PO_TBL_VARCHAR5,
4413   p_ip_category_tbl        IN PO_TBL_VARCHAR2000,
4414   x_ip_category_id_tbl     IN OUT NOCOPY PO_TBL_NUMBER
4415 ) IS
4416 
4417   d_api_name CONSTANT VARCHAR2(30) := 'derive_ip_category_id';
4418   d_module   CONSTANT VARCHAR2(255) := d_pkg_name || d_api_name || '.';
4419   d_position NUMBER;
4420 
4421   -- tables to store the derived result
4422   l_index_tbl        PO_TBL_NUMBER;
4423   l_result_tbl       PO_TBL_NUMBER;
4424 BEGIN
4425   d_position := 0;
4426 
4427   IF (PO_LOG.d_proc) THEN
4428     PO_LOG.proc_begin(d_module, 'p_ip_category_tbl', p_ip_category_tbl);
4429     PO_LOG.proc_begin(d_module, 'p_file_line_language_tbl', p_file_line_language_tbl);
4430     PO_LOG.proc_begin(d_module, 'x_ip_category_id_tbl', x_ip_category_id_tbl);
4431   END IF;
4432 
4433   -- 1. derive ip_category_id based on category key
4434   FORALL i IN 1.. p_index_tbl.COUNT
4435     INSERT INTO po_session_gt(key, num1, char1)
4436     SELECT p_key,
4437            p_index_tbl(i),
4438            cat.rt_category_id
4439     FROM   icx_cat_categories_v cat
4440     WHERE  p_ip_category_tbl(i) IS NOT NULL
4441     AND    x_ip_category_id_tbl(i) IS NULL
4442     AND    cat.key = p_ip_category_tbl(i);
4443 
4444   d_position := 10;
4445 
4446   -- read result from temp table, and delete the records from temp table
4447   DELETE FROM po_session_gt
4448   WHERE  key = p_key
4449   RETURNING num1, char1 BULK COLLECT INTO l_index_tbl, l_result_tbl;
4450 
4451   d_position := 20;
4452 
4453   -- push the result back to x_unit_of_measure_tbl
4454   FOR i IN 1..l_index_tbl.COUNT
4455   LOOP
4456     IF (PO_LOG.d_stmt) THEN
4457       PO_LOG.stmt(d_module, d_position, 'index', l_index_tbl(i));
4458       PO_LOG.stmt(d_module, d_position, 'new ip category id',
4459                   l_result_tbl(i));
4460     END IF;
4461 
4462     x_ip_category_id_tbl(l_index_tbl(i)) := l_result_tbl(i);
4463   END LOOP;
4464 
4465   d_position := 30;
4466 
4467   -- bug 5489942: derivation is based on line level language
4468   -- 2. derive ip_category_id based on category name,
4469   --    name is language specific
4470   FORALL i IN 1.. p_index_tbl.COUNT
4471     INSERT INTO po_session_gt(key, num1, char1)
4472     SELECT p_key,
4473            p_index_tbl(i),
4474            rt_category_id
4475     FROM   icx_cat_categories_v
4476     WHERE  p_ip_category_tbl(i) IS NOT NULL
4477     AND    x_ip_category_id_tbl(i) IS NULL
4478     AND    category_name = p_ip_category_tbl(i)
4479     AND    language = NVL(p_file_line_language_tbl(i),
4480                           userenv('LANG'));
4481 
4482   d_position := 40;
4483 
4484   -- read result from temp table, and delete the records from temp table
4485   DELETE FROM po_session_gt
4486   WHERE  key = p_key
4487   RETURNING num1, char1 BULK COLLECT INTO l_index_tbl, l_result_tbl;
4488 
4489   d_position := 50;
4490 
4491   -- push the result back to x_unit_of_measure_tbl
4492   FOR i IN 1..l_index_tbl.COUNT
4493   LOOP
4494     IF (PO_LOG.d_stmt) THEN
4495       PO_LOG.stmt(d_module, d_position, 'index', l_index_tbl(i));
4496       PO_LOG.stmt(d_module, d_position, 'new ip category id',
4497                   l_result_tbl(i));
4498     END IF;
4499 
4500     x_ip_category_id_tbl(l_index_tbl(i)) := l_result_tbl(i);
4501   END LOOP;
4502 
4503   IF (PO_LOG.d_proc) THEN
4504     PO_LOG.proc_end(d_module);
4505   END IF;
4506 
4507 EXCEPTION
4508   WHEN OTHERS THEN
4509     PO_MESSAGE_S.add_exc_msg
4510     (
4511       p_pkg_name => d_pkg_name,
4512       p_procedure_name => d_api_name || '.' || d_position
4513     );
4514     RAISE;
4515 END derive_ip_category_id;
4516 
4517 -----------------------------------------------------------------------
4518 --Start of Comments
4519 --Name: derive_unit_of_measure
4520 --Function: derive unit_of_measure from uom_code
4521 --Parameters:
4522 --IN:
4523 --  p_key
4524 --    key used to identify rows in po_session_gt
4525 --  p_index_tbl
4526 --    table containging the indexes of all rows
4527 --  p_uom_code_tbl
4528 --    list of uom_codes read within the batch
4529 --IN OUT:
4530 --  x_unit_of_measure_tbl
4531 --    list of unit_of_measures read within the batch;
4532 --    derived result will be saved here as well;
4533 --    derivation will only occur when uom_code
4534 --    is provided but unit_of_measure is not;
4535 --OUT:
4536 --End of Comments
4537 ------------------------------------------------------------------------
4538 PROCEDURE derive_unit_of_measure
4539 (
4540   p_key                  IN po_session_gt.key%TYPE,
4541   p_index_tbl            IN DBMS_SQL.NUMBER_TABLE,
4542   p_uom_code_tbl         IN PO_TBL_VARCHAR5,
4543   x_unit_of_measure_tbl  IN OUT NOCOPY PO_TBL_VARCHAR30
4544 ) IS
4545 
4546   d_api_name CONSTANT VARCHAR2(30) := 'derive_unit_of_measure';
4547   d_module   CONSTANT VARCHAR2(255) := d_pkg_name || d_api_name || '.';
4548   d_position NUMBER;
4549 
4550   -- tables to store the derived result
4551   l_index_tbl        PO_TBL_NUMBER;
4552   l_result_tbl       PO_TBL_VARCHAR30;
4553 BEGIN
4554   d_position := 0;
4555 
4556   IF (PO_LOG.d_proc) THEN
4557     PO_LOG.proc_begin(d_module, 'p_uom_code_tbl', p_uom_code_tbl);
4558     PO_LOG.proc_begin(d_module, 'x_unit_of_measure_tbl', x_unit_of_measure_tbl);
4559   END IF;
4560 
4561   -- derive unit_of_measure from uom_code
4562   FORALL i IN 1.. p_index_tbl.COUNT
4563     INSERT INTO po_session_gt(key, num1, char1)
4564     SELECT p_key,
4565            p_index_tbl(i),
4566            unit_of_measure
4567     FROM   po_units_of_measure_val_v
4568     WHERE  p_uom_code_tbl(i) IS NOT NULL
4569     AND    x_unit_of_measure_tbl(i) IS NULL
4570     AND    uom_code = p_uom_code_tbl(i);
4571 
4572   d_position := 10;
4573 
4574   -- read result from temp table, and delete the records from temp table
4575   DELETE FROM po_session_gt
4576   WHERE  key = p_key
4577   RETURNING num1, char1 BULK COLLECT INTO l_index_tbl, l_result_tbl;
4578 
4579   d_position := 20;
4580 
4581   -- push the result back to x_unit_of_measure_tbl
4582   FOR i IN 1..l_index_tbl.COUNT
4583   LOOP
4584     IF (PO_LOG.d_stmt) THEN
4585       PO_LOG.stmt(d_module, d_position, 'index', l_index_tbl(i));
4586       PO_LOG.stmt(d_module, d_position, 'new unit of measure',
4587                   l_result_tbl(i));
4588     END IF;
4589 
4590     x_unit_of_measure_tbl(l_index_tbl(i)) := l_result_tbl(i);
4591   END LOOP;
4592 
4593   IF (PO_LOG.d_proc) THEN
4594     PO_LOG.proc_end(d_module);
4595   END IF;
4596 
4597 EXCEPTION
4598   WHEN OTHERS THEN
4599     PO_MESSAGE_S.add_exc_msg
4600     (
4601       p_pkg_name => d_pkg_name,
4602       p_procedure_name => d_api_name || '.' || d_position
4603     );
4604     RAISE;
4605 END derive_unit_of_measure;
4606 
4607 -----------------------------------------------------------------------
4608 --Start of Comments
4609 --Name: derive_line_type_id
4610 --Function: derive line_type_id from line_type
4611 --Parameters:
4612 --IN:
4613 --  p_key
4614 --    key used to identify rows in po_session_gt
4615 --  p_index_tbl
4616 --    table containging the indexes of all rows
4617 --  p_file_line_language_tbl
4618 --    list of line level languages
4619 --  p_line_type_tbl
4620 --    list of line_types read within the batch
4621 --IN OUT:
4622 --  x_line_type_id_tbl
4623 --    list of line_type_ids read within the batch;
4624 --    derived result will be saved here as well;
4625 --    derivation will only occur when line_type
4626 --    is provided but line_type_id is not;
4627 --OUT:
4628 --End of Comments
4629 ------------------------------------------------------------------------
4630 PROCEDURE derive_line_type_id
4631 (
4632   p_key                    IN po_session_gt.key%TYPE,
4633   p_index_tbl              IN DBMS_SQL.NUMBER_TABLE,
4634   p_file_line_language_tbl IN PO_TBL_VARCHAR5,
4635   p_line_type_tbl          IN PO_TBL_VARCHAR30,
4636   x_line_type_id_tbl       IN OUT NOCOPY PO_TBL_NUMBER
4637 ) IS
4638 
4639   d_api_name CONSTANT VARCHAR2(30) := 'derive_line_type_id';
4640   d_module   CONSTANT VARCHAR2(255) := d_pkg_name || d_api_name || '.';
4641   d_position NUMBER;
4642 
4643   -- tables to store the derived result
4644   l_index_tbl        PO_TBL_NUMBER;
4645   l_result_tbl       PO_TBL_NUMBER;
4646 BEGIN
4647   d_position := 0;
4648 
4649   IF (PO_LOG.d_proc) THEN
4650     PO_LOG.proc_begin(d_module, 'p_line_type_tbl', p_line_type_tbl);
4651     PO_LOG.proc_begin(d_module, 'p_file_line_language_tbl', p_file_line_language_tbl);
4652     PO_LOG.proc_begin(d_module, 'x_line_type_id_tbl', x_line_type_id_tbl);
4653   END IF;
4654 
4655   -- bug 5489942: derivation is based on line level language
4656   -- derive line_type_id from line_type
4657   FORALL i IN 1..p_index_tbl.COUNT
4658     INSERT INTO po_session_gt(key, num1, num2)
4659     SELECT p_key,
4660            p_index_tbl(i),
4661            b.line_type_id
4662     FROM   po_line_types_b b,
4663            po_line_types_tl tl
4664     WHERE  p_line_type_tbl(i) IS NOT NULL
4665     AND    x_line_type_id_tbl(i) IS NULL
4666     AND    b.line_type_id = tl.line_type_id
4667     AND    tl.language = NVL(p_file_line_language_tbl(i),
4668                              userenv('LANG'))
4669     AND    SYSDATE < NVL(b.inactive_date, SYSDATE +1)
4670     AND    tl.line_type = p_line_type_tbl(i);
4671 
4672   d_position := 10;
4673 
4674   -- read result from temp table, and delete the records from temp table
4675   DELETE FROM po_session_gt
4676   WHERE  key = p_key
4677   RETURNING num1, num2 BULK COLLECT INTO l_index_tbl, l_result_tbl;
4678 
4679   d_position := 20;
4680 
4681   -- push the result back to x_line_type_ids
4682   FOR i IN 1..l_index_tbl.COUNT
4683   LOOP
4684     IF (PO_LOG.d_stmt) THEN
4685       PO_LOG.stmt(d_module, d_position, 'index', l_index_tbl(i));
4686       PO_LOG.stmt(d_module, d_position, 'new line type id', l_result_tbl(i));
4687     END IF;
4688 
4689     x_line_type_id_tbl(l_index_tbl(i)) := l_result_tbl(i);
4690   END LOOP;
4691 
4692   IF (PO_LOG.d_proc) THEN
4693     PO_LOG.proc_end(d_module);
4694   END IF;
4695 
4696 EXCEPTION
4697   WHEN OTHERS THEN
4698     PO_MESSAGE_S.add_exc_msg
4699     (
4700       p_pkg_name => d_pkg_name,
4701       p_procedure_name => d_api_name || '.' || d_position
4702     );
4703     RAISE;
4704 END derive_line_type_id;
4705 
4706 -----------------------------------------------------------------------
4707 --Start of Comments
4708 --Name: derive_un_number_id
4709 --Function: derive un_number_id from un_number
4710 --Parameters:
4711 --IN:
4712 --  p_key
4713 --    key used to identify rows in po_session_gt
4714 --  p_index_tbl
4715 --    table containging the indexes of all rows
4716 --  p_un_number_tbl
4717 --    list of un_numbers read within the batch
4718 --IN OUT:
4719 --  x_un_number_id_tbl
4720 --    list of un_number_ids read within the batch;
4721 --    derived result will be saved here as well;
4722 --    derivation will only occur when un_number
4723 --    is provided but un_number_id is not;
4724 --OUT:
4725 --End of Comments
4726 ------------------------------------------------------------------------
4727 PROCEDURE derive_un_number_id
4728 (
4729   p_key                  IN po_session_gt.key%TYPE,
4730   p_index_tbl            IN DBMS_SQL.NUMBER_TABLE,
4731   p_un_number_tbl        IN PO_TBL_VARCHAR30,
4732   x_un_number_id_tbl     IN OUT NOCOPY PO_TBL_NUMBER
4733 ) IS
4734 
4735   d_api_name CONSTANT VARCHAR2(30) := 'derive_un_number_id';
4736   d_module   CONSTANT VARCHAR2(255) := d_pkg_name || d_api_name || '.';
4737   d_position NUMBER;
4738 
4739   -- tables to store the derived result
4740   l_index_tbl        PO_TBL_NUMBER;
4741   l_result_tbl       PO_TBL_NUMBER;
4742 BEGIN
4743   d_position := 0;
4744 
4745   IF (PO_LOG.d_proc) THEN
4746     PO_LOG.proc_begin(d_module, 'p_un_number_tbl', p_un_number_tbl);
4747     PO_LOG.proc_begin(d_module, 'x_un_number_id_tbl', x_un_number_id_tbl);
4748   END IF;
4749 
4750   -- derive un_number_id from un_number
4751   FORALL i IN 1.. p_index_tbl.COUNT
4752     INSERT INTO po_session_gt(key, num1, num2)
4753     SELECT p_key,
4754            p_index_tbl(i),
4755            un_number_id
4756     FROM   po_un_numbers_vl
4757     WHERE  p_un_number_tbl(i) IS NOT NULL
4758     AND    x_un_number_id_tbl(i) IS NULL
4759     AND    sysdate < nvl(inactive_date, sysdate +1)
4760     AND    un_number = p_un_number_tbl(i);
4761 
4762   d_position := 10;
4763 
4764   -- read result from temp table, and delete the records from temp table
4765   DELETE FROM po_session_gt
4766   WHERE  key = p_key
4767   RETURNING num1, num2 BULK COLLECT INTO l_index_tbl, l_result_tbl;
4768 
4769   d_position := 20;
4770 
4771   -- push the result back to x_lines
4772   FOR i IN 1..l_index_tbl.COUNT
4773   LOOP
4774     IF (PO_LOG.d_stmt) THEN
4775       PO_LOG.stmt(d_module, d_position, 'index', l_index_tbl(i));
4776       PO_LOG.stmt(d_module, d_position, 'new un number id', l_result_tbl(i));
4777     END IF;
4778 
4779     x_un_number_id_tbl(l_index_tbl(i)) := l_result_tbl(i);
4780   END LOOP;
4781 
4782   IF (PO_LOG.d_proc) THEN
4783     PO_LOG.proc_end(d_module);
4784   END IF;
4785 
4786 EXCEPTION
4787   WHEN OTHERS THEN
4788     PO_MESSAGE_S.add_exc_msg
4789     (
4790       p_pkg_name => d_pkg_name,
4791       p_procedure_name => d_api_name || '.' || d_position
4792     );
4793     RAISE;
4794 END derive_un_number_id;
4795 
4796 -----------------------------------------------------------------------
4797 --Start of Comments
4798 --Name: derive_hazard_class_id
4799 --Function: derive hazard_class_id from hazard_class
4800 --Parameters:
4801 --IN:
4802 --  p_key
4803 --    key used to identify rows in po_session_gt
4804 --  p_index_tbl
4805 --    table containging the indexes of all rows
4806 --  p_hazard_class_tbl
4807 --    list of hazard_classes read within the batch
4808 --IN OUT:
4809 --  x_hazard_class_id_tbl
4810 --    list of hazard_class_ids read within the batch;
4811 --    derived result will be saved here as well;
4812 --    derivation will only occur when hazard_class
4813 --    is provided but hazard_class_id is not;
4814 --OUT:
4815 --End of Comments
4816 ------------------------------------------------------------------------
4817 PROCEDURE derive_hazard_class_id
4818 (
4819   p_key                  IN po_session_gt.key%TYPE,
4820   p_index_tbl            IN DBMS_SQL.NUMBER_TABLE,
4821   p_hazard_class_tbl     IN PO_TBL_VARCHAR100,
4822   x_hazard_class_id_tbl  IN OUT NOCOPY PO_TBL_NUMBER
4823 ) IS
4824 
4825   d_api_name CONSTANT VARCHAR2(30) := 'derive_hazard_class_id';
4826   d_module   CONSTANT VARCHAR2(255) := d_pkg_name || d_api_name || '.';
4827   d_position NUMBER;
4828 
4829   -- tables to store the derived result
4830   l_index_tbl        PO_TBL_NUMBER;
4831   l_result_tbl       PO_TBL_NUMBER;
4832 BEGIN
4833   d_position := 0;
4834 
4835   IF (PO_LOG.d_proc) THEN
4836     PO_LOG.proc_begin(d_module, 'p_hazard_class_tbl', p_hazard_class_tbl);
4837     PO_LOG.proc_begin(d_module, 'x_hazard_class_id_tbl', x_hazard_class_id_tbl);
4838   END IF;
4839 
4840   -- derive hazard_class_id from hazard_class
4841   FORALL i IN 1..p_index_tbl.COUNT
4842     INSERT INTO po_session_gt(key, num1, num2)
4843     SELECT p_key,
4844            p_index_tbl(i),
4845            hazard_class_id
4846     FROM   po_hazard_classes_val_v
4847     WHERE  p_hazard_class_tbl(i) IS NOT NULL
4848     AND    x_hazard_class_id_tbl(i) IS NULL
4849     AND    hazard_class = p_hazard_class_tbl(i);
4850 
4851   d_position := 10;
4852 
4853   -- read result from temp table, and delete the records from temp table
4854   DELETE FROM po_session_gt
4855   WHERE  key = p_key
4856   RETURNING num1, num2 BULK COLLECT INTO l_index_tbl, l_result_tbl;
4857 
4858   d_position := 20;
4859 
4860   -- push the result back to x_hazard_class_ids
4861   FOR i IN 1..l_index_tbl.COUNT
4862   LOOP
4863     IF (PO_LOG.d_stmt) THEN
4864       PO_LOG.stmt(d_module, d_position, 'index', l_index_tbl(i));
4865       PO_LOG.stmt(d_module, d_position, 'new hazard class id', l_result_tbl(i));
4866     END IF;
4867 
4868     x_hazard_class_id_tbl(l_index_tbl(i)) := l_result_tbl(i);
4869   END LOOP;
4870 
4871   IF (PO_LOG.d_proc) THEN
4872     PO_LOG.proc_end(d_module);
4873   END IF;
4874 
4875 EXCEPTION
4876   WHEN OTHERS THEN
4877     PO_MESSAGE_S.add_exc_msg
4878     (
4879       p_pkg_name => d_pkg_name,
4880       p_procedure_name => d_api_name || '.' || d_position
4881     );
4882     RAISE;
4883 END derive_hazard_class_id;
4884 
4885 -----------------------------------------------------------------------
4886 --Start of Comments
4887 --Name: derive_template_id
4888 --Function: derive template_id from template_name
4889 --Parameters:
4890 --IN:
4891 --  p_key
4892 --    key used to identify rows in po_session_gt
4893 --  p_index_tbl
4894 --    table containging the indexes of all rows
4895 --  p_template_name_tbl
4896 --    list of template_names read within the batch
4897 --IN OUT:
4898 --  x_template_id_tbl
4899 --    list of template_ids read within the batch;
4900 --    derived result will be saved here as well;
4901 --    derivation will only occur when template_name
4902 --    is provided but template_id is not;
4903 --OUT:
4904 --End of Comments
4905 ------------------------------------------------------------------------
4906 PROCEDURE derive_template_id
4907 (
4908   p_key                  IN po_session_gt.key%TYPE,
4909   p_index_tbl            IN DBMS_SQL.NUMBER_TABLE,
4910   p_template_name_tbl    IN PO_TBL_VARCHAR30,
4911   x_template_id_tbl      IN OUT NOCOPY PO_TBL_NUMBER
4912 ) IS
4913 
4914   d_api_name CONSTANT VARCHAR2(30) := 'derive_template_id';
4915   d_module   CONSTANT VARCHAR2(255) := d_pkg_name || d_api_name || '.';
4916   d_position NUMBER;
4917 
4918   -- tables to store the derived result
4919   l_index_tbl        PO_TBL_NUMBER;
4920   l_result_tbl       PO_TBL_NUMBER;
4921 BEGIN
4922   d_position := 0;
4923 
4924   IF (PO_LOG.d_proc) THEN
4925     PO_LOG.proc_begin(d_module, 'p_template_name_tbl', p_template_name_tbl);
4926     PO_LOG.proc_begin(d_module, 'x_template_id_tbl', x_template_id_tbl);
4927   END IF;
4928 
4929   -- derive template_id from template_name
4930   FORALL i IN 1..p_index_tbl.COUNT
4931     INSERT INTO po_session_gt(key, num1, num2)
4932     SELECT p_key,
4933            p_index_tbl(i),
4934            template_id
4935     FROM   mtl_item_templates
4936     WHERE  p_template_name_tbl(i) IS NOT NULL
4937     AND    x_template_id_tbl(i) IS NULL
4938     AND    template_name = p_template_name_tbl(i)
4939     AND    NVL(context_organization_id,
4940            PO_PDOI_PARAMS.g_sys.def_inv_org_id) =
4941            PO_PDOI_PARAMS.g_sys.def_inv_org_id;
4942 
4943   d_position := 10;
4944 
4945   -- read result from temp table, and delete the records from temp table
4946   DELETE FROM po_session_gt
4947   WHERE  key = p_key
4948   RETURNING num1, num2 BULK COLLECT INTO l_index_tbl, l_result_tbl;
4949 
4950   d_position := 20;
4951 
4952   -- push the result back to x_lines
4953   FOR i IN 1..l_index_tbl.COUNT
4954   LOOP
4955     IF (PO_LOG.d_stmt) THEN
4956       PO_LOG.stmt(d_module, d_position, 'index', l_index_tbl(i));
4957       PO_LOG.stmt(d_module, d_position, 'new template id', l_result_tbl(i));
4958     END IF;
4959 
4960     x_template_id_tbl(l_index_tbl(i)) := l_result_tbl(i);
4961   END LOOP;
4962 
4963   IF (PO_LOG.d_proc) THEN
4964     PO_LOG.proc_end(d_module);
4965   END IF;
4966 
4967 EXCEPTION
4968   WHEN OTHERS THEN
4969     PO_MESSAGE_S.add_exc_msg
4970     (
4971       p_pkg_name => d_pkg_name,
4972       p_procedure_name => d_api_name || '.' || d_position
4973     );
4974     RAISE;
4975 END derive_template_id;
4976 -----------------------------------------------------------------------
4977 --Start of Comments
4978 --Name: default_info_from_line_type
4979 --Function:
4980 --  default information from line types;
4981 --  the information can be defaulted from line type include:
4982 --  1. order_type_lookup_code
4983 --  2. purchase_basis
4984 --  3. matching_basis
4985 --  4. category_id
4986 --  5. unit_of_measure
4987 --  6. unit_price
4988 --Parameters:
4989 --IN:
4990 --  p_key
4991 --    key used to identify rows in po_session_gt
4992 --  p_index_tbl
4993 --    table containging the indexes of all rows
4994 --  p_line_type_id_tbl
4995 --    list of line_type_ids read within the batch
4996 --IN OUT:
4997 --  x_order_type_lookup_code_tbl
4998 --    list of default values from line_type_ids
4999 --  x_purchase_basis_tbl
5000 --    list of default values from line_type_ids
5001 --  x_matching_basis_tbl
5002 --    list of default values from line_type_ids
5003 --OUT:
5004 --  x_category_id_tbl
5005 --    list of default values from line_type_ids
5006 --  x_unit_of_measure_tbl
5007 --    list of default values from line_type_ids
5008 --  x_unit_price_tbl
5009 --    list of default values from line_type_ids
5010 --End of Comments
5011 ------------------------------------------------------------------------
5012 PROCEDURE default_info_from_line_type
5013 (
5014   p_key                        IN po_session_gt.key%TYPE,
5015   p_index_tbl                  IN DBMS_SQL.NUMBER_TABLE,
5016   p_line_type_id_tbl           IN PO_TBL_NUMBER,
5017   x_order_type_lookup_code_tbl IN OUT NOCOPY PO_TBL_VARCHAR30,
5018   x_purchase_basis_tbl         IN OUT NOCOPY PO_TBL_VARCHAR30,
5019   x_matching_basis_tbl         IN OUT NOCOPY PO_TBL_VARCHAR30,
5020   x_category_id_tbl            OUT NOCOPY PO_TBL_NUMBER,
5021   x_unit_of_measure_tbl        OUT NOCOPY PO_TBL_VARCHAR30,
5022   x_unit_price_tbl             OUT NOCOPY PO_TBL_NUMBER
5023 ) IS
5024 
5025   d_api_name CONSTANT VARCHAR2(30) := 'default_info_from_line_type';
5026   d_module   CONSTANT VARCHAR2(255) := d_pkg_name || d_api_name || '.';
5027   d_position NUMBER;
5028 
5029   -- variables to hold result read from temp table
5030   l_index_tbl                  PO_TBL_NUMBER;
5031   l_order_type_lookup_code_tbl PO_TBL_VARCHAR30;
5032   l_purchase_basis_tbl         PO_TBL_VARCHAR30;
5033   l_matching_basis_tbl         PO_TBL_VARCHAR30;
5034   l_category_id_tbl            PO_TBL_NUMBER;
5035   l_unit_of_measure_tbl        PO_TBL_VARCHAR30;
5036   l_unit_price_tbl             PO_TBL_NUMBER;
5037 
5038   -- current accessing index in the loop
5039   l_index                      NUMBER;
5040 BEGIN
5041   d_position := 0;
5042 
5043   IF (PO_LOG.d_proc) THEN
5044     PO_LOG.proc_begin(d_module);
5045   END IF;
5046 
5047   x_category_id_tbl     := PO_TBL_NUMBER();
5048   x_unit_of_measure_tbl := PO_TBL_VARCHAR30();
5049   x_unit_price_tbl      := PO_TBL_NUMBER();
5050 
5051   x_category_id_tbl.EXTEND(p_index_tbl.COUNT);
5052   x_unit_of_measure_tbl.EXTEND(p_index_tbl.COUNT);
5053   x_unit_price_tbl.EXTEND(p_index_tbl.COUNT);
5054 
5055   -- retrieve the values based on line type id
5056   FORALL i IN 1..p_index_tbl.COUNT
5057     INSERT INTO po_session_gt(key, num1, char1, char2, char3, num2, char4, num3)
5058     SELECT p_key,
5059            p_index_tbl(i),
5060            order_type_lookup_code,
5061            purchase_basis,
5062            matching_basis,
5063            category_id,
5064            unit_of_measure,
5065            unit_price
5066     FROM   po_line_types_b
5067     WHERE  line_type_id = p_line_type_id_tbl(i);
5068 
5069   d_position := 10;
5070 
5071   -- read result from temp table and delete the records at the same time
5072   DELETE FROM po_session_gt
5073   WHERE  key = p_key
5074   RETURNING num1, char1, char2, char3, num2, char4, num3
5075   BULK COLLECT INTO
5076     l_index_tbl,
5077     l_order_type_lookup_code_tbl,
5078     l_purchase_basis_tbl,
5079     l_matching_basis_tbl,
5080     l_category_id_tbl,
5081     l_unit_of_measure_tbl,
5082     l_unit_price_tbl;
5083 
5084   d_position := 20;
5085 
5086   -- set the result in OUT parameters
5087   FOR i IN 1..l_index_tbl.COUNT
5088   LOOP
5089     l_index := l_index_tbl(i);
5090 
5091     IF (PO_LOG.d_stmt) THEN
5092       PO_LOG.stmt(d_module, d_position, 'index', l_index);
5093       PO_LOG.stmt(d_module, d_position, 'new order type',
5094                   l_order_type_lookup_code_tbl(i));
5095       PO_LOG.stmt(d_module, d_position, 'new purchase basis',
5096                   l_purchase_basis_tbl(i));
5097       PO_LOG.stmt(d_module, d_position, 'new matching basis',
5098                   l_matching_basis_tbl(i));
5099       PO_LOG.stmt(d_module, d_position, 'new category id',
5100                   l_category_id_tbl(i));
5101       PO_LOG.stmt(d_module, d_position, 'new unit of measure',
5102                   l_unit_of_measure_tbl(i));
5103       PO_LOG.stmt(d_module, d_position, 'new unit price',
5104                   l_unit_price_tbl(i));
5105     END IF;
5106 
5107     x_order_type_lookup_code_tbl(l_index) := l_order_type_lookup_code_tbl(i);
5108     x_purchase_basis_tbl(l_index) := l_purchase_basis_tbl(i);
5109     x_matching_basis_tbl(l_index) := l_matching_basis_tbl(i);
5110     x_category_id_tbl(l_index) := l_category_id_tbl(i);
5111     x_unit_of_measure_tbl(l_index) := l_unit_of_measure_tbl(i);
5112     x_unit_price_tbl(l_index) := l_unit_price_tbl(i);
5113   END LOOP;
5114 
5115   IF (PO_LOG.d_proc) THEN
5116     PO_LOG.proc_end(d_module);
5117   END IF;
5118 
5119 EXCEPTION
5120   WHEN OTHERS THEN
5121     PO_MESSAGE_S.add_exc_msg
5122     (
5123       p_pkg_name => d_pkg_name,
5124       p_procedure_name => d_api_name || '.' || d_position
5125     );
5126     RAISE;
5127 END default_info_from_line_type;
5128 
5129 -----------------------------------------------------------------------
5130 --Start of Comments
5131 --Name: default_info_from_item
5132 --Function:
5133 --  default information from item;
5134 --  the information can be defaulted from item include:
5135 --  1. item_description
5136 --  2. unit_of_measure
5137 --  3. unit_price
5138 --  4. category_id
5139 --  5. un_number_id
5140 --  6. hazard_class_id
5141 --  7. market_price
5142 --  8. secondary_unit_of_measure
5143 --Parameters:
5144 --IN:
5145 --  p_key
5146 --    key used to identify rows in po_session_gt
5147 --  p_index_tbl
5148 --    table containging the indexes of all rows
5149 --  p_item_id_tbl
5150 --    list of item_ids read within the batch
5151 --IN OUT:
5152 --OUT:
5153 --  x_item_desc_tbl
5154 --    list of default values from item_desc
5155 --  x_unit_of_measure_tbl
5156 --    list of default values from unit_of_measure
5157 --  x_unit_price_tbl
5158 --    list of default values from unit_price
5159 --  x_category_id_tbl
5160 --    list of default values from category_id
5161 --  x_un_number_id_tbl
5162 --    list of default values from un_number_id
5163 --  x_hazard_class_id_tbl
5164 --    list of default values from hazard_class_id
5165 --  x_market_price_tbl
5166 --    list of default values from market_price
5167 --  x_secondary_unit_of_meas_tbl
5168 --    list of default values from secondary_unit_of_measure
5169 --End of Comments
5170 ------------------------------------------------------------------------
5171 PROCEDURE default_info_from_item
5172 (
5173   p_key                        IN po_session_gt.key%TYPE,
5174   p_index_tbl                  IN DBMS_SQL.NUMBER_TABLE,
5175   p_item_id_tbl                IN PO_TBL_NUMBER,
5176   x_item_desc_tbl              OUT NOCOPY PO_TBL_VARCHAR2000,
5177   x_unit_of_measure_tbl        OUT NOCOPY PO_TBL_VARCHAR30,
5178   x_unit_price_tbl             OUT NOCOPY PO_TBL_NUMBER,
5179   x_category_id_tbl            OUT NOCOPY PO_TBL_NUMBER,
5180   x_un_number_id_tbl           OUT NOCOPY PO_TBL_NUMBER,
5181   x_hazard_class_id_tbl        OUT NOCOPY PO_TBL_NUMBER,
5182   x_market_price_tbl           OUT NOCOPY PO_TBL_NUMBER,
5183   x_secondary_unit_of_meas_tbl OUT NOCOPY PO_TBL_VARCHAR30
5184 ) IS
5185 
5186   d_api_name CONSTANT VARCHAR2(30) := 'default_info_from_item';
5187   d_module   CONSTANT VARCHAR2(255) := d_pkg_name || d_api_name || '.';
5188   d_position NUMBER;
5189 
5190   -- variables to hold result read from temp table
5191   l_index_tbl                  PO_TBL_NUMBER;
5192   l_item_desc_tbl              PO_TBL_VARCHAR2000;
5193   l_unit_of_measure_tbl        PO_TBL_VARCHAR30;
5194   l_unit_price_tbl             PO_TBL_NUMBER;
5195   l_category_id_tbl            PO_TBL_NUMBER;
5196   l_un_number_id_tbl           PO_TBL_NUMBER;
5197   l_hazard_class_id_tbl        PO_TBL_NUMBER;
5198   l_market_price_tbl           PO_TBL_NUMBER;
5199   l_secondary_unit_of_meas_tbl PO_TBL_VARCHAR30;
5200 
5201   -- current accessing index in the loop
5202   l_index                      NUMBER;
5203 BEGIN
5204   d_position := 0;
5205 
5206   IF (PO_LOG.d_proc) THEN
5207     PO_LOG.proc_begin(d_module);
5208   END IF;
5209 
5210   x_item_desc_tbl              := PO_TBL_VARCHAR2000();
5211   x_unit_of_measure_tbl        := PO_TBL_VARCHAR30();
5212   x_unit_price_tbl             := PO_TBL_NUMBER();
5213   x_category_id_tbl            := PO_TBL_NUMBER();
5214   x_un_number_id_tbl           := PO_TBL_NUMBER();
5215   x_hazard_class_id_tbl        := PO_TBL_NUMBER();
5216   x_market_price_tbl           := PO_TBL_NUMBER();
5217   x_secondary_unit_of_meas_tbl := PO_TBL_VARCHAR30();
5218 
5219   x_item_desc_tbl.EXTEND(p_index_tbl.COUNT);
5220   x_unit_of_measure_tbl.EXTEND(p_index_tbl.COUNT);
5221   x_unit_price_tbl.EXTEND(p_index_tbl.COUNT);
5222   x_category_id_tbl.EXTEND(p_index_tbl.COUNT);
5223   x_un_number_id_tbl.EXTEND(p_index_tbl.COUNT);
5224   x_hazard_class_id_tbl.EXTEND(p_index_tbl.COUNT);
5225   x_market_price_tbl.EXTEND(p_index_tbl.COUNT);
5226   x_secondary_unit_of_meas_tbl.EXTEND(p_index_tbl.COUNT);
5227 
5228   -- retrieve the values based on item id and default inv org id
5229   -- bug 4723323: get secondary_unit_of_measure value for dual-um
5230   --              control item, used in default logic
5231   FORALL i IN 1..p_index_tbl.COUNT
5232     INSERT INTO po_session_gt(key, num1, char1, char2, num2, num3,
5233                               num4, num5, num6, char3)
5234     SELECT p_key,
5235            p_index_tbl(i),
5236            item_tl.description,
5237            item.primary_unit_of_measure,
5238            item.list_price_per_unit,
5239            item_cat.category_id,
5240            item.un_number_id,
5241            item.hazard_class_id,
5242            item.market_price,
5243            decode(item.tracking_quantity_ind, 'PS', uom.unit_of_measure, NULL)
5244     FROM   mtl_item_categories item_cat,
5245            mtl_system_items item,
5246            mtl_system_items_tl item_tl,
5247            mtl_units_of_measure uom
5248     WHERE  item.inventory_item_id = p_item_id_tbl(i)
5249     AND    item_tl.inventory_item_id = item.inventory_item_id
5250     AND    item_cat.inventory_item_id = item.inventory_item_id
5251     AND    item.organization_id = PO_PDOI_PARAMS.g_sys.def_inv_org_id
5252     AND    item_tl.language = USERENV('LANG')
5253     AND    item_tl.organization_id = PO_PDOI_PARAMS.g_sys.def_inv_org_id
5254     AND    item_cat.category_set_id = PO_PDOI_PARAMS.g_sys.def_cat_set_id
5255     AND    item_cat.organization_id = PO_PDOI_PARAMS.g_sys.def_inv_org_id
5256     AND    item.secondary_uom_code = uom.uom_code(+);
5257 
5258   d_position := 10;
5259 
5260   -- read result from temp table and delete the records at the same time
5261   DELETE FROM po_session_gt
5262   WHERE  key = p_key
5263   RETURNING num1, char1, char2, num2, num3, num4, num5, num6, char3
5264   BULK COLLECT INTO
5265     l_index_tbl,
5266     l_item_desc_tbl,
5267     l_unit_of_measure_tbl,
5268     l_unit_price_tbl,
5269     l_category_id_tbl,
5270     l_un_number_id_tbl,
5271     l_hazard_class_id_tbl,
5272     l_market_price_tbl,
5273     l_secondary_unit_of_meas_tbl;
5274 
5275   d_position := 20;
5276 
5277   -- set the result in OUT parameters
5278   FOR i IN 1..l_index_tbl.COUNT
5279   LOOP
5280     l_index := l_index_tbl(i);
5281 
5282     IF (PO_LOG.d_stmt) THEN
5283       PO_LOG.stmt(d_module, d_position, 'index', l_index_tbl(i));
5284       PO_LOG.stmt(d_module, d_position, 'new item desc',
5285                   l_item_desc_tbl(i));
5286       PO_LOG.stmt(d_module, d_position, 'new unit of measure',
5287                   l_unit_of_measure_tbl(i));
5288       PO_LOG.stmt(d_module, d_position, 'new unit price',
5289                   l_unit_price_tbl(i));
5290       PO_LOG.stmt(d_module, d_position, 'new category id',
5291                   l_category_id_tbl(i));
5292       PO_LOG.stmt(d_module, d_position, 'new un number id',
5293                   l_un_number_id_tbl(i));
5294       PO_LOG.stmt(d_module, d_position, 'new hazard class id',
5295                   l_hazard_class_id_tbl(i));
5296       PO_LOG.stmt(d_module, d_position, 'new market price',
5297                   l_market_price_tbl(i));
5298       PO_LOG.stmt(d_module, d_position, 'new secondary unit of measure',
5299                   l_secondary_unit_of_meas_tbl(i));
5300     END IF;
5301 
5302     x_item_desc_tbl(l_index) := l_item_desc_tbl(i);
5303     x_unit_of_measure_tbl(l_index) := l_unit_of_measure_tbl(i);
5304     x_unit_price_tbl(l_index) := l_unit_price_tbl(i);
5305     x_category_id_tbl(l_index) := l_category_id_tbl(i);
5306     x_un_number_id_tbl(l_index) := l_un_number_id_tbl(i);
5307     x_hazard_class_id_tbl(l_index) := l_hazard_class_id_tbl(i);
5308     x_market_price_tbl(l_index) := l_market_price_tbl(i);
5309     x_secondary_unit_of_meas_tbl(l_index) := l_secondary_unit_of_meas_tbl(i);
5310   END LOOP;
5311 
5312   IF (PO_LOG.d_proc) THEN
5313     PO_LOG.proc_end(d_module);
5314   END IF;
5315 
5316 EXCEPTION
5317   WHEN OTHERS THEN
5318     PO_MESSAGE_S.add_exc_msg
5319     (
5320       p_pkg_name => d_pkg_name,
5321       p_procedure_name => d_api_name || '.' || d_position
5322     );
5323     RAISE;
5324 END default_info_from_item;
5325 
5326 -----------------------------------------------------------------------
5327 --Start of Comments
5328 --Name: default_info_from_job
5329 --Function:
5330 --  default information from job;
5331 --  the information can be defaulted from job include:
5332 --  1. item_description
5333 --  2. category_id
5334 --Parameters:
5335 --IN:
5336 --  p_key
5337 --    key used to identify rows in po_session_gt
5338 --  p_index_tbl
5339 --    table containging the indexes of all rows
5340 --  p_job_id_tbl
5341 --    list of job_ids read within the batch
5342 --IN OUT:
5343 --OUT:
5344 --  x_item_desc_tbl
5345 --    list of default values from job_ids
5346 --  x_category_id_tbl
5347 --    list of default values from job_ids
5348 --End of Comments
5349 ------------------------------------------------------------------------
5350 PROCEDURE default_info_from_job
5351 (
5352   p_key                        IN po_session_gt.key%TYPE,
5353   p_index_tbl                  IN DBMS_SQL.NUMBER_TABLE,
5354   p_job_id_tbl                 IN PO_TBL_NUMBER,
5355   x_item_desc_tbl              OUT NOCOPY PO_TBL_VARCHAR2000,
5356   x_category_id_tbl            OUT NOCOPY PO_TBL_NUMBER
5357 ) IS
5358 
5359   d_api_name CONSTANT VARCHAR2(30) := 'default_info_from_job';
5360   d_module   CONSTANT VARCHAR2(255) := d_pkg_name || d_api_name || '.';
5361   d_position NUMBER;
5362 
5363   l_index                      NUMBER;
5364 
5365   -- variables to hold result read from temp table
5366   l_index_tbl                  PO_TBL_NUMBER;
5367   l_item_desc_tbl              PO_TBL_VARCHAR2000;
5368   l_category_id_tbl            PO_TBL_NUMBER;
5369 BEGIN
5370   d_position := 0;
5371 
5372   IF (PO_LOG.d_proc) THEN
5373     PO_LOG.proc_begin(d_module);
5374   END IF;
5375 
5376   x_item_desc_tbl              := PO_TBL_VARCHAR2000();
5377   x_category_id_tbl            := PO_TBL_NUMBER();
5378 
5379   x_item_desc_tbl.EXTEND(p_index_tbl.COUNT);
5380   x_category_id_tbl.EXTEND(p_index_tbl.COUNT);
5381 
5382   -- retrieve the values based on line type id
5383   FORALL i IN 1..p_index_tbl.COUNT
5384     INSERT INTO po_session_gt(key, num1, char1, num2)
5385     SELECT p_key,
5386            p_index_tbl(i),
5387            association.job_description,
5388            association.category_id
5389     FROM   po_job_associations association,
5390            per_jobs_vl job
5391     WHERE  job.job_id = p_job_id_tbl(i)
5392     AND    association.job_id = job.job_id
5393     AND    TRUNC(sysdate) < TRUNC(NVL(association.inactive_date, sysdate+1))
5394     AND    TRUNC(sysdate) BETWEEN TRUNC(NVL(job.date_from, sysdate))
5395            AND TRUNC(NVL(job.date_to, sysdate+1));
5396 
5397   d_position := 10;
5398 
5399   -- read result from temp table and delete the records at the same time
5400   DELETE FROM po_session_gt
5401   WHERE  key = p_key
5402   RETURNING num1, char1, num2
5403   BULK COLLECT INTO
5404     l_index_tbl,
5405     l_item_desc_tbl,
5406     l_category_id_tbl;
5407 
5408   d_position := 20;
5409 
5410   -- set the result in OUT parameters
5411   FOR i IN 1..l_index_tbl.COUNT
5412   LOOP
5413     l_index := l_index_tbl(i);
5414 
5415     IF (PO_LOG.d_stmt) THEN
5416       PO_LOG.stmt(d_module, d_position, 'index', l_index_tbl(i));
5417       PO_LOG.stmt(d_module, d_position, 'new item desc', l_item_desc_tbl(i));
5418       PO_LOG.stmt(d_module, d_position, 'new category id', l_category_id_tbl(i));
5419     END IF;
5420 
5421     x_item_desc_tbl(l_index) := l_item_desc_tbl(i);
5422     x_category_id_tbl(l_index) := l_category_id_tbl(i);
5423   END LOOP;
5424 
5425   IF (PO_LOG.d_proc) THEN
5426     PO_LOG.proc_end(d_module);
5427   END IF;
5428 
5429 EXCEPTION
5430   WHEN OTHERS THEN
5431     PO_MESSAGE_S.add_exc_msg
5432     (
5433       p_pkg_name => d_pkg_name,
5434       p_procedure_name => d_api_name || '.' || d_position
5435     );
5436     RAISE;
5437 END default_info_from_job;
5438 
5439 -----------------------------------------------------------------------
5440 --Start of Comments
5441 --Name: default_po_cat_id_from_ip
5442 --Function: default po category_id from ip_category_id
5443 --Parameters:
5444 --IN:
5445 --  p_key
5446 --    key used to identify rows in po_session_gt
5447 --  p_index_tbl
5448 --    table containging the indexes of all rows
5449 --  p_ip_category_id_tbl
5450 --    list of ip_category_ids read within the batch
5451 --IN OUT:
5452 --  x_po_category_id_tbl
5453 --    list of po_category_ids defaulted from ip_category_ids
5454 --OUT:
5455 --End of Comments
5456 ------------------------------------------------------------------------
5457 PROCEDURE default_po_cat_id_from_ip
5458 (
5459   p_key                        IN po_session_gt.key%TYPE,
5460   p_index_tbl                  IN DBMS_SQL.NUMBER_TABLE,
5461   p_ip_category_id_tbl         IN PO_TBL_NUMBER,
5462   x_po_category_id_tbl         IN OUT NOCOPY PO_TBL_NUMBER
5463 ) IS
5464 
5465   d_api_name CONSTANT VARCHAR2(30) := 'default_po_cat_id_from_ip';
5466   d_module   CONSTANT VARCHAR2(255) := d_pkg_name || d_api_name || '.';
5467   d_position NUMBER;
5468 
5469   -- variables to hold result read from temp table
5470   l_index_tbl                  PO_TBL_NUMBER;
5471   l_result_tbl                 PO_TBL_NUMBER;
5472 BEGIN
5473   d_position := 0;
5474 
5475   IF (PO_LOG.d_proc) THEN
5476     PO_LOG.proc_begin(d_module, 'p_ip_category_id_tbl', p_ip_category_id_tbl);
5477     PO_LOG.proc_begin(d_module, 'x_po_category_id_tbl',
5478                       x_po_category_id_tbl);
5479   END IF;
5480 
5481   -- retrieve the values based on ip category id
5482   FORALL i IN 1..p_index_tbl.COUNT
5483     INSERT INTO po_session_gt(key, num1, num2)
5484     SELECT p_key,
5485            p_index_tbl(i),
5486            po_category_id
5487     FROM   icx_cat_shopping_cat_map_v
5488     WHERE  p_ip_category_id_tbl(i) IS NOT NULL
5489     AND    x_po_category_id_tbl(i) IS NULL
5490     AND    shopping_category_id = p_ip_category_id_tbl(i);
5491 
5492   d_position := 10;
5493 
5494   -- read result from temp table and delete the records at the same time
5495   DELETE FROM po_session_gt
5496   WHERE  key = p_key
5497   RETURNING num1, num2
5498   BULK COLLECT INTO l_index_tbl, l_result_tbl;
5499 
5500   d_position := 20;
5501 
5502   -- set the result in OUT parameters
5503   FOR i IN 1..l_index_tbl.COUNT
5504   LOOP
5505     IF (PO_LOG.d_stmt) THEN
5506       PO_LOG.stmt(d_module, d_position, 'index', l_index_tbl(i));
5507       PO_LOG.stmt(d_module, d_position, 'new po category id', l_result_tbl(i));
5508     END IF;
5509 
5510     x_po_category_id_tbl(l_index_tbl(i)) := l_result_tbl(i);
5511   END LOOP;
5512 
5513   IF (PO_LOG.d_proc) THEN
5514     PO_LOG.proc_end(d_module);
5515   END IF;
5516 
5517 EXCEPTION
5518   WHEN OTHERS THEN
5519     PO_MESSAGE_S.add_exc_msg
5520     (
5521       p_pkg_name => d_pkg_name,
5522       p_procedure_name => d_api_name || '.' || d_position
5523     );
5524     RAISE;
5525 END default_po_cat_id_from_ip;
5526 
5527 -----------------------------------------------------------------------
5528 --Start of Comments
5529 --Name: default_ip_cat_id_from_po
5530 --Function: default ip_category_id from po category_id
5531 --Parameters:
5532 --IN:
5533 --  p_key
5534 --    key used to identify rows in po_session_gt
5535 --  p_index_tbl
5536 --    table containging the indexes of all rows
5537 --  p_po_category_id_tbl
5538 --    list of po_category_ids read within the batch
5539 --IN OUT:
5540 --  x_ip_category_id_tbl
5541 --    list of ip_category_ids defaulted from po_category_ids
5542 --OUT:
5543 --End of Comments
5544 ------------------------------------------------------------------------
5545 PROCEDURE default_ip_cat_id_from_po
5546 (
5547   p_key                        IN po_session_gt.key%TYPE,
5548   p_index_tbl                  IN DBMS_SQL.NUMBER_TABLE,
5549   p_po_category_id_tbl         IN PO_TBL_NUMBER,
5550   x_ip_category_id_tbl         IN OUT NOCOPY PO_TBL_NUMBER
5551 ) IS
5552 
5553   d_api_name CONSTANT VARCHAR2(30) := 'default_ip_cat_id_from_po';
5554   d_module   CONSTANT VARCHAR2(255) := d_pkg_name || d_api_name || '.';
5555   d_position NUMBER;
5556 
5557   -- variables to hold result read from temp table
5558   l_index_tbl                  PO_TBL_NUMBER;
5559   l_result_tbl                 PO_TBL_NUMBER;
5560 BEGIN
5561   d_position := 0;
5562 
5563   IF (PO_LOG.d_proc) THEN
5564     PO_LOG.proc_begin(d_module, 'p_po_category_id_tbl', p_po_category_id_tbl);
5565     PO_LOG.proc_begin(d_module, 'x_ip_category_id_tbl',
5566                       x_ip_category_id_tbl);
5567   END IF;
5568 
5569   -- retrieve the values based on po category id
5570   FORALL i IN 1..p_index_tbl.COUNT
5571     INSERT INTO po_session_gt(key, num1, num2)
5572     SELECT p_key,
5573            p_index_tbl(i),
5574            shopping_category_id
5575     FROM   icx_cat_purchasing_cat_map_v
5576     WHERE  p_po_category_id_tbl(i) IS NOT NULL
5577     AND    x_ip_category_id_tbl(i) IS NULL
5578     AND    po_category_id = p_po_category_id_tbl(i);
5579 
5580   d_position := 10;
5581 
5582   -- read result from temp table and delete the records at the same time
5583   DELETE FROM po_session_gt
5584   WHERE  key = p_key
5585   RETURNING num1, num2
5586   BULK COLLECT INTO l_index_tbl, l_result_tbl;
5587 
5588   d_position := 20;
5589 
5590   -- set the result in OUT parameters
5591   FOR i IN 1..l_index_tbl.COUNT
5592   LOOP
5593     IF (PO_LOG.d_stmt) THEN
5594       PO_LOG.stmt(d_module, d_position, 'index', l_index_tbl(i));
5595       PO_LOG.stmt(d_module, d_position, 'new ip category id', l_result_tbl(i));
5596     END IF;
5597 
5598     x_ip_category_id_tbl(l_index_tbl(i)) := l_result_tbl(i);
5599   END LOOP;
5600 
5601   IF (PO_LOG.d_proc) THEN
5602     PO_LOG.proc_end(d_module);
5603   END IF;
5604 
5605 EXCEPTION
5606   WHEN OTHERS THEN
5607     PO_MESSAGE_S.add_exc_msg
5608     (
5609       p_pkg_name => d_pkg_name,
5610       p_procedure_name => d_api_name || '.' || d_position
5611     );
5612     RAISE;
5613 END default_ip_cat_id_from_po;
5614 
5615 -----------------------------------------------------------------------
5616 --Start of Comments
5617 --Name: default_hc_id_from_un_number
5618 --Function: default hazard_class_id from un_number
5619 --Parameters:
5620 --IN:
5621 --  p_key
5622 --    key used to identify rows in po_session_gt
5623 --  p_index_tbl
5624 --    table containging the indexes of all rows
5625 --  p_un_number_tbl
5626 --    list of un_numbers read within the batch
5627 --IN OUT:
5628 --  x_hazard_class_id_tbl
5629 --    list of hazard_class_ids defaulted from un_numbers
5630 --OUT:
5631 --End of Comments
5632 ------------------------------------------------------------------------
5633 PROCEDURE default_hc_id_from_un_number
5634 (
5635   p_key                        IN po_session_gt.key%TYPE,
5636   p_index_tbl                  IN DBMS_SQL.NUMBER_TABLE,
5637   p_un_number_tbl              IN PO_TBL_VARCHAR30,
5638   x_hazard_class_id_tbl        IN OUT NOCOPY PO_TBL_NUMBER
5639 ) IS
5640 
5641   d_api_name CONSTANT VARCHAR2(30) := 'default_hc_id_from_un_number';
5642   d_module   CONSTANT VARCHAR2(255) := d_pkg_name || d_api_name || '.';
5643   d_position NUMBER;
5644 
5645   -- variables to hold result read from temp table
5646   l_index_tbl                  PO_TBL_NUMBER;
5647   l_result_tbl                 PO_TBL_NUMBER;
5648 BEGIN
5649   d_position := 0;
5650 
5651   IF (PO_LOG.d_proc) THEN
5652     PO_LOG.proc_begin(d_module, 'p_un_number_tbl', p_un_number_tbl);
5653     PO_LOG.proc_begin(d_module, 'x_hazard_class_id_tbl',
5654                       x_hazard_class_id_tbl);
5655   END IF;
5656 
5657   -- retrieve the values based on line type id
5658   FORALL i IN 1..p_index_tbl.COUNT
5659     INSERT INTO po_session_gt(key, num1, num2)
5660     SELECT p_key,
5661            p_index_tbl(i),
5662            hazard_class_id
5663     FROM   po_un_numbers_vl
5664     WHERE  p_un_number_tbl(i) IS NOT NULL
5665     AND    x_hazard_class_id_tbl(i) IS NULL
5666     AND    sysdate < nvl(inactive_date, sysdate +1)
5667     AND    un_number = p_un_number_tbl(i);
5668 
5669   d_position := 10;
5670 
5671   -- read result from temp table and delete the records at the same time
5672   DELETE FROM po_session_gt
5673   WHERE  key = p_key
5674   RETURNING num1, num2
5675   BULK COLLECT INTO l_index_tbl, l_result_tbl;
5676 
5677   d_position := 20;
5678 
5679   -- set the result in OUT parameters
5680   FOR i IN 1..l_index_tbl.COUNT
5681   LOOP
5682     IF (PO_LOG.d_stmt) THEN
5683       PO_LOG.stmt(d_module, d_position, 'index', l_index_tbl(i));
5684       PO_LOG.stmt(d_module, d_position, 'new hazard class id', l_result_tbl(i));
5685     END IF;
5686 
5687     x_hazard_class_id_tbl(l_index_tbl(i)) := l_result_tbl(i);
5688   END LOOP;
5689 
5690   IF (PO_LOG.d_proc) THEN
5691     PO_LOG.proc_end(d_module);
5692   END IF;
5693 
5694 EXCEPTION
5695   WHEN OTHERS THEN
5696     PO_MESSAGE_S.add_exc_msg
5697     (
5698       p_pkg_name => d_pkg_name,
5699       p_procedure_name => d_api_name || '.' || d_position
5700     );
5701     RAISE;
5702 END default_hc_id_from_un_number;
5703 
5704 -----------------------------------------------------------------------
5705 --Start of Comments
5706 --Name: match_lines_on_line_num
5707 --Function:
5708 --  If header action is 'ORIGINAL', 'REPLACE' or
5709 --  'UPDATE SPO', this procedure will be called
5710 --  to group the po lines and po line locations.
5711 --  The first criteria used is line_num
5712 --Parameters:
5713 --IN:
5714 --  p_index_tbl
5715 --    table containging the indexes of all rows
5716 --IN OUT:
5717 --  x_lines
5718 --    record containing line info within the batch
5719 --OUT:
5720 --End of Comments
5721 ------------------------------------------------------------------------
5722 PROCEDURE match_lines_on_line_num
5723 (
5724   p_index_tbl     DBMS_SQL.NUMBER_TABLE,
5725   x_lines         IN OUT NOCOPY PO_PDOI_TYPES.lines_rec_type
5726 ) IS
5727 
5728   d_api_name CONSTANT VARCHAR2(30) := 'match_lines_on_line_num';
5729   d_module   CONSTANT VARCHAR2(255) := d_pkg_name || d_api_name || '.';
5730   d_position NUMBER;
5731 
5732   -- hold the key value which is used to identify rows in temp table
5733   l_key           po_session_gt.key%TYPE;
5734 
5735   -- po line that has been found as a match for current line
5736   l_index_tbl          PO_TBL_NUMBER;
5737   l_result_tbl         PO_TBL_NUMBER;
5738 
5739   -- hash table of po_line_id based on po_header_id and line num
5740   TYPE line_ref_type IS TABLE OF DBMS_SQL.NUMBER_TABLE INDEX BY PLS_INTEGER;
5741   l_line_reference_tbl line_ref_type;
5742   l_po_header_id   NUMBER;
5743   l_line_num       NUMBER;
5744 
5745   -- temp variable used in processing
5746   l_index          NUMBER;
5747   l_match_index    NUMBER;
5748 BEGIN
5749   d_position := 0;
5750 
5751   IF (PO_LOG.d_proc) THEN
5752     PO_LOG.proc_begin(d_module);
5753   END IF;
5754 
5755   -- get new key value for po_session_gt table
5756   l_key := PO_CORE_S.get_session_gt_nextval;
5757 
5758   -- match lines whose line_num is not null
5759   -- first, try to find matching line in draft table
5760   FORALL i IN 1..x_lines.rec_count
5761   INSERT INTO po_session_gt(key, num1, num2)
5762   SELECT l_key,
5763          p_index_tbl(i),
5764          po_line_id
5765   FROM   po_lines_draft_all
5766   WHERE  draft_id = x_lines.draft_id_tbl(i)
5767   AND    po_header_id = x_lines.po_header_id_tbl(i)
5768   AND    line_num = x_lines.line_num_tbl(i)
5769   AND    NVL(delete_flag, 'N') <> 'Y';
5770 
5771   d_position := 10;
5772 
5773   DELETE FROM po_session_gt
5774   WHERE  key = l_key
5775   RETURNING num1, num2
5776   BULK COLLECT INTO l_index_tbl, l_result_tbl;
5777 
5778   FOR i IN 1..l_index_tbl.COUNT
5779   LOOP
5780     l_index := l_index_tbl(i);
5781 
5782     IF (PO_LOG.d_stmt) THEN
5783       PO_LOG.stmt(d_module, d_position, 'index', l_index);
5784       PO_LOG.stmt(d_module, d_position, 'matched po line id', l_result_tbl(i));
5785     END IF;
5786 
5787     x_lines.po_line_id_tbl(l_index) := l_result_tbl(i);
5788     x_lines.action_tbl(l_index) := PO_PDOI_CONSTANTS.g_ACTION_UPDATE;
5789   END LOOP;
5790 
5791   d_position := 20;
5792 
5793   -- second, loop through the lines in batch to determine the matching
5794   FOR i IN 1..x_lines.rec_count
5795   LOOP
5796     IF (x_lines.line_num_tbl(i) IS NOT NULL AND
5797         x_lines.po_line_id_tbl(i) IS NULL) THEN
5798       l_po_header_id := x_lines.hd_po_header_id_tbl(i);
5799       l_line_num := x_lines.line_num_tbl(i);
5800 
5801       IF (PO_LOG.d_stmt) THEN
5802         PO_LOG.stmt(d_module, d_position, 'index', i);
5803         PO_LOG.stmt(d_module, d_position, 'po header id', l_po_header_id);
5804         PO_LOG.stmt(d_module, d_position, 'line num', l_line_num);
5805       END IF;
5806 
5807       IF (l_line_reference_tbl.EXISTS(l_po_header_id) AND
5808           l_line_reference_tbl(l_po_header_id).EXISTS(l_line_num)) THEN
5809         d_position := 30;
5810 
5811         x_lines.po_line_id_tbl(i) :=
5812           l_line_reference_tbl(l_po_header_id)(l_line_num);
5813         x_lines.action_tbl(i) := PO_PDOI_CONSTANTS.g_ACTION_UPDATE;
5814 
5815         IF (PO_LOG.d_stmt) THEN
5816           PO_LOG.stmt(d_module, d_position, 'match found for line num');
5817           PO_LOG.stmt(d_module, d_position, 'new po line id',
5818                       x_lines.po_line_id_tbl(i));
5819         END IF;
5820       ELSE
5821         d_position := 40;
5822 
5823         x_lines.po_line_id_tbl(i) :=
5824           PO_PDOI_MAINPROC_UTL_PVT.get_next_po_line_id;
5825         x_lines.action_tbl(i) := PO_PDOI_CONSTANTS.g_ACTION_ADD;
5826 
5827         l_line_reference_tbl(l_po_header_id)(l_line_num) :=
5828           x_lines.po_line_id_tbl(i);
5829 
5830         IF (PO_LOG.d_stmt) THEN
5831           PO_LOG.stmt(d_module, d_position, 'match not found for line num');
5832           PO_LOG.stmt(d_module, d_position, 'new po line id',
5833                       x_lines.po_line_id_tbl(i));
5834         END IF;
5835       END IF;
5836     END IF;
5837   END LOOP;
5838 
5839   IF (PO_LOG.d_proc) THEN
5840     PO_LOG.proc_end(d_module);
5841   END IF;
5842 
5843 EXCEPTION
5844   WHEN OTHERS THEN
5845     PO_MESSAGE_S.add_exc_msg
5846     (
5847       p_pkg_name => d_pkg_name,
5848       p_procedure_name => d_api_name || '.' || d_position
5849     );
5850     RAISE;
5851 END match_lines_on_line_num;
5852 
5853 -----------------------------------------------------------------------
5854 --Start of Comments
5855 --Name: match_lines_on_item_info
5856 --Function:
5857 --  If header action is 'ORIGINAL', or 'REPLACE',
5858 --  this procedure will be called to group the
5859 --  po lines and po line locations.
5860 --  this procedure match the lines based on
5861 --  item related info.
5862 --Parameters:
5863 --IN:
5864 --IN OUT:
5865 --  x_lines
5866 --    record containing line info within the batch
5867 --OUT:
5868 --End of Comments
5869 ------------------------------------------------------------------------
5870 PROCEDURE match_lines_on_item_info
5871 (
5872   x_lines         IN OUT NOCOPY PO_PDOI_TYPES.lines_rec_type
5873 ) IS
5874 
5875   d_api_name CONSTANT VARCHAR2(30) := 'match_lines_on_item_info';
5876   d_module   CONSTANT VARCHAR2(255) := d_pkg_name || d_api_name || '.';
5877   d_position NUMBER;
5878 
5879   -- hold the key value which is used to identify rows in temp table
5880   l_key           po_session_gt.key%TYPE;
5881   l_data_key      po_session_gt.key%TYPE;
5882 
5883   -- identify lines that are going to be processed
5884   l_processing_line_tbl DBMS_SQL.NUMBER_TABLE;
5885   l_num_list            DBMS_SQL.NUMBER_TABLE;
5886 
5887   -- po line that has been found as a match for current line
5888   l_index_tbl          PO_TBL_NUMBER;
5889   l_po_line_id_tbl     PO_TBL_NUMBER;
5890   l_line_num_tbl       PO_TBL_NUMBER;
5891   l_match_index_tbl    PO_TBL_NUMBER;
5892 
5893   -- temp variable used in processing
5894   l_index          NUMBER;
5895   l_match_index    NUMBER;
5896 BEGIN
5897   d_position := 0;
5898 
5899   IF (PO_LOG.d_proc) THEN
5900     PO_LOG.proc_begin(d_module);
5901   END IF;
5902 
5903   -- get key value for po_session_gt table
5904   l_key := PO_CORE_S.get_session_gt_nextval;
5905 
5906   -- First, get lines qualified. The qualified lines must satisfy the following conditions:
5907   -- 1. x_lines.line_num_tbl(i) IS NULL
5908   -- 2. x_lines.hd_actions(i) <> 'UPDATE'
5909   -- 3. x_lines.error_flag_tbl(i) = FND_API.G_FALSE
5910   -- 4. document is not AMOUNT based BLANKET
5911   FOR i IN 1..x_lines.rec_count
5912   LOOP
5913     IF (x_lines.line_num_tbl(i) IS NULL) THEN
5914       IF (x_lines.hd_action_tbl(i) <> PO_PDOI_CONSTANTS.g_ACTION_UPDATE AND
5915           x_lines.error_flag_tbl(i) = FND_API.g_FALSE AND
5916           NOT (x_lines.order_type_lookup_code_tbl(i) = 'AMOUNT' AND
5917                PO_PDOI_PARAMS.g_request.document_type =
5918                PO_PDOI_CONSTANTS.g_DOC_TYPE_BLANKET)) THEN
5919         IF (PO_LOG.d_stmt) THEN
5920           PO_LOG.stmt(d_module, d_position, 'processing index', i);
5921         END IF;
5922 
5923         l_processing_line_tbl(i) := i;
5924       ELSE
5925         -- all lines will be marked as 'ADD'
5926         x_lines.po_line_id_tbl(i) := PO_PDOI_MAINPROC_UTL_PVT.get_next_po_line_id;
5927         x_lines.line_num_tbl(i) :=
5928           PO_PDOI_MAINPROC_UTL_PVT.get_next_line_num(x_lines.po_header_id_tbl(i));
5929         x_lines.action_tbl(i) := PO_PDOI_CONSTANTS.g_ACTION_ADD;
5930 
5931         IF (PO_LOG.d_stmt) THEN
5932           PO_LOG.stmt(d_module, d_position, 'new po line id', x_lines.po_line_id_tbl(i));
5933           PO_LOG.stmt(d_module, d_position, 'new line num', x_lines.line_num_tbl(i));
5934         END IF;
5935       END IF;
5936     END IF;
5937   END LOOP;
5938 
5939   d_position := 10;
5940 
5941   -- perform matching logic for qualified lines
5942   -- a. match on draft table
5943   -- a.1 match on draft table when item_id is not null
5944   FORALL i IN INDICES OF l_processing_line_tbl
5945     INSERT INTO po_session_gt(key, num1, num2, num3)
5946     SELECT l_key,
5947            l_processing_line_tbl(i),
5948            po_line_id,
5949            line_num
5950     FROM   po_lines_draft_all
5951     WHERE  x_lines.item_id_tbl(i) IS NOT NULL
5952     AND    draft_id = x_lines.draft_id_tbl(i)
5953     AND    po_header_id = x_lines.po_header_id_tbl(i)
5954     AND    item_id = x_lines.item_id_tbl(i)
5955     AND    (item_revision = x_lines.item_revision_tbl(i) OR
5956             item_revision IS NULL OR
5957             x_Lines.item_revision_tbl(i) IS NULL)
5958     AND     unit_meas_lookup_code = x_lines.unit_of_measure_tbl(i)
5959     AND     line_type_id = x_lines.line_type_id_tbl(i)
5960     AND     category_id = x_lines.category_id_tbl(i)
5961     AND    NVL(delete_flag, 'N') <> 'Y';
5962 
5963   d_position := 20;
5964 
5965   -- a.2 match on draft table when item_id is null
5966   FORALL i IN INDICES OF l_processing_line_tbl
5967     INSERT INTO po_session_gt(key, num1, num2, num3)
5968     SELECT l_key,
5969            l_processing_line_tbl(i),
5970            po_line_id,
5971            line_num
5972     FROM   po_lines_draft_all
5973     WHERE  x_lines.item_id_tbl(i) IS NULL
5974     AND    draft_id = x_lines.draft_id_tbl(i)
5975     AND    po_header_id = x_lines.po_header_id_tbl(i)
5976     AND    item_description = x_lines.item_desc_tbl(i)
5977     AND    unit_meas_lookup_code = x_lines.unit_of_measure_tbl(i)
5978     AND    line_type_id = x_lines.line_type_id_tbl(i)
5979     AND    category_id = x_lines.category_id_tbl(i)
5980     AND    NVL(delete_flag, 'N') <> 'Y';
5981 
5982   d_position := 30;
5983 
5984   -- get result from temp table
5985   DELETE FROM po_session_gt
5986   WHERE key = l_key
5987   RETURNING num1, num2, num3
5988   BULK COLLECT INTO l_index_tbl, l_po_line_id_tbl, l_line_num_tbl;
5989 
5990   -- set the po_line_id and line_num from matching line
5991   -- so there is no new line created from this row
5992   FOR i IN 1..l_index_tbl.COUNT
5993   LOOP
5994     l_index := l_index_tbl(i);
5995 
5996     IF (PO_LOG.d_stmt) THEN
5997       PO_LOG.stmt(d_module, d_position, 'index', l_index);
5998       PO_LOG.stmt(d_module, d_position, 'matched po line id', l_po_line_id_tbl(i));
5999       PO_LOG.stmt(d_module, d_position, 'matched line num', l_line_num_tbl(i));
6000     END IF;
6001 
6002     x_lines.po_line_id_tbl(l_index) := l_po_line_id_tbl(i);
6003     x_lines.line_num_tbl(l_index) := l_line_num_tbl(i);
6004     x_lines.action_tbl(l_index) := PO_PDOI_CONSTANTS.g_ACTION_UPDATE;
6005     -- delete the corresponding node so the line won't be matched within batch
6006     l_processing_line_tbl.DELETE(i);
6007   END LOOP;
6008 
6009   d_position := 40;
6010 
6011   -- b. match within the same batch
6012   l_data_key := PO_CORE_S.get_session_gt_nextval;
6013   -- initialize table containing the row number(index)
6014   PO_PDOI_UTL.generate_ordered_num_list
6015   (
6016     p_size     => x_lines.rec_count,
6017     x_num_list => l_num_list
6018   );
6019 
6020   FORALL i IN 1..x_lines.rec_count
6021     INSERT INTO po_session_gt(key, num1, num2, num3, char1, char2,
6022                               num4, num5, char3, char4, num6)
6023     VALUES (l_data_key,
6024             x_lines.intf_line_id_tbl(i),           -- num1
6025             x_lines.po_header_id_tbl(i),           -- num2
6026             x_lines.item_id_tbl(i),                -- num3
6027             x_lines.item_revision_tbl(i),          -- char1
6028             x_lines.unit_of_measure_tbl(i),        -- char2
6029             x_lines.line_type_id_tbl(i),           -- num4
6030             x_lines.category_id_tbl(i),            -- num5
6031             x_lines.item_desc_tbl(i),              -- char3
6032             x_lines.order_type_lookup_code_tbl(i), -- char4
6033             l_num_list(i)                          -- num6
6034            );
6035 
6036   d_position := 50;
6037 
6038   -- find lines that cannot find a match in the batch
6039   -- a. check lines where item_id is not null
6040   FORALL i IN INDICES OF l_processing_line_tbl
6041     INSERT INTO po_session_gt(key, num1)
6042     SELECT l_key,
6043            l_processing_line_tbl(i)
6044     FROM   DUAL
6045     WHERE  x_lines.item_id_tbl(i) IS NOT NULL
6046     AND    NOT EXISTS(
6047             SELECT 1
6048             FROM   po_session_gt gt
6049             WHERE  gt.num2 = x_lines.po_header_id_tbl(i)
6050             AND    gt.num1 < x_lines.intf_line_id_tbl(i)
6051             AND    gt.num3 = x_lines.item_id_tbl(i)
6052             AND    (gt.char1 = x_lines.item_revision_tbl(i) OR
6053                     gt.char1 IS NULL OR
6054                     x_lines.item_revision_tbl(i) IS NULL)
6055             AND    gt.char2 = x_lines.unit_of_measure_tbl(i)
6056             AND    gt.num4 = x_lines.line_type_id_tbl(i)
6057             AND    gt.num5 = x_lines.category_id_tbl(i)
6058            );
6059 
6060   d_position := 60;
6061 
6062   -- b. check lines when item_id = null
6063   FORALL i IN INDICES OF l_processing_line_tbl
6064     INSERT INTO po_session_gt(key, num1)
6065     SELECT l_key,
6066            l_processing_line_tbl(i)
6067     FROM   DUAL
6068     WHERE  x_lines.item_id_tbl(i) IS NULL
6069     AND    NOT EXISTS(
6070             SELECT 1
6071             FROM   po_session_gt gt
6072             WHERE  gt.num2 = x_lines.po_header_id_tbl(i)
6073             AND    gt.num1 < x_lines.intf_line_id_tbl(i)
6074             AND    gt.char3 = x_lines.item_desc_tbl(i)
6075             AND    gt.char2 = x_lines.unit_of_measure_tbl(i)
6076             AND    gt.num4 = x_lines.line_type_id_tbl(i)
6077             AND    gt.num5 = x_lines.category_id_tbl(i)
6078            );
6079 
6080   d_position := 70;
6081 
6082   -- get result from temp table
6083   DELETE FROM po_session_gt
6084   WHERE key = l_key
6085   RETURNING num1 BULK COLLECT INTO l_index_tbl;
6086 
6087   -- assign a new po_line_id and line_num to these lines
6088   FOR i IN 1..l_index_tbl.COUNT
6089   LOOP
6090     l_index := l_index_tbl(i);
6091 
6092     x_lines.po_line_id_tbl(l_index) := PO_PDOI_MAINPROC_UTL_PVT.get_next_po_line_id;
6093     x_lines.action_tbl(l_index) := PO_PDOI_CONSTANTS.g_ACTION_ADD;
6094     x_lines.line_num_tbl(l_index) := PO_PDOI_MAINPROC_UTL_PVT.get_next_line_num(x_lines.po_header_id_tbl(i));
6095     -- delete the corresponding node so the line won't be matched within batch
6096     l_processing_line_tbl.DELETE(i);
6097 
6098     IF (PO_LOG.d_stmt) THEN
6099       PO_LOG.stmt(d_module, d_position, 'index', l_index);
6100       PO_LOG.stmt(d_module, d_position, 'assigned po line id',
6101                   x_lines.po_line_id_tbl(l_index));
6102       PO_LOG.stmt(d_module, d_position, 'assigned line num', x_lines.line_num_tbl(l_index));
6103     END IF;
6104   END LOOP;
6105 
6106   d_position := 80;
6107 
6108   -- Last, for lines that can find at least one match in current batch,
6109   -- return one matching line that has the smallest interface_line_id
6110   FORALL i IN INDICES OF l_processing_line_tbl
6111     INSERT INTO po_session_gt(key, num1, num2)
6112     SELECT l_key,
6113            l_processing_line_tbl(i),
6114            v.min_index
6115     FROM   (SELECT min(num6) AS min_index
6116             FROM   po_session_gt
6117             WHERE  x_lines.item_id_tbl(i) IS NOT NULL
6118             AND    num2  = x_lines.po_header_id_tbl(i)
6119             AND    num1 < x_lines.intf_line_id_tbl(i)
6120             AND    num3 = x_lines.item_id_tbl(i)
6121             AND    (char1 = x_lines.item_revision_tbl(i) OR
6122                     char1 IS NULL OR
6123                     x_lines.item_revision_tbl(i) IS NULL)
6124             AND    char2 = x_lines.unit_of_measure_tbl(i)
6125             AND    num4 = x_lines.line_type_id_tbl(i)
6126             AND    num5 = x_lines.category_id_tbl(i)) v
6127     WHERE  v.min_index IS NOT NULL;
6128 
6129   d_position := 90;
6130 
6131   FORALL i IN INDICES OF l_processing_line_tbl
6132     INSERT INTO po_session_gt(key, num1, num2)
6133     SELECT l_key,
6134            l_processing_line_tbl(i),
6135            v.min_index
6136     FROM   (SELECT min(num6) AS min_index
6137             FROM   po_session_gt
6138             WHERE  x_lines.item_id_tbl(i) IS NULL
6139             AND    num2 = x_lines.po_header_id_tbl(i)
6140             AND    num1 < x_lines.intf_line_id_tbl(i)
6141             AND    char3 = x_lines.item_desc_tbl(i)
6142             AND    char2 = x_lines.unit_of_measure_tbl(i)
6143             AND    num4 = x_lines.line_type_id_tbl(i)
6144             AND    num5 = x_lines.category_id_tbl(i)) v
6145     WHERE   v.min_index IS NOT NULL;
6146 
6147   d_position := 100;
6148 
6149   DELETE FROM po_session_gt
6150   WHERE key = l_key
6151   RETURNING num1, num2 BULK COLLECT INTO l_index_tbl, l_match_index_tbl;
6152 
6153   IF (PO_LOG.d_stmt) THEN
6154     PO_LOG.stmt(d_module, d_position, 'l_index_tbl', l_index_tbl);
6155     PO_LOG.stmt(d_module, d_position, 'l_match_index_tbl', l_match_index_tbl);
6156   END IF;
6157 
6158   FOR i IN 1..l_index_tbl.COUNT
6159   LOOP
6160     l_index := l_index_tbl(i);
6161     l_match_index := l_match_index_tbl(i);
6162 
6163     x_lines.po_line_id_tbl(l_index) := x_lines.po_line_id_tbl(l_match_index);
6164     x_lines.line_num_tbl(l_index) := x_lines.line_num_tbl(l_match_index);
6165     x_lines.action_tbl(l_index) := PO_PDOI_CONSTANTS.g_ACTION_UPDATE;
6166 
6167     IF (PO_LOG.d_stmt) THEN
6168       PO_LOG.stmt(d_module, d_position, 'index', l_index);
6169       PO_LOG.stmt(d_module, d_position, 'match index', l_match_index);
6170       PO_LOG.stmt(d_module, d_position, 'matched po line id',
6171                   x_lines.po_line_id_tbl(l_index));
6172       PO_LOG.stmt(d_module, d_position, 'matched line num', x_lines.line_num_tbl(l_index));
6173     END IF;
6174   END LOOP;
6175 
6176   d_position := 110;
6177 
6178   -- clean up po_session_gt
6179   PO_PDOI_UTL.remove_session_gt_records
6180   ( p_key => l_data_key
6181   );
6182 
6183   IF (PO_LOG.d_proc) THEN
6184     PO_LOG.proc_end(d_module);
6185   END IF;
6186 
6187 EXCEPTION
6188   WHEN OTHERS THEN
6189     PO_MESSAGE_S.add_exc_msg
6190     (
6191       p_pkg_name => d_pkg_name,
6192       p_procedure_name => d_api_name || '.' || d_position
6193     );
6194     RAISE;
6195 END match_lines_on_item_info;
6196 
6197 -----------------------------------------------------------------------
6198 --Start of Comments
6199 --Name: copy_lines
6200 --Function:
6201 --  copy all the attribute values from one po_line to another
6202 --Parameters:
6203 --IN:
6204 --  p_source_lines
6205 --    source of copy action
6206 --  p_source_index_tbl
6207 --    the indexes of line to be copied
6208 --IN OUT:
6209 --  x_target_lines
6210 --    record containing lines copied from source line
6211 --OUT:
6212 --End of Comments
6213 ------------------------------------------------------------------------
6214 PROCEDURE copy_lines
6215 (
6216   p_source_lines     IN PO_PDOI_TYPES.lines_rec_type,
6217   p_source_index_tbl IN DBMS_SQL.NUMBER_TABLE,
6218   x_target_lines     IN OUT NOCOPY PO_PDOI_TYPES.lines_rec_type
6219 ) IS
6220 
6221   d_api_name CONSTANT VARCHAR2(30) := 'copy_lines';
6222   d_module   CONSTANT VARCHAR2(255) := d_pkg_name || d_api_name || '.';
6223   d_position NUMBER;
6224 
6225   l_source_index NUMBER;
6226   l_target_index NUMBER :=0;
6227 BEGIN
6228   d_position := 0;
6229 
6230   IF (PO_LOG.d_proc) THEN
6231     PO_LOG.proc_begin(d_module);
6232   END IF;
6233 
6234   -- bug5107324
6235   -- Refactored the code as PO_PDOI_TYPES.fill_all_lines_attr already does
6236   -- all the initialization work for all attributes in lines
6237 
6238   -- bug5129752
6239   -- Move the initialization up front
6240 
6241   -- initialize the tables
6242   PO_PDOI_TYPES.fill_all_lines_attr
6243   ( p_num_records => p_source_index_tbl.COUNT,
6244     x_lines       => x_target_lines
6245   );
6246 
6247   IF (p_source_index_tbl.COUNT = 0) THEN
6248 
6249     IF (PO_LOG.d_proc) THEN
6250       PO_LOG.proc_end(d_module, 'no line is copied', p_source_index_tbl.COUNT);
6251     END IF;
6252 
6253     RETURN;
6254   END IF;
6255 
6256   l_source_index := p_source_index_tbl.FIRST;
6257   WHILE (l_source_index IS NOT NULL)
6258   LOOP
6259     -- increase target index
6260     l_target_index := l_target_index + 1;
6261 
6262     d_position := 20;
6263 
6264     -- copy line interface attributes
6265     x_target_lines.intf_line_id_tbl(l_target_index) := p_source_lines.intf_line_id_tbl(l_source_index);
6266     x_target_lines.intf_header_id_tbl(l_target_index) := p_source_lines.intf_header_id_tbl(l_source_index);
6267     x_target_lines.po_header_id_tbl(l_target_index) := p_source_lines.po_header_id_tbl(l_source_index);
6268     x_target_lines.po_line_id_tbl(l_target_index) := p_source_lines.po_line_id_tbl(l_source_index);
6269     x_target_lines.action_tbl(l_target_index) := p_source_lines.action_tbl(l_source_index);
6270     x_target_lines.document_num_tbl(l_target_index) := p_source_lines.document_num_tbl(l_source_index);
6271     x_target_lines.item_tbl(l_target_index) := p_source_lines.item_tbl(l_source_index);
6272     x_target_lines.vendor_product_num_tbl(l_target_index) := p_source_lines.vendor_product_num_tbl(l_source_index);
6273     x_target_lines.supplier_part_auxid_tbl(l_target_index) := p_source_lines.supplier_part_auxid_tbl(l_source_index);
6274     x_target_lines.item_id_tbl(l_target_index) := p_source_lines.item_id_tbl(l_source_index);
6275     x_target_lines.item_revision_tbl(l_target_index) := p_source_lines.item_revision_tbl(l_source_index);
6276     x_target_lines.job_business_group_name_tbl(l_target_index) := p_source_lines.job_business_group_name_tbl(l_source_index);
6277     x_target_lines.job_business_group_id_tbl(l_target_index) := p_source_lines.job_business_group_id_tbl(l_source_index);
6278     x_target_lines.job_name_tbl(l_target_index) := p_source_lines.job_name_tbl(l_source_index);
6279     x_target_lines.job_id_tbl(l_target_index) := p_source_lines.job_id_tbl(l_source_index);
6280     x_target_lines.category_tbl(l_target_index) := p_source_lines.category_tbl(l_source_index);
6281     x_target_lines.category_id_tbl(l_target_index) := p_source_lines.category_id_tbl(l_source_index);
6282     x_target_lines.ip_category_tbl(l_target_index) := p_source_lines.ip_category_tbl(l_source_index);
6283     x_target_lines.ip_category_id_tbl(l_target_index) := p_source_lines.ip_category_id_tbl(l_source_index);
6284     x_target_lines.uom_code_tbl(l_target_index) := p_source_lines.uom_code_tbl(l_source_index);
6285     x_target_lines.unit_of_measure_tbl(l_target_index) := p_source_lines.unit_of_measure_tbl(l_source_index);
6286     x_target_lines.line_type_tbl(l_target_index) := p_source_lines.line_type_tbl(l_source_index);
6287     x_target_lines.line_type_id_tbl(l_target_index) := p_source_lines.line_type_id_tbl(l_source_index);
6288     x_target_lines.un_number_tbl(l_target_index) := p_source_lines.un_number_tbl(l_source_index);
6289     x_target_lines.un_number_id_tbl(l_target_index) := p_source_lines.un_number_id_tbl(l_source_index);
6290     x_target_lines.hazard_class_tbl(l_target_index) := p_source_lines.hazard_class_tbl(l_source_index);
6291     x_target_lines.hazard_class_id_tbl(l_target_index) := p_source_lines.hazard_class_id_tbl(l_source_index);
6292     x_target_lines.template_name_tbl(l_target_index) := p_source_lines.template_name_tbl(l_source_index);
6293     x_target_lines.template_id_tbl(l_target_index) := p_source_lines.template_id_tbl(l_source_index);
6294     x_target_lines.item_desc_tbl(l_target_index) := p_source_lines.item_desc_tbl(l_source_index);
6295     x_target_lines.unit_price_tbl(l_target_index) := p_source_lines.unit_price_tbl(l_source_index);
6296     x_target_lines.base_unit_price_tbl(l_target_index) := p_source_lines.base_unit_price_tbl(l_source_index);
6297     x_target_lines.from_header_id_tbl(l_target_index) := p_source_lines.from_header_id_tbl(l_source_index);
6298     x_target_lines.from_line_id_tbl(l_target_index) := p_source_lines.from_line_id_tbl(l_source_index);
6299     x_target_lines.list_price_per_unit_tbl(l_target_index) := p_source_lines.list_price_per_unit_tbl(l_source_index);
6300     x_target_lines.market_price_tbl(l_target_index) := p_source_lines.market_price_tbl(l_source_index);
6301     x_target_lines.capital_expense_flag_tbl(l_target_index) := p_source_lines.capital_expense_flag_tbl(l_source_index);
6302     x_target_lines.min_release_amount_tbl(l_target_index) := p_source_lines.min_release_amount_tbl(l_source_index);
6303     x_target_lines.allow_price_override_flag_tbl(l_target_index) := p_source_lines.allow_price_override_flag_tbl(l_source_index);
6304     x_target_lines.price_type_tbl(l_target_index) := p_source_lines.price_type_tbl(l_source_index);
6305     x_target_lines.price_break_lookup_code_tbl(l_target_index) := p_source_lines.price_break_lookup_code_tbl(l_source_index);
6306     x_target_lines.closed_code_tbl(l_target_index) := p_source_lines.closed_code_tbl(l_source_index);
6307     x_target_lines.quantity_tbl(l_target_index) := p_source_lines.quantity_tbl(l_source_index);
6308     x_target_lines.line_num_tbl(l_target_index) := p_source_lines.line_num_tbl(l_source_index);
6309     x_target_lines.shipment_num_tbl(l_target_index) := p_source_lines.shipment_num_tbl(l_source_index);
6310     x_target_lines.price_chg_accept_flag_tbl(l_target_index) := p_source_lines.price_chg_accept_flag_tbl(l_source_index);
6311     x_target_lines.effective_date_tbl(l_target_index) := p_source_lines.effective_date_tbl(l_source_index);
6312     x_target_lines.expiration_date_tbl(l_target_index) := p_source_lines.expiration_date_tbl(l_source_index);
6313     x_target_lines.attribute14_tbl(l_target_index) := p_source_lines.attribute14_tbl(l_source_index);
6314     x_target_lines.price_update_tolerance_tbl(l_target_index) := p_source_lines.price_update_tolerance_tbl(l_source_index);
6315     x_target_lines.error_flag_tbl(l_target_index) := p_source_lines.error_flag_tbl(l_source_index);
6316     x_target_lines.need_to_reject_flag_tbl(l_target_index) := p_source_lines.need_to_reject_flag_tbl(l_source_index);
6317     x_target_lines.line_loc_populated_flag_tbl(l_target_index) := p_source_lines.line_loc_populated_flag_tbl(l_source_index);
6318     x_target_lines.negotiated_flag_tbl(l_target_index) := p_source_lines.negotiated_flag_tbl(l_source_index);
6319     x_target_lines.amount_tbl(l_target_index) := p_source_lines.amount_tbl(l_source_index);
6320     x_target_lines.contractor_last_name_tbl(l_target_index) := p_source_lines.contractor_last_name_tbl(l_source_index);
6321     x_target_lines.contractor_first_name_tbl(l_target_index) := p_source_lines.contractor_first_name_tbl(l_source_index);
6322     x_target_lines.over_tolerance_err_flag_tbl(l_target_index) := p_source_lines.over_tolerance_err_flag_tbl(l_source_index);
6323     x_target_lines.not_to_exceed_price_tbl(l_target_index) := p_source_lines.not_to_exceed_price_tbl(l_source_index);
6324     x_target_lines.po_release_id_tbl(l_target_index) := p_source_lines.po_release_id_tbl(l_source_index);
6325     x_target_lines.release_num_tbl(l_target_index) := p_source_lines.release_num_tbl(l_source_index);
6326     x_target_lines.source_shipment_id_tbl(l_target_index) := p_source_lines.source_shipment_id_tbl(l_source_index);
6327     x_target_lines.contract_num_tbl(l_target_index) := p_source_lines.contract_num_tbl(l_source_index);
6328     x_target_lines.contract_id_tbl(l_target_index) := p_source_lines.contract_id_tbl(l_source_index);
6329     x_target_lines.type_1099_tbl(l_target_index) := p_source_lines.type_1099_tbl(l_source_index);
6330     x_target_lines.closed_by_tbl(l_target_index) := p_source_lines.closed_by_tbl(l_source_index);
6331     x_target_lines.closed_date_tbl(l_target_index) := p_source_lines.closed_date_tbl(l_source_index);
6332     x_target_lines.committed_amount_tbl(l_target_index) := p_source_lines.committed_amount_tbl(l_source_index);
6333     x_target_lines.qty_rcv_exception_code_tbl(l_target_index) := p_source_lines.qty_rcv_exception_code_tbl(l_source_index);
6334     x_target_lines.weight_uom_code_tbl(l_target_index) := p_source_lines.weight_uom_code_tbl(l_source_index);
6335     x_target_lines.volume_uom_code_tbl(l_target_index) := p_source_lines.volume_uom_code_tbl(l_source_index);
6336     x_target_lines.secondary_unit_of_meas_tbl(l_target_index) := p_source_lines.secondary_unit_of_meas_tbl(l_source_index);
6337     x_target_lines.secondary_quantity_tbl(l_target_index) := p_source_lines.secondary_quantity_tbl(l_source_index);
6338     x_target_lines.preferred_grade_tbl(l_target_index) := p_source_lines.preferred_grade_tbl(l_source_index);
6339     x_target_lines.process_code_tbl(l_target_index) := p_source_lines.process_code_tbl(l_source_index);
6340     x_target_lines.parent_interface_line_id_tbl(l_target_index) := p_source_lines.parent_interface_line_id_tbl(l_source_index); -- bug5149827
6341 
6342     d_position := 30;
6343 
6344     -- copy standard who columns
6345     x_target_lines.last_updated_by_tbl(l_target_index) := p_source_lines.last_updated_by_tbl(l_source_index);
6346     x_target_lines.last_update_date_tbl(l_target_index) := p_source_lines.last_update_date_tbl(l_source_index);
6347     x_target_lines.last_update_login_tbl(l_target_index) := p_source_lines.last_update_login_tbl(l_source_index);
6348     x_target_lines.creation_date_tbl(l_target_index) := p_source_lines.creation_date_tbl(l_source_index);
6349     x_target_lines.created_by_tbl(l_target_index) := p_source_lines.created_by_tbl(l_source_index);
6350     x_target_lines.request_id_tbl(l_target_index) := p_source_lines.request_id_tbl(l_source_index);
6351     x_target_lines.program_application_id_tbl(l_target_index) := p_source_lines.program_application_id_tbl(l_source_index);
6352     x_target_lines.program_id_tbl(l_target_index) := p_source_lines.program_id_tbl(l_source_index);
6353     x_target_lines.program_update_date_tbl(l_target_index) := p_source_lines.program_update_date_tbl(l_source_index);
6354 
6355     d_position := 40;
6356 
6357     -- copy attributes from header
6358     x_target_lines.draft_id_tbl(l_target_index) := p_source_lines.draft_id_tbl(l_source_index);
6359     x_target_lines.hd_action_tbl(l_target_index) := p_source_lines.hd_action_tbl(l_source_index);
6360     x_target_lines.hd_po_header_id_tbl(l_target_index) := p_source_lines.hd_po_header_id_tbl(l_source_index);
6361     x_target_lines.hd_vendor_id_tbl(l_target_index) := p_source_lines.hd_vendor_id_tbl(l_source_index);
6362     x_target_lines.hd_min_release_amount_tbl(l_target_index) := p_source_lines.hd_min_release_amount_tbl(l_source_index);
6363     x_target_lines.hd_start_date_tbl(l_target_index) := p_source_lines.hd_start_date_tbl(l_source_index);
6364     x_target_lines.hd_end_date_tbl(l_target_index) := p_source_lines.hd_end_date_tbl(l_source_index);
6365     x_target_lines.hd_global_agreement_flag_tbl(l_target_index) := p_source_lines.hd_global_agreement_flag_tbl(l_source_index);
6366     x_target_lines.hd_currency_code_tbl(l_target_index) := p_source_lines.hd_currency_code_tbl(l_source_index);
6367     x_target_lines.hd_created_language_tbl(l_target_index) := p_source_lines.hd_created_language_tbl(l_source_index);
6368     x_target_lines.hd_style_id_tbl(l_target_index) := p_source_lines.hd_style_id_tbl(l_source_index);
6369     x_target_lines.hd_rate_type_tbl(l_target_index) := p_source_lines.hd_rate_type_tbl(l_source_index);
6370 
6371     -- copy processing attributes
6372     x_target_lines.create_line_loc_tbl(l_target_index) := p_source_lines.create_line_loc_tbl(l_source_index);
6373     x_target_lines.order_type_lookup_code_tbl(l_target_index) := p_source_lines.order_type_lookup_code_tbl(l_source_index);
6374     x_target_lines.purchase_basis_tbl(l_target_index) := p_source_lines.purchase_basis_tbl(l_source_index);
6375     x_target_lines.matching_basis_tbl(l_target_index) := p_source_lines.matching_basis_tbl(l_source_index);
6376     x_target_lines.unordered_flag_tbl(l_target_index) := p_source_lines.unordered_flag_tbl(l_source_index);
6377     x_target_lines.cancel_flag_tbl(l_target_index) := p_source_lines.cancel_flag_tbl(l_source_index);
6378     x_target_lines.quantity_committed_tbl(l_target_index) := p_source_lines.quantity_committed_tbl(l_source_index);
6379     x_target_lines.tax_attribute_update_code_tbl(l_target_index) := p_source_lines.tax_attribute_update_code_tbl(l_source_index);
6380     x_target_lines.allow_desc_update_flag_tbl(l_target_index) := p_source_lines.allow_desc_update_flag_tbl(l_source_index); -- bug5107324
6381 
6382     -- get next index
6383     l_source_index := p_source_index_tbl.NEXT(l_source_index);
6384   END LOOP;
6385 
6386   d_position := 50;
6387 
6388   -- rebuild index table
6389   FOR i IN 1..x_target_lines.rec_count
6390   LOOP
6391     x_target_lines.intf_id_index_tbl(x_target_lines.intf_line_id_tbl(i)) := i;
6392   END LOOP;
6393 
6394   IF (PO_LOG.d_proc) THEN
6395     PO_LOG.proc_end(d_module, 'number of copied lines', l_target_index);
6396   END IF;
6397 
6398 EXCEPTION
6399   WHEN OTHERS THEN
6400     PO_MESSAGE_S.add_exc_msg
6401     (
6402       p_pkg_name => d_pkg_name,
6403       p_procedure_name => d_api_name || '.' || d_position
6404     );
6405     RAISE;
6406 END copy_lines;
6407 
6408 -----------------------------------------------------------------------
6409 --Start of Comments
6410 --Name: uniqueness_check_on_desc
6411 --Function:
6412 --  check item uniqueness based on description + category name
6413 --Parameters:
6414 --IN:
6415 --  p_key
6416 --    key value used to identify rows in temp table
6417 --  p_group_num
6418 --    the new group number that is going to be assigned to rows
6419 --    whose action can be decided in this procedure
6420 --IN OUT:
6421 --  x_processing_row_tbl
6422 --    index table of rows that are going to be processed
6423 --  x_lines
6424 --    record of line information read within the batch
6425 --OUT:
6426 --End of Comments
6427 ------------------------------------------------------------------------
6428 PROCEDURE uniqueness_check_on_desc
6429 (
6430   p_key                 IN po_session_gt.key%TYPE,
6431   p_group_num           IN NUMBER,
6432   x_processing_row_tbl  IN OUT NOCOPY DBMS_SQL.NUMBER_TABLE,
6433   x_lines               IN OUT NOCOPY PO_PDOI_TYPES.lines_rec_type
6434 ) IS
6435 
6436   d_api_name CONSTANT VARCHAR2(30) := 'uniqueness_check_on_desc';
6437   d_module   CONSTANT VARCHAR2(255) := d_pkg_name || d_api_name || '.';
6438   d_position NUMBER;
6439 
6440   -- variables to hold matching result read from po_session_gt table
6441   l_index_tbl           PO_TBL_NUMBER;
6442   l_po_line_id_tbl      PO_TBL_NUMBER;
6443   l_line_num_tbl        PO_TBL_NUMBER;
6444 
6445   l_index               NUMBER;
6446   l_data_key            po_session_gt.key%TYPE;
6447 
6448 BEGIN
6449   d_position := 0;
6450 
6451   IF (PO_LOG.d_proc) THEN
6452     PO_LOG.proc_begin(d_module);
6453   END IF;
6454 
6455   -- check matchings on draft table
6456   FORALL i IN INDICES OF x_processing_row_tbl
6457     INSERT INTO po_session_gt
6458     (
6459       key,
6460       num1,
6461       num2,
6462       num3
6463     )
6464     SELECT
6465       p_key,
6466       x_processing_row_tbl(i),
6467       draft_lines.po_line_id,
6468       draft_lines.line_num
6469     FROM  po_lines_draft_all draft_lines
6470     WHERE draft_lines.po_header_id = x_lines.hd_po_header_id_tbl(i)
6471     AND   draft_lines.draft_id = x_lines.draft_id_tbl(i)
6472     AND   NVL(draft_lines.expiration_date, TRUNC(sysdate)) >= TRUNC(sysdate)
6473     AND   draft_lines.item_description = x_lines.item_desc_tbl(i)
6474     AND   (x_lines.category_tbl(i) IS NULL OR
6475            EXISTS ( SELECT 1
6476                     FROM   mtl_categories_kfv mck
6477                     WHERE  mck.concatenated_segments = x_lines.category_tbl(i)
6478                     AND    mck.category_id = draft_lines.category_id));
6479 
6480   d_position := 10;
6481 
6482   -- check matching on txn table
6483   FORALL i IN INDICES OF x_processing_row_tbl
6484     INSERT INTO po_session_gt
6485     (
6486       key,
6487       num1,
6488       num2,
6489       num3
6490     )
6491     SELECT
6492       p_key,
6493       x_processing_row_tbl(i),
6494       txn_lines.po_line_id,
6495       txn_lines.line_num
6496     FROM  po_lines txn_lines
6497     WHERE txn_lines.po_header_id = x_lines.hd_po_header_id_tbl(i)
6498     AND   NOT EXISTS ( SELECT 1
6499                        FROM   po_lines_draft_all draft_lines
6500                        WHERE  draft_lines.po_line_id = txn_lines.po_line_id
6501                        AND    draft_lines.draft_id = x_lines.draft_id_tbl(i))
6502     AND   txn_lines.item_description = x_lines.item_desc_tbl(i)
6503     AND   (x_lines.category_tbl(i) IS NULL OR
6504            EXISTS ( SELECT 1
6505                     FROM   mtl_categories_kfv mck
6506                     WHERE  mck.concatenated_segments = x_lines.category_tbl(i)
6507                     AND    mck.category_id = txn_lines.category_id))
6508     AND   NVL(txn_lines.expiration_date, TRUNC(sysdate)) >= TRUNC(sysdate)
6509     AND   NVL(txn_lines.closed_code, 'OPEN') <> 'FINALLY CLOSED'
6510     AND   NVL(txn_lines.cancel_flag, 'N') <> 'Y';
6511 
6512   d_position := 20;
6513 
6514   DELETE FROM po_session_gt
6515   WHERE key = p_key
6516   RETURNING num1, num2, num3 BULK COLLECT INTO
6517     l_index_tbl, l_po_line_id_tbl, l_line_num_tbl;
6518 
6519   -- set po_line_id, and line_num from matching record
6520   -- If there is only one matching -- OK
6521   -- If there are multiple matching records, update the line that has same
6522   -- line_num as in interface table; otherwise, update line with maximum
6523   -- line_num
6524   FOR i IN 1..l_index_tbl.COUNT
6525   LOOP
6526     l_index := l_index_tbl(i);
6527 
6528     IF (x_lines.po_line_id_tbl(l_index) IS NULL) THEN
6529       IF (PO_LOG.d_stmt) THEN
6530         PO_LOG.stmt(d_module, d_position, 'first match index', l_index);
6531         PO_LOG.stmt(d_module, d_position, 'po line id', l_po_line_id_tbl(i));
6532         PO_LOG.stmt(d_module, d_position, 'line num', l_line_num_tbl(i));
6533       END IF;
6534 
6535       -- first match found
6536       x_lines.origin_line_num_tbl(l_index) := x_lines.line_num_tbl(l_index);
6537       x_lines.action_tbl(l_index) := PO_PDOI_CONSTANTS.g_ACTION_UPDATE;
6538       x_lines.group_num_tbl(l_index) := p_group_num;
6539       x_lines.po_line_id_tbl(l_index) := l_po_line_id_tbl(i);
6540       x_lines.line_num_tbl(l_index) := l_line_num_tbl(i);
6541       x_processing_row_tbl.DELETE(l_index);
6542       IF (l_line_num_tbl(i) = x_lines.origin_line_num_tbl(l_index)) THEN
6543         x_lines.match_line_found_tbl(l_index) := FND_API.g_TRUE;
6544       END IF;
6545     ELSE
6546       IF (PO_LOG.d_stmt) THEN
6547         PO_LOG.stmt(d_module, d_position, 'multi match index', l_index);
6548         PO_LOG.stmt(d_module, d_position, 'po line id', l_po_line_id_tbl(i));
6549         PO_LOG.stmt(d_module, d_position, 'line num', l_line_num_tbl(i));
6550         PO_LOG.stmt(d_module, d_position, 'original line num',
6551                     x_lines.origin_line_num_tbl(l_index));
6552         PO_LOG.stmt(d_module, d_position, 'match line found',
6553                     x_lines.match_line_found_tbl(l_index));
6554         PO_LOG.stmt(d_module, d_position, 'current line num',
6555                     x_lines.line_num_tbl(l_index));
6556       END IF;
6557 
6558       -- multiple matches found
6559       IF (l_line_num_tbl(i) = x_lines.origin_line_num_tbl(l_index)) THEN
6560         -- record matching line_num is found
6561         x_lines.po_line_id_tbl(l_index) := l_po_line_id_tbl(i);
6562         x_lines.line_num_tbl(l_index) := l_line_num_tbl(i);
6563         x_lines.match_line_found_tbl(l_index) := FND_API.g_TRUE;
6564       ELSIF (x_lines.match_line_found_tbl(l_index) = FND_API.g_TRUE) THEN
6565         -- need to do nothing, record with matching line num is found before
6566         NULL;
6567       ELSIF (x_lines.line_num_tbl(l_index) < l_line_num_tbl(i)) THEN
6568         -- try to update line with maximum line num if exact match can not be found
6569         x_lines.po_line_id_tbl(l_index) := l_po_line_id_tbl(i);
6570         x_lines.line_num_tbl(l_index) := l_line_num_tbl(i);
6571       ELSE
6572         -- do nothing since the new coming record has smaller line num
6573         -- than current matching record
6574         NULL;
6575       END IF;
6576     END IF;
6577   END LOOP;
6578 
6579   d_position := 30;
6580 
6581   -- search within the batch
6582   -- find out all lines that cannot find a match
6583   -- and set their action to ADD
6584   l_data_key := PO_CORE_S.get_session_gt_nextval;
6585   FORALL i IN INDICES OF x_processing_row_tbl
6586     INSERT INTO po_session_gt
6587     (
6588       key,
6589       num1,
6590       num2,
6591       char1,
6592       char2
6593     )
6594   SELECT
6595     l_data_key,
6596     x_lines.intf_line_id_tbl(i),       -- num1
6597     x_lines.hd_po_header_id_tbl(i),    -- num2
6598     x_lines.item_desc_tbl(i),          -- char1
6599     x_lines.category_tbl(i)            -- char2
6600   FROM DUAL;
6601 
6602   d_position := 40;
6603 
6604   FORALL i IN INDICES OF x_processing_row_tbl
6605     INSERT INTO po_session_gt
6606     (
6607       key,
6608       num1
6609     )
6610     SELECT p_key,
6611            x_processing_row_tbl(i)
6612     FROM   DUAL
6613     WHERE  NOT EXISTS(
6614            SELECT 1
6615            FROM   po_session_gt gt
6616            WHERE  key = l_data_key
6617            AND    gt.num1 < x_lines.intf_line_id_tbl(i)
6618            AND    gt.num2 = x_lines.hd_po_header_id_tbl(i)
6619            AND    gt.char1 = x_lines.item_desc_tbl(i)
6620            AND    NVL(x_lines.category_tbl(i), NVL(gt.char2, -99))=
6621                     NVL(gt.char2, -99));
6622 
6623   d_position := 50;
6624 
6625   DELETE FROM po_session_gt
6626   WHERE key = p_key
6627   RETURNING num1 BULK COLLECT INTO l_index_tbl;
6628 
6629   -- bug5093465
6630   -- For the records in l_index_tbl, assign action 'ADD'
6631   set_action_add
6632   ( p_key                    => p_key,
6633     p_group_num              => p_group_num,
6634     p_target_lines_index_tbl => l_index_tbl,
6635     p_check_line_num_assign  => FND_API.G_TRUE,
6636     x_processing_row_tbl     => x_processing_row_tbl,
6637     x_lines                  => x_lines
6638   );
6639 
6640   d_position := 60;
6641 
6642   -- clean up po_session_gt
6643   PO_PDOI_UTL.remove_session_gt_records
6644   ( p_key => l_data_key
6645   );
6646 
6647   IF (PO_LOG.d_proc) THEN
6648     PO_LOG.proc_end(d_module);
6649   END IF;
6650 
6651 EXCEPTION
6652   WHEN OTHERS THEN
6653     PO_MESSAGE_S.add_exc_msg
6654     (
6655       p_pkg_name => d_pkg_name,
6656       p_procedure_name => d_api_name || '.' || d_position
6657     );
6658     RAISE;
6659 END uniqueness_check_on_desc;
6660 
6661 -----------------------------------------------------------------------
6662 --Start of Comments
6663 --Name: uniqueness_check_on_item
6664 --Function:
6665 --  check item uniqueness based on item + revision + vendor_product_num
6666 --  + supplier_part_aux_id
6667 --Parameters:
6668 --IN:
6669 --  p_key
6670 --    key value used to identify rows in temp table
6671 --  p_group_num
6672 --    the new group number that is going to be assigned to rows
6673 --    whose action can be decided in this procedure
6674 --IN OUT:
6675 --  x_processing_row_tbl
6676 --    index table of rows that are going to be processed
6677 --  x_lines
6678 --    record of line information read within the batch
6679 --OUT:
6680 --End of Comments
6681 ------------------------------------------------------------------------
6682 PROCEDURE uniqueness_check_on_item
6683 (
6684   p_key                 IN po_session_gt.key%TYPE,
6685   p_group_num           IN NUMBER,
6686   x_processing_row_tbl  IN OUT NOCOPY DBMS_SQL.NUMBER_TABLE,
6687   x_lines               IN OUT NOCOPY PO_PDOI_TYPES.lines_rec_type
6688 ) IS
6689 
6690   d_api_name CONSTANT VARCHAR2(30) := 'uniqueness_check_on_item';
6691   d_module   CONSTANT VARCHAR2(255) := d_pkg_name || d_api_name || '.';
6692   d_position NUMBER;
6693 
6694   l_def_master_org_id   NUMBER;
6695 
6696   -- variables to hold matching result read from po_session_gt table
6697   l_index_tbl           PO_TBL_NUMBER;
6698   l_po_line_id_tbl      PO_TBL_NUMBER;
6699   l_line_num_tbl        PO_TBL_NUMBER;
6700 
6701   l_index               NUMBER;
6702   l_data_key            po_session_gt.key%TYPE;
6703 
6704 BEGIN
6705   d_position := 0;
6706 
6707   IF (PO_LOG.d_proc) THEN
6708     PO_LOG.proc_begin(d_module);
6709   END IF;
6710 
6711   -- get default master org id
6712   l_def_master_org_id := PO_PDOI_PARAMS.g_sys.master_inv_org_id;
6713 
6714   IF (PO_LOG.d_stmt) THEN
6715     PO_LOG.stmt(d_module, d_position, 'l_def_master_org_id',
6716                 l_def_master_org_id);
6717     PO_LOG.stmt(d_module, d_position, 'item_tbl', x_lines.item_tbl);
6718     PO_LOG.stmt(d_module, d_position, 'po_header_id_tbl',
6719                 x_lines.hd_po_header_id_tbl);
6720     PO_LOG.stmt(d_module, d_position, 'draft_id_tbl', x_lines.draft_id_tbl);
6721     PO_LOG.stmt(d_module, d_position, 'item_revision_tbl',
6722                 x_lines.item_revision_tbl);
6723     PO_LOG.stmt(d_module, d_position, 'vendor_product_num_tbl',
6724                 x_lines.vendor_product_num_tbl);
6725     PO_LOG.stmt(d_module, d_position, 'supplier_part_auxid_tbl',
6726                 x_lines.supplier_part_auxid_tbl);
6727   END IF;
6728 
6729   -- check matching on draft table
6730   FORALL i IN INDICES OF x_processing_row_tbl
6731     INSERT INTO po_session_gt
6732     (
6733       key,
6734       num1,
6735       num2,
6736       num3
6737     )
6738     SELECT
6739       p_key,
6740       x_processing_row_tbl(i),
6741       draft_lines.po_line_id,
6742       draft_lines.line_num
6743     FROM  po_lines_draft_all draft_lines
6744     WHERE x_lines.item_tbl(i) IS NOT NULL
6745     AND   draft_lines.po_header_id = x_lines.hd_po_header_id_tbl(i)
6746     AND   draft_lines.draft_id = x_lines.draft_id_tbl(i)
6747     AND   NVL(draft_lines.expiration_date, TRUNC(sysdate)) >= TRUNC(sysdate)
6748     AND   EXISTS (SELECT 1
6749                   FROM   mtl_system_items items
6750                   WHERE  items.inventory_item_id = draft_lines.item_id
6751                   AND    items.segment1 = x_lines.item_tbl(i)
6752                   AND    items.organization_id =
6753                            NVL(l_def_master_org_id, items.organization_id))
6754     AND    NVL(x_lines.item_revision_tbl(i), NVL(draft_lines.item_revision, -99)) =
6755              NVL(draft_lines.item_revision, -99)
6756     AND    NVL(x_lines.vendor_product_num_tbl(i), NVL(draft_lines.vendor_product_num, -99)) =
6757              NVL(draft_lines.vendor_product_num, -99)
6758     AND    NVL(x_lines.supplier_part_auxid_tbl(i),
6759                NVL(draft_lines.supplier_part_auxid, FND_API.g_NULL_CHAR))=
6760            NVL(draft_lines.supplier_part_auxid, FND_API.g_NULL_CHAR);
6761 
6762   d_position := 10;
6763 
6764   -- check matching on txn table
6765   FORALL i IN INDICES OF x_processing_row_tbl
6766     INSERT INTO po_session_gt
6767     (
6768       key,
6769       num1,
6770       num2,
6771       num3
6772     )
6773     SELECT
6774       p_key,
6775       x_processing_row_tbl(i),
6776       txn_lines.po_line_id,
6777       txn_lines.line_num
6778     FROM  po_lines txn_lines
6779     WHERE x_lines.item_tbl(i) IS NOT NULL
6780     AND   txn_lines.po_header_id = x_lines.hd_po_header_id_tbl(i)
6781     AND   NOT EXISTS ( SELECT 1
6782                        FROM   po_lines_draft_all draft_lines
6783                        WHERE  draft_lines.po_line_id = txn_lines.po_line_id
6784                        AND    draft_lines.draft_id = x_lines.draft_id_tbl(i))
6785     AND   EXISTS (SELECT 1
6786                   FROM   mtl_system_items items
6787                   WHERE  items.inventory_item_id = txn_lines.item_id
6788                   AND    items.segment1 = x_lines.item_tbl(i)
6789                   AND    items.organization_id =
6790                            NVL(l_def_master_org_id, items.organization_id))
6791     AND   NVL(x_lines.item_revision_tbl(i), NVL(txn_lines.item_revision, -99)) =
6792             NVL(txn_lines.item_revision, -99)
6793     AND   NVL(x_lines.vendor_product_num_tbl(i), NVL(txn_lines.vendor_product_num, -99)) =
6794             NVL(txn_lines.vendor_product_num, -99)
6795     AND   NVL(x_lines.supplier_part_auxid_tbl(i),
6796               NVL(txn_lines.supplier_part_auxid, FND_API.g_NULL_CHAR)) =
6797           NVL(txn_lines.supplier_part_auxid, FND_API.g_NULL_CHAR)
6798     AND   NVL(txn_lines.expiration_date, TRUNC(sysdate)) >= TRUNC(sysdate)
6799     AND   NVL(txn_lines.closed_code, 'OPEN') <> 'FINALLY CLOSED'
6800     AND   NVL(txn_lines.cancel_flag, 'N') <> 'Y';
6801 
6802   d_position := 20;
6803 
6804   DELETE FROM po_session_gt
6805   WHERE key = p_key
6806   RETURNING num1, num2, num3 BULK COLLECT INTO
6807     l_index_tbl, l_po_line_id_tbl, l_line_num_tbl;
6808 
6809   -- set po_line_id, and line_num from matching record
6810   -- If there is only one matching -- OK
6811   -- If there are multiple matching records, update the line that has same
6812   -- line_num as in interface table; otherwise, update line with maximum
6813   -- line_num
6814   FOR i IN 1..l_index_tbl.COUNT
6815   LOOP
6816     l_index := l_index_tbl(i);
6817 
6818     IF (x_lines.po_line_id_tbl(l_index) IS NULL) THEN
6819       IF (PO_LOG.d_stmt) THEN
6820         PO_LOG.stmt(d_module, d_position, 'first match index', l_index);
6821         PO_LOG.stmt(d_module, d_position, 'po line id', l_po_line_id_tbl(i));
6822         PO_LOG.stmt(d_module, d_position, 'line num', l_line_num_tbl(i));
6823       END IF;
6824 
6825       -- first match found
6826       x_lines.origin_line_num_tbl(l_index) := x_lines.line_num_tbl(l_index);
6827       x_lines.action_tbl(l_index) := PO_PDOI_CONSTANTS.g_ACTION_UPDATE;
6828       x_lines.group_num_tbl(l_index) := p_group_num;
6829       x_lines.po_line_id_tbl(l_index) := l_po_line_id_tbl(i);
6830       x_lines.line_num_tbl(l_index) := l_line_num_tbl(i);
6831       x_processing_row_tbl.DELETE(l_index);
6832       IF (l_line_num_tbl(i) = x_lines.origin_line_num_tbl(l_index)) THEN
6833         x_lines.match_line_found_tbl(l_index) := FND_API.g_TRUE;
6834       END IF;
6835     ELSE
6836       IF (PO_LOG.d_stmt) THEN
6837         PO_LOG.stmt(d_module, d_position, 'multi match index', l_index);
6838         PO_LOG.stmt(d_module, d_position, 'po line id', l_po_line_id_tbl(i));
6839         PO_LOG.stmt(d_module, d_position, 'line num', l_line_num_tbl(i));
6840         PO_LOG.stmt(d_module, d_position, 'original line num',
6841                     x_lines.origin_line_num_tbl(l_index));
6842         PO_LOG.stmt(d_module, d_position, 'match line found',
6843                     x_lines.match_line_found_tbl(l_index));
6844         PO_LOG.stmt(d_module, d_position, 'current line num',
6845                     x_lines.line_num_tbl(l_index));
6846       END IF;
6847 
6848       -- multiple matches found
6849       IF (l_line_num_tbl(i) = x_lines.origin_line_num_tbl(l_index)) THEN
6850         -- record matching line_num is found
6851         x_lines.po_line_id_tbl(l_index) := l_po_line_id_tbl(i);
6852         x_lines.line_num_tbl(l_index) := l_line_num_tbl(i);
6853         x_lines.match_line_found_tbl(l_index) := FND_API.g_TRUE;
6854       ELSIF (x_lines.match_line_found_tbl(l_index) = FND_API.g_TRUE) THEN
6855         -- need to do nothing, record with matching line num is found before
6856         NULL;
6857       ELSIF (x_lines.line_num_tbl(l_index) < l_line_num_tbl(i)) THEN
6858         -- try to update line with maximum line num if exact match can not be found
6859         x_lines.po_line_id_tbl(l_index) := l_po_line_id_tbl(i);
6860         x_lines.line_num_tbl(l_index) := l_line_num_tbl(i);
6861       ELSE
6862         -- do nothing since the new coming record has smaller line num
6863         -- than current matching record
6864         NULL;
6865       END IF;
6866     END IF;
6867   END LOOP;
6868 
6869   d_position := 30;
6870 
6871   -- search within the batch
6872   -- find out all lines that cannot find a match
6873   -- and set their action to ADD
6874   l_data_key := PO_CORE_S.get_session_gt_nextval;
6875   FORALL i IN INDICES OF x_processing_row_tbl
6876     INSERT INTO po_session_gt
6877     (
6878       key,
6879       num1,
6880       num2,
6881       char1,
6882       char2,
6883       char3,
6884       char4
6885     )
6886   SELECT
6887     l_data_key,
6888     x_lines.intf_line_id_tbl(i),       -- num1
6889     x_lines.hd_po_header_id_tbl(i),    -- num2
6890     x_lines.item_tbl(i),               -- char1
6891     x_lines.item_revision_tbl(i),      -- char2
6892     x_lines.vendor_product_num_tbl(i), -- char3
6893     x_lines.supplier_part_auxid_tbl(i) -- char4
6894   FROM DUAL;
6895 
6896   d_position := 40;
6897 
6898   -- bug4930510
6899   -- Take away the table mtl_system_items from the query since it's
6900   -- never used.
6901   FORALL i IN INDICES OF x_processing_row_tbl
6902     INSERT INTO po_session_gt
6903     (
6904       key,
6905       num1
6906     )
6907     SELECT p_key,
6908            x_processing_row_tbl(i)
6909     FROM   DUAL
6910     WHERE  x_lines.item_tbl(i) IS NOT NULL
6911     AND    NOT EXISTS(
6912            SELECT 1
6913            FROM   po_session_gt gt
6914            WHERE  key = l_data_key
6915            AND    gt.num1 < x_lines.intf_line_id_tbl(i)
6916            AND    gt.num2 = x_lines.hd_po_header_id_tbl(i)
6917            AND    gt.char1 = x_lines.item_tbl(i)
6918            AND    NVL(x_lines.item_revision_tbl(i), NVL(gt.char2, -99)) =
6919                     NVL(gt.char2, -99)
6920            AND    NVL(x_lines.vendor_product_num_tbl(i), NVL(gt.char3, -99)) =
6921                     NVL(gt.char3, -99)
6922            AND    NVL(x_lines.supplier_part_auxid_tbl(i),
6923                       NVL(gt.char4, FND_API.g_NULL_CHAR))=
6924                   NVL(gt.char4, FND_API.g_NULL_CHAR));
6925 
6926   d_position := 50;
6927 
6928   DELETE FROM po_session_gt
6929   WHERE key = p_key
6930   RETURNING num1 BULK COLLECT INTO l_index_tbl;
6931 
6932   -- bug5093465
6933   -- For the records in l_index_tbl, assign action 'ADD'
6934   set_action_add
6935   ( p_key                    => p_key,
6936     p_group_num              => p_group_num,
6937     p_target_lines_index_tbl => l_index_tbl,
6938     p_check_line_num_assign  => FND_API.G_TRUE,
6939     x_processing_row_tbl     => x_processing_row_tbl,
6940     x_lines                  => x_lines
6941   );
6942 
6943   d_position := 60;
6944 
6945   -- clean up po_session_gt
6946   PO_PDOI_UTL.remove_session_gt_records
6947   ( p_key => l_data_key
6948   );
6949 
6950   IF (PO_LOG.d_proc) THEN
6951     PO_LOG.proc_end(d_module);
6952   END IF;
6953 
6954 EXCEPTION
6955   WHEN OTHERS THEN
6956     PO_MESSAGE_S.add_exc_msg
6957     (
6958       p_pkg_name => d_pkg_name,
6959       p_procedure_name => d_api_name || '.' || d_position
6960     );
6961     RAISE;
6962 END uniqueness_check_on_item;
6963 
6964 -----------------------------------------------------------------------
6965 --Start of Comments
6966 --Name: uniqueness_check_on_vpn
6967 --Function:
6968 --  check item uniqueness based on vendor_product_num + aux id
6969 --Parameters:
6970 --IN:
6971 --  p_key
6972 --    key value used to identify rows in temp table
6973 --  p_group_num
6974 --    the new group number that is going to be assigned to rows
6975 --    whose action can be decided in this procedure
6976 --IN OUT:
6977 --  x_processing_row_tbl
6978 --    index table of rows that are going to be processed
6979 --  x_lines
6980 --    record of line information read within the batch
6981 --OUT:
6982 --End of Comments
6983 ------------------------------------------------------------------------
6984 PROCEDURE uniqueness_check_on_vpn
6985 (
6986   p_key                 IN po_session_gt.key%TYPE,
6987   p_group_num           IN NUMBER,
6988   x_processing_row_tbl  IN OUT NOCOPY DBMS_SQL.NUMBER_TABLE,
6989   x_lines               IN OUT NOCOPY PO_PDOI_TYPES.lines_rec_type
6990 ) IS
6991 
6992   d_api_name CONSTANT VARCHAR2(30) := 'uniqueness_check_on_vpn';
6993   d_module   CONSTANT VARCHAR2(255) := d_pkg_name || d_api_name || '.';
6994   d_position NUMBER;
6995 
6996   -- variables to hold matching result read from po_session_gt table
6997   l_index_tbl           PO_TBL_NUMBER;
6998   l_po_line_id_tbl      PO_TBL_NUMBER;
6999   l_line_num_tbl        PO_TBL_NUMBER;
7000 
7001   l_index               NUMBER;
7002   l_data_key            po_session_gt.key%TYPE;
7003 
7004 BEGIN
7005   d_position := 0;
7006 
7007   IF (PO_LOG.d_proc) THEN
7008     PO_LOG.proc_begin(d_module);
7009   END IF;
7010 
7011   -- check matchings on draft table
7012   FORALL i IN INDICES OF x_processing_row_tbl
7013     INSERT INTO po_session_gt
7014     (
7015       key,
7016       num1,
7017       num2,
7018       num3
7019     )
7020     SELECT
7021       p_key,
7022       x_processing_row_tbl(i),
7023       draft_lines.po_line_id,
7024       draft_lines.line_num
7025     FROM  po_lines_draft_all draft_lines
7026     WHERE x_lines.item_tbl(i) IS NULL
7027     AND   x_lines.vendor_product_num_tbl(i) IS NOT NULL
7028     AND   draft_lines.po_header_id = x_lines.hd_po_header_id_tbl(i)
7029     AND   draft_lines.draft_id = x_lines.draft_id_tbl(i)
7030     AND   NVL(draft_lines.expiration_date, TRUNC(sysdate)) >= TRUNC(sysdate)
7031     AND   draft_lines.vendor_product_num = x_lines.vendor_product_num_tbl(i)
7032     AND   NVL(x_lines.supplier_part_auxid_tbl(i),
7033               NVL(draft_lines.supplier_part_auxid, FND_API.g_NULL_CHAR))=
7034           NVL(draft_lines.supplier_part_auxid, FND_API.g_NULL_CHAR);
7035 
7036   d_position := 10;
7037 
7038   -- check matching on txn table
7039   FORALL i IN INDICES OF x_processing_row_tbl
7040     INSERT INTO po_session_gt
7041     (
7042       key,
7043       num1,
7044       num2,
7045       num3
7046     )
7047     SELECT
7048       p_key,
7049       x_processing_row_tbl(i),
7050       txn_lines.po_line_id,
7051       txn_lines.line_num
7052     FROM  po_lines txn_lines
7053     WHERE x_lines.item_tbl(i) IS NULL
7054     AND   x_lines.vendor_product_num_tbl(i) IS NOT NULL
7055     AND   txn_lines.po_header_id = x_lines.hd_po_header_id_tbl(i)
7056     AND   NOT EXISTS ( SELECT 1
7057                        FROM   po_lines_draft_all draft_lines
7058                        WHERE  draft_lines.po_line_id = txn_lines.po_line_id
7059                        AND    draft_lines.draft_id = x_lines.draft_id_tbl(i))
7060     AND   txn_lines.vendor_product_num = x_lines.vendor_product_num_tbl(i)
7061     AND   NVL(x_lines.supplier_part_auxid_tbl(i),
7062               NVL(txn_lines.supplier_part_auxid, FND_API.g_NULL_CHAR))=
7063           NVL(txn_lines.supplier_part_auxid, FND_API.g_NULL_CHAR)
7064     AND   NVL(txn_lines.expiration_date, TRUNC(sysdate)) >= TRUNC(sysdate)
7065     AND   NVL(txn_lines.closed_code, 'OPEN') <> 'FINALLY CLOSED'
7066     AND   NVL(txn_lines.cancel_flag, 'N') <> 'Y';
7067 
7068   d_position := 20;
7069 
7070   DELETE FROM po_session_gt
7071   WHERE key = p_key
7072   RETURNING num1, num2, num3 BULK COLLECT INTO
7073     l_index_tbl, l_po_line_id_tbl, l_line_num_tbl;
7074 
7075   -- set po_line_id, and line_num from matching record
7076   -- If there is only one matching -- OK
7077   -- If there are multiple matching records, update the line that has same
7078   -- line_num as in interface table; otherwise, update line with maximum
7079   -- line_num
7080   FOR i IN 1..l_index_tbl.COUNT
7081   LOOP
7082     l_index := l_index_tbl(i);
7083 
7084     IF (x_lines.po_line_id_tbl(l_index) IS NULL) THEN
7085       IF (PO_LOG.d_stmt) THEN
7086         PO_LOG.stmt(d_module, d_position, 'first match index', l_index);
7087         PO_LOG.stmt(d_module, d_position, 'po line id', l_po_line_id_tbl(i));
7088         PO_LOG.stmt(d_module, d_position, 'line num', l_line_num_tbl(i));
7089       END IF;
7090 
7091       -- first match found
7092       x_lines.origin_line_num_tbl(l_index) := x_lines.line_num_tbl(l_index);
7093       x_lines.action_tbl(l_index) := PO_PDOI_CONSTANTS.g_ACTION_UPDATE;
7094       x_lines.group_num_tbl(l_index) := p_group_num;
7095       x_lines.po_line_id_tbl(l_index) := l_po_line_id_tbl(i);
7096       x_lines.line_num_tbl(l_index) := l_line_num_tbl(i);
7097       x_processing_row_tbl.DELETE(l_index);
7098       IF (l_line_num_tbl(i) = x_lines.origin_line_num_tbl(l_index)) THEN
7099         x_lines.match_line_found_tbl(l_index) := FND_API.g_TRUE;
7100       END IF;
7101     ELSE
7102       IF (PO_LOG.d_stmt) THEN
7103         PO_LOG.stmt(d_module, d_position, 'multi match index', l_index);
7104         PO_LOG.stmt(d_module, d_position, 'po line id', l_po_line_id_tbl(i));
7105         PO_LOG.stmt(d_module, d_position, 'line num', l_line_num_tbl(i));
7106         PO_LOG.stmt(d_module, d_position, 'original line num',
7107                     x_lines.origin_line_num_tbl(l_index));
7108         PO_LOG.stmt(d_module, d_position, 'match line found',
7109                     x_lines.match_line_found_tbl(l_index));
7110         PO_LOG.stmt(d_module, d_position, 'current line num',
7111                     x_lines.line_num_tbl(l_index));
7112       END IF;
7113 
7114       -- multiple matches found
7115       IF (l_line_num_tbl(i) = x_lines.origin_line_num_tbl(l_index)) THEN
7116         -- record matching line_num is found
7117         x_lines.po_line_id_tbl(l_index) := l_po_line_id_tbl(i);
7118         x_lines.line_num_tbl(l_index) := l_line_num_tbl(i);
7119         x_lines.match_line_found_tbl(l_index) := FND_API.g_TRUE;
7120       ELSIF (x_lines.match_line_found_tbl(l_index) = FND_API.g_TRUE) THEN
7121         -- need to do nothing, record with matching line num is found before
7122         NULL;
7123       ELSIF (x_lines.line_num_tbl(l_index) < l_line_num_tbl(i)) THEN
7124         -- try to update line with maximum line num if exact match can not be found
7125         x_lines.po_line_id_tbl(l_index) := l_po_line_id_tbl(i);
7126         x_lines.line_num_tbl(l_index) := l_line_num_tbl(i);
7127       ELSE
7128         -- do nothing since the new coming record has smaller line num
7129         -- than current matching record
7130         NULL;
7131       END IF;
7132     END IF;
7133   END LOOP;
7134 
7135   d_position := 30;
7136 
7137   -- search within the batch
7138   -- find out all lines that cannot find a match
7139   -- and set their action to ADD
7140   l_data_key := PO_CORE_S.get_session_gt_nextval;
7141   FORALL i IN INDICES OF x_processing_row_tbl
7142     INSERT INTO po_session_gt
7143     (
7144       key,
7145       num1,
7146       num2,
7147       char1,
7148       char2
7149     )
7150   SELECT
7151     l_data_key,
7152     x_lines.intf_line_id_tbl(i),       -- num1
7153     x_lines.hd_po_header_id_tbl(i),    -- num2
7154     x_lines.vendor_product_num_tbl(i), -- char1
7155     x_lines.supplier_part_auxid_tbl(i) -- char2
7156   FROM DUAL;
7157 
7158   d_position := 40;
7159 
7160   FORALL i IN INDICES OF x_processing_row_tbl
7161     INSERT INTO po_session_gt
7162     (
7163       key,
7164       num1
7165     )
7166     SELECT p_key,
7167            x_processing_row_tbl(i)
7168     FROM   DUAL
7169     WHERE  x_lines.item_tbl(i) IS NULL
7170     AND    x_lines.vendor_product_num_tbl(i) IS NOT NULL
7171     AND    NOT EXISTS(
7172            SELECT 1
7173            FROM   po_session_gt gt
7174            WHERE  key = l_data_key
7175            AND    gt.num1 < x_lines.intf_line_id_tbl(i)
7176            AND    gt.num2 = x_lines.hd_po_header_id_tbl(i)
7177            AND    gt.char1 = x_lines.vendor_product_num_tbl(i)
7178            AND    NVL(x_lines.supplier_part_auxid_tbl(i),
7179                       NVL(gt.char2, FND_API.g_NULL_CHAR))=
7180                   NVL(gt.char2, FND_API.g_NULL_CHAR));
7181 
7182   d_position := 50;
7183 
7184   DELETE FROM po_session_gt
7185   WHERE key = p_key
7186   RETURNING num1 BULK COLLECT INTO l_index_tbl;
7187 
7188   d_position := 60;
7189 
7190   -- bug5093465
7191   -- For the records in l_index_tbl, assign action 'ADD'
7192   set_action_add
7193   ( p_key                    => p_key,
7194     p_group_num              => p_group_num,
7195     p_target_lines_index_tbl => l_index_tbl,
7196     p_check_line_num_assign  => FND_API.G_TRUE,
7197     x_processing_row_tbl     => x_processing_row_tbl,
7198     x_lines                  => x_lines
7199   );
7200 
7201   d_position := 70;
7202 
7203   -- clean up po_session_gt
7204   PO_PDOI_UTL.remove_session_gt_records
7205   ( p_key => l_data_key
7206   );
7207 
7208   IF (PO_LOG.d_proc) THEN
7209     PO_LOG.proc_end(d_module);
7210   END IF;
7211 
7212 EXCEPTION
7213   WHEN OTHERS THEN
7214     PO_MESSAGE_S.add_exc_msg
7215     (
7216       p_pkg_name => d_pkg_name,
7217       p_procedure_name => d_api_name || '.' || d_position
7218     );
7219     RAISE;
7220 END uniqueness_check_on_vpn;
7221 
7222 -----------------------------------------------------------------------
7223 --Start of Comments
7224 --Name: uniqueness_check_on_job
7225 --Function:
7226 --  check item uniqueness based on job name
7227 --Parameters:
7228 --IN:
7229 --  p_key
7230 --    key value used to identify rows in temp table
7231 --  p_group_num
7232 --    the new group number that is going to be assigned to rows
7233 --    whose action can be decided in this procedure
7234 --IN OUT:
7235 --  x_processing_row_tbl
7236 --    index table of rows that are going to be processed
7237 --  x_lines
7238 --    record of line information read within the batch
7239 --OUT:
7240 --End of Comments
7241 ------------------------------------------------------------------------
7242 PROCEDURE uniqueness_check_on_job
7243 (
7244   p_key                 IN po_session_gt.key%TYPE,
7245   p_group_num           IN NUMBER,
7246   x_processing_row_tbl  IN OUT NOCOPY DBMS_SQL.NUMBER_TABLE,
7247   x_lines               IN OUT NOCOPY PO_PDOI_TYPES.lines_rec_type
7248 ) IS
7249 
7250   d_api_name CONSTANT VARCHAR2(30) := 'uniqueness_check_on_job';
7251   d_module   CONSTANT VARCHAR2(255) := d_pkg_name || d_api_name || '.';
7252   d_position NUMBER;
7253 
7254   -- variables to hold matching result read from po_session_gt table
7255   l_index_tbl           PO_TBL_NUMBER;
7256   l_po_line_id_tbl      PO_TBL_NUMBER;
7257   l_line_num_tbl        PO_TBL_NUMBER;
7258 
7259   l_index               NUMBER;
7260   l_data_key            po_session_gt.key%TYPE;
7261 
7262 BEGIN
7263   d_position := 0;
7264 
7265   IF (PO_LOG.d_proc) THEN
7266     PO_LOG.proc_begin(d_module);
7267   END IF;
7268 
7269   -- check matchings on draft table
7270   FORALL i IN INDICES OF x_processing_row_tbl
7271     INSERT INTO po_session_gt
7272     (
7273       key,
7274       num1,
7275       num2,
7276       num3
7277     )
7278     SELECT
7279       p_key,
7280       x_processing_row_tbl(i),
7281       draft_lines.po_line_id,
7282       draft_lines.line_num
7283     FROM  po_lines_draft_all draft_lines
7284     WHERE x_lines.item_tbl(i) IS NULL
7285     AND   x_lines.vendor_product_num_tbl(i) IS NULL
7286     AND   x_lines.job_name_tbl(i) IS NOT NULL
7287     AND   draft_lines.po_header_id = x_lines.hd_po_header_id_tbl(i)
7288     AND   draft_lines.draft_id = x_lines.draft_id_tbl(i)
7289     AND   NVL(draft_lines.expiration_date, TRUNC(sysdate)) >= TRUNC(sysdate)
7290     AND   EXISTS (SELECT 1
7291                   FROM   per_jobs_vl
7292                   WHERE  name = x_lines.job_name_tbl(i)
7293                   AND    job_id = draft_lines.job_id)
7294     AND   NVL(draft_lines.expiration_date, TRUNC(sysdate)) >= TRUNC(sysdate);
7295 
7296   d_position := 10;
7297 
7298   -- check matching on txn table
7299   FORALL i IN INDICES OF x_processing_row_tbl
7300     INSERT INTO po_session_gt
7301     (
7302       key,
7303       num1,
7304       num2,
7305       num3
7306     )
7307     SELECT
7308       p_key,
7309       x_processing_row_tbl(i),
7310       txn_lines.po_line_id,
7311       txn_lines.line_num
7312     FROM  po_lines txn_lines
7313     WHERE x_lines.item_tbl(i) IS NULL
7314     AND   x_lines.vendor_product_num_tbl(i) IS NULL
7315     AND   x_lines.job_name_tbl(i) IS NOT NULL
7316     AND   txn_lines.po_header_id = x_lines.hd_po_header_id_tbl(i)
7317     AND   NOT EXISTS ( SELECT 1
7318                        FROM   po_lines_draft_all draft_lines
7319                        WHERE  draft_lines.po_line_id = txn_lines.po_line_id
7320                        AND    draft_lines.draft_id = x_lines.draft_id_tbl(i))
7321     AND   EXISTS (SELECT 1
7322                   FROM   per_jobs_vl
7323                   WHERE  name = x_lines.job_name_tbl(i)
7324                   AND    job_id = txn_lines.job_id)
7325     AND   NVL(txn_lines.expiration_date, TRUNC(sysdate)) >= TRUNC(sysdate)
7326     AND   NVL(txn_lines.closed_code, 'OPEN') <> 'FINALLY CLOSED'
7327     AND   NVL(txn_lines.cancel_flag, 'N') <> 'Y';
7328 
7329   d_position := 20;
7330 
7331   DELETE FROM po_session_gt
7332   WHERE key = p_key
7333   RETURNING num1, num2, num3 BULK COLLECT INTO
7334     l_index_tbl, l_po_line_id_tbl, l_line_num_tbl;
7335 
7336   -- set po_line_id, and line_num from matching record
7337   -- If there is only one matching -- OK
7338   -- If there are multiple matching records, update the line that has same
7339   -- line_num as in interface table; otherwise, update line with maximum
7340   -- line_num
7341   FOR i IN 1..l_index_tbl.COUNT
7342   LOOP
7343     l_index := l_index_tbl(i);
7344 
7345     IF (x_lines.po_line_id_tbl(l_index) IS NULL) THEN
7346       IF (PO_LOG.d_stmt) THEN
7347         PO_LOG.stmt(d_module, d_position, 'first match index', l_index);
7348         PO_LOG.stmt(d_module, d_position, 'po line id', l_po_line_id_tbl(i));
7349         PO_LOG.stmt(d_module, d_position, 'line num', l_line_num_tbl(i));
7350       END IF;
7351 
7352       -- first match found
7353       x_lines.origin_line_num_tbl(l_index) := x_lines.line_num_tbl(l_index);
7354       x_lines.action_tbl(l_index) := PO_PDOI_CONSTANTS.g_ACTION_UPDATE;
7355       x_lines.group_num_tbl(l_index) := p_group_num;
7356       x_lines.po_line_id_tbl(l_index) := l_po_line_id_tbl(i);
7357       x_lines.line_num_tbl(l_index) := l_line_num_tbl(i);
7358       x_processing_row_tbl.DELETE(l_index);
7359       IF (l_line_num_tbl(i) = x_lines.origin_line_num_tbl(l_index)) THEN
7360         x_lines.match_line_found_tbl(l_index) := FND_API.g_TRUE;
7361       END IF;
7362     ELSE
7363       IF (PO_LOG.d_stmt) THEN
7364         PO_LOG.stmt(d_module, d_position, 'multi match index', l_index);
7365         PO_LOG.stmt(d_module, d_position, 'po line id', l_po_line_id_tbl(i));
7366         PO_LOG.stmt(d_module, d_position, 'line num', l_line_num_tbl(i));
7367         PO_LOG.stmt(d_module, d_position, 'original line num',
7368                     x_lines.origin_line_num_tbl(l_index));
7369         PO_LOG.stmt(d_module, d_position, 'match line found',
7370                     x_lines.match_line_found_tbl(l_index));
7371         PO_LOG.stmt(d_module, d_position, 'current line num',
7372                     x_lines.line_num_tbl(l_index));
7373       END IF;
7374 
7375       -- multiple matches found
7376       IF (l_line_num_tbl(i) = x_lines.origin_line_num_tbl(l_index)) THEN
7377         -- record matching line_num is found
7378         x_lines.po_line_id_tbl(l_index) := l_po_line_id_tbl(i);
7379         x_lines.line_num_tbl(l_index) := l_line_num_tbl(i);
7380         x_lines.match_line_found_tbl(l_index) := FND_API.g_TRUE;
7381       ELSIF (x_lines.match_line_found_tbl(l_index) = FND_API.g_TRUE) THEN
7382         -- need to do nothing, record with matching line num is found before
7383         NULL;
7384       ELSIF (x_lines.line_num_tbl(l_index) < l_line_num_tbl(i)) THEN
7385         -- try to update line with maximum line num if exact match can not be found
7386         x_lines.po_line_id_tbl(l_index) := l_po_line_id_tbl(i);
7387         x_lines.line_num_tbl(l_index) := l_line_num_tbl(i);
7388       ELSE
7389         -- do nothing since the new coming record has smaller line num
7390         -- than current matching record
7391         NULL;
7392       END IF;
7393     END IF;
7394   END LOOP;
7395 
7396   d_position := 30;
7397 
7398   -- search within the batch
7399   -- find out all lines that cannot find a match
7400   -- and set their action to ADD
7401   l_data_key := PO_CORE_S.get_session_gt_nextval;
7402   FORALL i IN INDICES OF x_processing_row_tbl
7403     INSERT INTO po_session_gt
7404     (
7405       key,
7406       num1,
7407       num2,
7408       char1
7409     )
7410   SELECT
7411     l_data_key,
7412     x_lines.intf_line_id_tbl(i),       -- num1
7413     x_lines.hd_po_header_id_tbl(i),    -- num2
7414     x_lines.job_name_tbl(i)            -- char1
7415   FROM DUAL;
7416 
7417   d_position := 40;
7418 
7419   FORALL i IN INDICES OF x_processing_row_tbl
7420     INSERT INTO po_session_gt
7421     (
7422       key,
7423       num1
7424     )
7425     SELECT p_key,
7426            x_processing_row_tbl(i)
7427     FROM   DUAL
7428     WHERE  x_lines.item_tbl(i) IS NULL
7429     AND    x_lines.vendor_product_num_tbl(i) IS NULL
7430     AND    x_lines.job_name_tbl(i) IS NOT NULL
7431     AND    NOT EXISTS(
7432            SELECT 1
7433            FROM   po_session_gt gt
7434            WHERE  key = l_data_key
7435            AND    gt.num1 < x_lines.intf_line_id_tbl(i)
7436            AND    gt.num2 = x_lines.hd_po_header_id_tbl(i)
7437            AND    gt.char1 = x_lines.job_name_tbl(i));
7438 
7439   d_position := 50;
7440 
7441   DELETE FROM po_session_gt
7442   WHERE key = p_key
7443   RETURNING num1 BULK COLLECT INTO l_index_tbl;
7444 
7445   -- bug5093465
7446   -- For the records in l_index_tbl, assign action 'ADD'
7447   set_action_add
7448   ( p_key                    => p_key,
7449     p_group_num              => p_group_num,
7450     p_target_lines_index_tbl => l_index_tbl,
7451     p_check_line_num_assign  => FND_API.G_TRUE,
7452     x_processing_row_tbl     => x_processing_row_tbl,
7453     x_lines                  => x_lines
7454   );
7455 
7456   d_position := 60;
7457 
7458   -- clean up po_session_gt
7459   PO_PDOI_UTL.remove_session_gt_records
7460   ( p_key => l_data_key
7461   );
7462 
7463   IF (PO_LOG.d_proc) THEN
7464     PO_LOG.proc_end(d_module);
7465   END IF;
7466 
7467 EXCEPTION
7468   WHEN OTHERS THEN
7469     PO_MESSAGE_S.add_exc_msg
7470     (
7471       p_pkg_name => d_pkg_name,
7472       p_procedure_name => d_api_name || '.' || d_position
7473     );
7474     RAISE;
7475 END uniqueness_check_on_job;
7476 
7477 -----------------------------------------------------------------------
7478 --Start of Comments
7479 --Name: uniqueness_check_on_line_num
7480 --Function:
7481 --  check item uniqueness based on line number
7482 --Parameters:
7483 --IN:
7484 --  p_key
7485 --    key value used to identify rows in temp table
7486 --  p_group_num
7487 --    the new group number that is going to be assigned to rows
7488 --    whose action can be decided in this procedure
7489 --IN OUT:
7490 --  x_processing_row_tbl
7491 --    index table of rows that are going to be processed
7492 --  x_lines
7493 --    record of line information read within the batch
7494 --OUT:
7495 --End of Comments
7496 ------------------------------------------------------------------------
7497 PROCEDURE uniqueness_check_on_line_num
7498 (
7499   p_key                 IN po_session_gt.key%TYPE,
7500   p_group_num           IN NUMBER,
7501   x_processing_row_tbl  IN OUT NOCOPY DBMS_SQL.NUMBER_TABLE,
7502   x_lines               IN OUT NOCOPY PO_PDOI_TYPES.lines_rec_type
7503 ) IS
7504 
7505   d_api_name CONSTANT VARCHAR2(30) := 'uniqueness_check_on_line_num';
7506   d_module   CONSTANT VARCHAR2(255) := d_pkg_name || d_api_name || '.';
7507   d_position NUMBER;
7508 
7509   -- variables to hold matching result read from po_session_gt table
7510   l_index_tbl           PO_TBL_NUMBER;
7511   l_po_line_id_tbl      PO_TBL_NUMBER;
7512   l_line_num_tbl        PO_TBL_NUMBER;
7513 
7514   l_index               NUMBER;
7515   l_data_key            po_session_gt.key%TYPE;
7516 
7517 BEGIN
7518   d_position := 0;
7519 
7520   IF (PO_LOG.d_proc) THEN
7521     PO_LOG.proc_begin(d_module);
7522   END IF;
7523 
7524   -- check matchings on draft table
7525   FORALL i IN INDICES OF x_processing_row_tbl
7526     INSERT INTO po_session_gt
7527     (
7528       key,
7529       num1,
7530       num2,
7531       num3
7532     )
7533     SELECT
7534       p_key,
7535       x_processing_row_tbl(i),
7536       draft_lines.po_line_id,
7537       draft_lines.line_num
7538     FROM  po_lines_draft_all draft_lines
7539     WHERE x_lines.item_tbl(i) IS NULL
7540     AND   x_lines.vendor_product_num_tbl(i) IS NULL
7541     AND   x_lines.job_name_tbl(i) IS NULL
7542     AND   x_lines.line_num_tbl(i) IS NOT NULL
7543     AND   draft_lines.po_header_id = x_lines.hd_po_header_id_tbl(i)
7544     AND   draft_lines.draft_id = x_lines.draft_id_tbl(i)
7545     AND   NVL(draft_lines.expiration_date, TRUNC(sysdate)) >= TRUNC(sysdate)
7546     AND   draft_lines.line_num = x_lines.line_num_tbl(i);
7547 
7548   d_position := 10;
7549 
7550   -- check matching on txn table
7551   FORALL i IN INDICES OF x_processing_row_tbl
7552     INSERT INTO po_session_gt
7553     (
7554       key,
7555       num1,
7556       num2,
7557       num3
7558     )
7559     SELECT
7560       p_key,
7561       x_processing_row_tbl(i),
7562       txn_lines.po_line_id,
7563       txn_lines.line_num
7564     FROM  po_lines txn_lines
7565     WHERE x_lines.item_tbl(i) IS NULL
7566     AND   x_lines.vendor_product_num_tbl(i) IS NULL
7567     AND   x_lines.job_name_tbl(i) IS NULL
7568     AND   x_lines.line_num_tbl(i) IS NOT NULL
7569     AND   txn_lines.po_header_id = x_lines.hd_po_header_id_tbl(i)
7570     AND   NOT EXISTS ( SELECT 1
7571                        FROM   po_lines_draft_all draft_lines
7572                        WHERE  draft_lines.po_line_id = txn_lines.po_line_id
7573                        AND    draft_lines.draft_id = x_lines.draft_id_tbl(i))
7574     AND   txn_lines.line_num = x_lines.line_num_tbl(i)
7575     AND   NVL(txn_lines.expiration_date, TRUNC(sysdate)) >= TRUNC(sysdate)
7576     AND   NVL(txn_lines.closed_code, 'OPEN') <> 'FINALLY CLOSED'
7577     AND   NVL(txn_lines.cancel_flag, 'N') <> 'Y';
7578 
7579   d_position := 20;
7580 
7581   DELETE FROM po_session_gt
7582   WHERE key = p_key
7583   RETURNING num1, num2, num3 BULK COLLECT INTO
7584     l_index_tbl, l_po_line_id_tbl, l_line_num_tbl;
7585 
7586   -- set po_line_id, and line_num from matching record
7587   -- There can be at most 1 matching record since we match on line num
7588   FOR i IN 1..l_index_tbl.COUNT
7589   LOOP
7590     l_index := l_index_tbl(i);
7591 
7592     x_lines.origin_line_num_tbl(l_index) := x_lines.line_num_tbl(l_index);
7593     x_lines.action_tbl(l_index) := PO_PDOI_CONSTANTS.g_ACTION_UPDATE;
7594     x_lines.group_num_tbl(l_index) := p_group_num;
7595     x_lines.po_line_id_tbl(l_index) := l_po_line_id_tbl(i);
7596     x_processing_row_tbl.DELETE(l_index);
7597 
7598     IF (PO_LOG.d_stmt) THEN
7599       PO_LOG.stmt(d_module, d_position, 'match index', l_index);
7600       PO_LOG.stmt(d_module, d_position, 'po line id', l_po_line_id_tbl(i));
7601       PO_LOG.stmt(d_module, d_position, 'current line num',
7602                   x_lines.line_num_tbl(l_index));
7603     END IF;
7604   END LOOP;
7605 
7606   d_position := 30;
7607 
7608   -- search within the batch
7609   -- find out all lines that cannot find a match
7610   -- and set their action to ADD
7611   l_data_key := PO_CORE_S.get_session_gt_nextval;
7612   FORALL i IN INDICES OF x_processing_row_tbl
7613     INSERT INTO po_session_gt
7614     (
7615       key,
7616       num1,
7617       num2,
7618       num3
7619     )
7620   SELECT
7621     l_data_key,
7622     x_lines.intf_line_id_tbl(i),       -- num1
7623     x_lines.hd_po_header_id_tbl(i),    -- num2
7624     x_lines.line_num_tbl(i)            -- num3
7625   FROM DUAL;
7626 
7627   d_position := 40;
7628 
7629   FORALL i IN INDICES OF x_processing_row_tbl
7630     INSERT INTO po_session_gt
7631     (
7632       key,
7633       num1
7634     )
7635     SELECT p_key,
7636            x_processing_row_tbl(i)
7637     FROM   DUAL
7638     WHERE  x_lines.item_tbl(i) IS NULL
7639     AND    x_lines.vendor_product_num_tbl(i) IS NULL
7640     AND    x_lines.job_name_tbl(i) IS NULL
7641     AND    x_lines.line_num_tbl(i) IS NOT NULL
7642     AND    NOT EXISTS(
7643            SELECT 1
7644            FROM   po_session_gt gt
7645            WHERE  key = l_data_key
7646            AND    gt.num1 < x_lines.intf_line_id_tbl(i)
7647            AND    gt.num2 = x_lines.hd_po_header_id_tbl(i)
7648            AND    gt.num3 = x_lines.line_num_tbl(i));
7649 
7650   d_position := 50;
7651 
7652   DELETE FROM po_session_gt
7653   WHERE key = p_key
7654   RETURNING num1 BULK COLLECT INTO l_index_tbl;
7655 
7656   -- bug5093465
7657   -- For the records in l_index_tbl, assign action 'ADD'
7658   set_action_add
7659   ( p_key                    => p_key,
7660     p_group_num              => p_group_num,
7661     p_target_lines_index_tbl => l_index_tbl,
7662     p_check_line_num_assign  => FND_API.G_FALSE,
7663     x_processing_row_tbl     => x_processing_row_tbl,
7664     x_lines                  => x_lines
7665   );
7666 
7667   d_position := 60;
7668 
7669   PO_PDOI_UTL.remove_session_gt_records
7670   ( p_key => l_data_key
7671   );
7672 
7673   IF (PO_LOG.d_proc) THEN
7674     PO_LOG.proc_end(d_module);
7675   END IF;
7676 
7677 EXCEPTION
7678   WHEN OTHERS THEN
7679     PO_MESSAGE_S.add_exc_msg
7680     (
7681       p_pkg_name => d_pkg_name,
7682       p_procedure_name => d_api_name || '.' || d_position
7683     );
7684     RAISE;
7685 END uniqueness_check_on_line_num;
7686 
7687 
7688 -- bug5093465 START
7689 -----------------------------------------------------------------------
7690 --Start of Comments
7691 --Name: set_action_add
7692 --Function:
7693 --  Assign ADD as the action for the line. If needed, assign new line number
7694 --  for the line
7695 --Parameters:
7696 --IN:
7697 --  p_key
7698 --    key value used to identify rows in temp table
7699 --  p_group_num
7700 --    the new group number that is going to be assigned to rows
7701 --    whose action can be decided in this procedure
7702 --  p_target_line_index_tbl
7703 --    Table containing indexes for the lines to be assigned with action
7704 --    'ADD'
7705 --  p_check_line_num_assign
7706 --    If FND_API.G_TRUE, then it checks whether a new line number needs
7707 --    to be assigned to the record. FND_API.G_FALSE otherwise.
7708 --IN OUT:
7709 --  x_processing_row_tbl
7710 --    index table of rows that are going to be processed
7711 --  x_lines
7712 --    record of line information read within the batch
7713 --OUT:
7714 --End of Comments
7715 ------------------------------------------------------------------------
7716 
7717 PROCEDURE set_action_add
7718 (
7719   p_key                   IN po_session_gt.key%TYPE,
7720   p_group_num             IN NUMBER,
7721   p_target_lines_index_tbl IN PO_TBL_NUMBER,
7722   p_check_line_num_assign IN VARCHAR2,
7723   x_processing_row_tbl    IN OUT NOCOPY DBMS_SQL.NUMBER_TABLE,
7724   x_lines                 IN OUT NOCOPY PO_PDOI_TYPES.lines_rec_type
7725 ) IS
7726 
7727 
7728 d_api_name CONSTANT VARCHAR2(30) := 'set_action_add';
7729 d_module   CONSTANT VARCHAR2(255) := d_pkg_name || d_api_name || '.';
7730 d_position NUMBER;
7731 
7732 l_index NUMBER;
7733 BEGIN
7734   d_position := 0;
7735 
7736   IF (PO_LOG.d_proc) THEN
7737     PO_LOG.proc_begin(d_module);
7738   END IF;
7739 
7740   -- mark all lines as to be created
7741   FOR i IN 1..p_target_lines_index_tbl.COUNT
7742   LOOP
7743 
7744     d_position := 10;
7745     l_index := p_target_lines_index_tbl(i);
7746 
7747     x_lines.action_tbl(l_index) := PO_PDOI_CONSTANTS.g_ACTION_ADD;
7748     x_lines.group_num_tbl(l_index) := p_group_num;
7749     x_lines.po_line_id_tbl(l_index) := PO_PDOI_MAINPROC_UTL_PVT.get_next_po_line_id;
7750 
7751     IF (p_check_line_num_assign = FND_API.G_TRUE) THEN
7752 
7753 
7754       IF (x_lines.line_num_tbl(l_index) IS NULL OR
7755           x_lines.line_num_unique_tbl(l_index) = FND_API.g_FALSE) THEN
7756 
7757         d_position := 20;
7758 
7759         x_lines.line_num_tbl(l_index) :=
7760           PO_PDOI_MAINPROC_UTL_PVT.get_next_line_num
7761           (
7762             p_po_header_id => x_lines.hd_po_header_id_tbl(l_index)
7763           );
7764 
7765         IF (PO_LOG.d_stmt) THEN
7766           PO_LOG.stmt(d_module, d_position, 'assign new line num', x_lines.line_num_tbl(l_index));
7767         END IF;
7768 
7769       END IF;
7770 
7771     END IF;
7772 
7773     d_position := 30;
7774 
7775     -- action is determined. No longer need to process it
7776     x_processing_row_tbl.DELETE(l_index);
7777 
7778     IF (PO_LOG.d_stmt) THEN
7779       PO_LOG.stmt(d_module, d_position, 'match index', l_index);
7780       PO_LOG.stmt(d_module, d_position, 'po line id',
7781                   x_lines.po_line_id_tbl(l_index));
7782     END IF;
7783 
7784   END LOOP;
7785 
7786   IF (PO_LOG.d_proc) THEN
7787     PO_LOG.proc_end(d_module);
7788   END IF;
7789 
7790 EXCEPTION
7791   WHEN OTHERS THEN
7792     PO_MESSAGE_S.add_exc_msg
7793     (
7794       p_pkg_name => d_pkg_name,
7795       p_procedure_name => d_api_name || '.' || d_position
7796     );
7797     RAISE;
7798 END set_action_add;
7799 
7800 -- bug5093465 END
7801 
7802 
7803 
7804 -----------------------------------------------------------------------
7805 --Start of Comments
7806 --Name: validate_attr_tlp
7807 --Function:
7808 --  validate whether there is a line with creation language existing
7809 --  in po_attr_values_tlp_interface table; If rows with creation lang
7810 --  does not exist but rows in other langs exist, insert error in
7811 --  error interface table
7812 --  The procedure is called only when line action = 'CREATE'
7813 --Parameters:
7814 --IN:
7815 --IN OUT:
7816 --  x_lines
7817 --    record of line information read within the batch
7818 --OUT:
7819 --End of Comments
7820 ------------------------------------------------------------------------
7821 PROCEDURE validate_attr_tlp
7822 (
7823   x_lines IN OUT NOCOPY PO_PDOI_TYPES.lines_rec_type
7824 ) IS
7825 
7826   d_api_name CONSTANT VARCHAR2(30) := 'validate_attr_tlp';
7827   d_module   CONSTANT VARCHAR2(255) := d_pkg_name || d_api_name || '.';
7828   d_position NUMBER;
7829 
7830   l_key po_session_gt.key%TYPE;
7831 
7832   -- table used to save the index of the each row
7833   l_index_tbl DBMS_SQL.NUMBER_TABLE;
7834   l_index     NUMBER;
7835 BEGIN
7836   d_position := 0;
7837 
7838   IF (PO_LOG.d_proc) THEN
7839     PO_LOG.proc_begin(d_module);
7840   END IF;
7841 
7842   -- assign a new key used in temporary table
7843   l_key := PO_CORE_S.get_session_gt_nextval;
7844 
7845   -- initialize table containing the row number(index)
7846   PO_PDOI_UTL.generate_ordered_num_list
7847   (
7848     p_size     => x_lines.rec_count,
7849     x_num_list => l_index_tbl
7850   );
7851 
7852   FORALL i IN 1..x_lines.rec_count
7853     INSERT INTO po_session_gt
7854     (
7855       key,
7856       num1
7857     )
7858     SELECT
7859       l_key,
7860       l_index_tbl(i)
7861     FROM   DUAL
7862     WHERE  NOT EXISTS
7863            (
7864              SELECT 1
7865              FROM   po_attr_values_tlp_interface
7866              WHERE  interface_line_id = x_lines.intf_line_id_tbl(i)
7867              AND    language = x_lines.hd_created_language_tbl(i)
7868            )
7869     AND    EXISTS
7870            (
7871              SELECT 1
7872              FROM   po_attr_values_tlp_interface
7873              WHERE  interface_line_id = x_lines.intf_line_id_tbl(i)
7874              AND    language <> x_lines.hd_created_language_tbl(i)
7875            );
7876 
7877   d_position := 10;
7878 
7879   DELETE FROM po_session_gt
7880   WHERE key = l_key
7881   RETURNING num1 BULK COLLECT INTO l_index_tbl;
7882 
7883   d_position := 20;
7884 
7885   FOR i IN 1..l_index_tbl.COUNT
7886   LOOP
7887     l_index := l_index_tbl(i);
7888 
7889     IF (PO_LOG.d_stmt) THEN
7890       PO_LOG.stmt(d_module, d_position, 'error on index', l_index);
7891     END IF;
7892 
7893     PO_PDOI_ERR_UTL.add_fatal_error
7894     (
7895       p_interface_header_id  => x_lines.intf_header_id_tbl(l_index),
7896       p_interface_line_id    => x_lines.intf_line_id_tbl(l_index),
7897       p_error_message_name   => 'PO_PDOI_NO_TLP_IN_CREATE_LANG',
7898       p_table_name           => 'PO_LINES_INTERFACE',
7899       p_column_name          => NULL,
7900       p_column_value         => NULL,
7901       p_validation_id        => PO_VAL_CONSTANTS.c_language,
7902       p_lines                => x_lines
7903     );
7904 
7905     x_lines.error_flag_tbl(l_index) := FND_API.g_TRUE;
7906   END LOOP;
7907 
7908   IF (PO_LOG.d_proc) THEN
7909     PO_LOG.proc_end(d_module);
7910   END IF;
7911 
7912 EXCEPTION
7913   WHEN OTHERS THEN
7914     PO_MESSAGE_S.add_exc_msg
7915     (
7916       p_pkg_name => d_pkg_name,
7917       p_procedure_name => d_api_name || '.' || d_position
7918     );
7919     RAISE;
7920 END validate_attr_tlp;
7921 
7922 -----------------------------------------------------------------------
7923 --Start of Comments
7924 --Name: populate_error_flag
7925 --Function:
7926 --  corresponding value in error_flag_tbl will be set with value FND_API.G_FALSE.
7927 --Parameters:
7928 --IN:
7929 --x_results
7930 --  The validation results that contains the errored line information.
7931 --IN OUT:
7932 --x_lines
7933 --  The record contains the values to be validated.
7934 --  If there is error(s) on any attribute of the price differential row,
7935 --  corresponding value in error_flag_tbl will be set with value
7936 --  FND_API.G_FALSE.
7937 --OUT:
7938 --End of Comments
7939 ------------------------------------------------------------------------
7940 PROCEDURE populate_error_flag
7941 (
7942   x_results           IN     po_validation_results_type,
7943   x_lines             IN OUT NOCOPY PO_PDOI_TYPES.lines_rec_type
7944 ) IS
7945 
7946   d_api_name CONSTANT VARCHAR2(30) := 'populate_error_flag';
7947   d_module   CONSTANT VARCHAR2(255) := d_pkg_name || d_api_name || '.';
7948   d_position NUMBER;
7949 
7950   l_index_tbl DBMS_SQL.number_table;
7951 
7952 BEGIN
7953   d_position := 0;
7954 
7955   IF (PO_LOG.d_proc) THEN
7956     PO_LOG.proc_begin(d_module);
7957   END IF;
7958 
7959   d_position := 10;
7960 
7961   FOR i IN 1 .. x_lines.intf_line_id_tbl.COUNT LOOP
7962       l_index_tbl(x_lines.intf_line_id_tbl(i)) := i;
7963   END LOOP;
7964 
7965   d_position := 20;
7966 
7967   FOR i IN 1 .. x_results.entity_id.COUNT LOOP
7968      IF x_results.result_type(i) = po_validations.c_result_type_failure THEN
7969         IF (PO_LOG.d_stmt) THEN
7970           PO_LOG.stmt(d_module, d_position, 'error on index',
7971                       l_index_tbl(x_results.entity_id(i)));
7972         END IF;
7973 
7974         x_lines.error_flag_tbl(l_index_tbl(x_results.entity_id(i))) := FND_API.g_TRUE;
7975      END IF;
7976   END LOOP;
7977 
7978   IF (PO_LOG.d_proc) THEN
7979     PO_LOG.proc_end(d_module);
7980   END IF;
7981 
7982 EXCEPTION
7983   WHEN OTHERS THEN
7984     PO_MESSAGE_S.add_exc_msg
7985     (
7986       p_pkg_name => d_pkg_name,
7987       p_procedure_name => d_api_name || '.' || d_position
7988     );
7989     RAISE;
7990 END populate_error_flag;
7991 
7992 -----------------------------------------------------------------------
7993 --Start of Comments
7994 --Name: handle_err_tolerance
7995 --Function:  This procedure maintains line processing information for each
7996 --           document. It also handles the error tolerance for Catalog Upload.
7997 --           Update PO_PDOI_PARAMS.g_docs_info(intf_header_id).number_of_processed_lines
7998 --           for each line.
7999 --
8000 --           If line contains error, increment
8001 --           PO_PDOI_PARAMS.g_docs_info(intf_header_id).number_of_errored_lines
8002 --
8003 --           If the number of errored lines exceeds the error tolerance, then set
8004 --           PO_PDOI_PARAMS.g_docs_info(intf_header_id).err_tolerance_exceeded to TRUE and
8005 --           set x_lines.need_to_reject_flag_tbl to TRUE.
8006 --
8007 --           If the line does not have error, increment
8008 --           PO_PDOI_PARAMS.g_docs_info(intf_header_id).number_of_valid_lines
8009 --Parameters:
8010 --IN OUT:
8011 --  x_lines
8012 --    record which stores all the line rows within the batch;
8013 --OUT:
8014 --End of Comments
8015 ------------------------------------------------------------------------
8016 PROCEDURE handle_err_tolerance
8017 (
8018   x_lines       IN OUT NOCOPY PO_PDOI_TYPES.lines_rec_type
8019 ) IS
8020 
8021   d_api_name CONSTANT VARCHAR2(30) := 'handle_err_tolerance';
8022   d_module   CONSTANT VARCHAR2(255) := d_pkg_name || d_api_name || '.';
8023   d_position NUMBER;
8024 
8025   l_err_lines_tolerance  NUMBER := PO_PDOI_PARAMS.g_request.err_lines_tolerance;
8026   l_intf_header_id       NUMBER;
8027   l_num_errored_lines    NUMBER;
8028   l_num_processed_lines  NUMBER;
8029   l_num_valid_lines      NUMBER;
8030   l_remove_err_line_tbl  PO_TBL_NUMBER := PO_TBL_NUMBER();
8031 
8032 BEGIN
8033 
8034   d_position := 0;
8035 
8036   IF (PO_LOG.d_proc) THEN
8037     PO_LOG.proc_begin(d_module, 'err_lines_tolerance', l_err_lines_tolerance);
8038   END IF;
8039 
8040   FOR i IN 1 .. x_lines.rec_count
8041   LOOP
8042     l_intf_header_id := x_lines.intf_header_id_tbl(i);
8043 
8044     IF (PO_LOG.d_stmt) THEN
8045       PO_LOG.stmt(d_module, d_position, 'index', i);
8046       PO_LOG.stmt(d_module, d_position, 'intf header id', l_intf_header_id);
8047     END IF;
8048 
8049     d_position := 10;
8050 
8051     IF (PO_PDOI_PARAMS.g_request.calling_module = PO_PDOI_CONSTANTS.g_call_mod_CATALOG_UPLOAD AND
8052         PO_PDOI_PARAMS.g_docs_info(l_intf_header_id).err_tolerance_exceeded = FND_API.G_TRUE ) THEN
8053        x_lines.need_to_reject_flag_tbl(i) := FND_API.g_TRUE;
8054 
8055        -- bug 5215781:
8056        -- collect ids of lines for which errors on them would be removed from error interface
8057        -- table since error tolerance threshold is hit before them
8058        l_remove_err_line_tbl.EXTEND;
8059        l_remove_err_line_tbl(l_remove_err_line_tbl.COUNT) := x_lines.intf_line_id_tbl(i);
8060     ELSE
8061       l_num_processed_lines := PO_PDOI_PARAMS.g_docs_info(l_intf_header_id).number_of_processed_lines + 1;
8062       PO_PDOI_PARAMS.g_docs_info(l_intf_header_id).number_of_processed_lines := l_num_processed_lines;
8063 
8064       IF (PO_LOG.d_stmt) THEN
8065        PO_LOG.stmt(d_module, d_position, 'num_processed_lines', l_num_processed_lines);
8066       END IF;
8067 
8068       d_position := 20;
8069 
8070       IF x_lines.error_flag_tbl(i) = FND_API.g_TRUE THEN
8071         l_num_errored_lines := PO_PDOI_PARAMS.g_docs_info(l_intf_header_id).number_of_errored_lines + 1;
8072         PO_PDOI_PARAMS.g_docs_info(l_intf_header_id).number_of_errored_lines := l_num_errored_lines;
8073 
8074         -- set corresponding line to ERROR
8075         PO_PDOI_PARAMS.g_errored_lines(x_lines.intf_line_id_tbl(i)) := 'Y';
8076 
8077         IF (PO_LOG.d_stmt) THEN
8078           PO_LOG.stmt(d_module, d_position, 'num_errored_lines', l_num_errored_lines);
8079         END IF;
8080 
8081         d_position := 30;
8082 
8083         IF (PO_PDOI_PARAMS.g_request.calling_module =
8084               PO_PDOI_CONSTANTS.g_call_mod_CATALOG_UPLOAD AND
8085             l_num_errored_lines = l_err_lines_tolerance) THEN
8086 
8087            PO_PDOI_PARAMS.g_docs_info(l_intf_header_id).err_tolerance_exceeded := FND_API.g_TRUE;
8088         END IF;
8089 
8090         d_position := 40;
8091       ELSE
8092         d_position := 50;
8093 
8094         -- maintain number of valid lines
8095         l_num_valid_lines := PO_PDOI_PARAMS.g_docs_info(l_intf_header_id).number_of_valid_lines + 1;
8096         PO_PDOI_PARAMS.g_docs_info(l_intf_header_id).number_of_valid_lines := l_num_valid_lines;
8097 
8098       END IF;
8099     END IF;
8100   END LOOP;
8101 
8102   d_position := 60;
8103 
8104   -- Bug 5215781:
8105   -- remove the errors for lines from po_interface_errors if those lines are supposed to be processed
8106   -- after the line where we hit the error tolerance; That means, we want to rollback the changes if
8107   -- error tolerance is reached at some point
8108   PO_INTERFACE_ERRORS_UTL.flush_errors_tbl;
8109 
8110   FORALL i IN 1..l_remove_err_line_tbl.COUNT
8111     DELETE FROM PO_INTERFACE_ERRORS
8112     WHERE interface_line_id = l_remove_err_line_tbl(i);
8113 
8114   d_position := 70;
8115 
8116   IF (PO_LOG.d_proc) THEN
8117     PO_LOG.proc_end(d_module, 'num_processed_lines', l_num_processed_lines);
8118     PO_LOG.proc_end(d_module, 'num_errored_lines', l_num_errored_lines);
8119   END IF;
8120 
8121 EXCEPTION
8122   WHEN OTHERS THEN
8123     PO_MESSAGE_S.add_exc_msg
8124     (
8125       p_pkg_name => d_pkg_name,
8126       p_procedure_name => d_api_name || '.' || d_position
8127     );
8128     RAISE;
8129 END handle_err_tolerance;
8130 
8131 END PO_PDOI_LINE_PROCESS_PVT;