1 PACKAGE BODY po_pdoi_mainproc_pvt AS
2 /* $Header: PO_PDOI_MAINPROC_PVT.plb 120.22.12020000.5 2013/05/09 10:00:31 vlalwani ship $ */
3
4 d_pkg_name CONSTANT VARCHAR2(50) :=
5 PO_LOG.get_package_base('PO_PDOI_MAINPROC_PVT');
6
7 g_snap_shot_too_old EXCEPTION;
8 PRAGMA EXCEPTION_INIT(g_snap_shot_too_old, -1555);
9
10 --------------------------------------------------------------------------
11 ---------------------- PRIVATE PROCEDURES PROTOTYPE ----------------------
12 --------------------------------------------------------------------------
13 PROCEDURE process_headers;
14
15 PROCEDURE process_lines;
16
17 PROCEDURE process_lines_add
18 (
19 p_data_set_type IN NUMBER -- choice on data set to be processed
20 );
21
22 PROCEDURE process_lines_sync
23 (
24 p_data_set_type IN NUMBER -- choice on data set to be processed
25 );
26
27 PROCEDURE process_create_lines_in_group
28 (
29 p_group_num IN NUMBER,
30 p_expire_line_id_tbl IN DBMS_SQL.NUMBER_TABLE,
31 x_lines IN OUT NOCOPY PO_PDOI_TYPES.lines_rec_type
32 );
33
34 PROCEDURE process_update_lines_in_group
35 (
36 p_group_num IN NUMBER,
37 x_lines IN OUT NOCOPY PO_PDOI_TYPES.lines_rec_type
38 );
39
40 PROCEDURE process_line_locations;
41
42 PROCEDURE process_distributions;
43
44 PROCEDURE process_price_diffs;
45
46 PROCEDURE process_attributes;
47
48 PROCEDURE process_attr_values;
49
50 PROCEDURE process_attr_values_tlp;
51
52 --Bug 13343886
53 PROCEDURE gather_stats(p_table_name IN VARCHAR2,p_api_name IN VARCHAR2,p_position IN VARCHAR2);
54 --Bug 13343886
55
56 --PDOI CLM Integration Start
57 PROCEDURE process_info_lines
58 (
59 p_data_set_type IN number
60 );
61
62 PROCEDURE set_clm_structure;
63
64 PROCEDURE set_intf_base_line_num_to_dft;
65 --PDOI CLM Integration End
66 --------------------------------------------------------------------------
67 ---------------------- PUBLIC PROCEDURES ---------------------------------
68 --------------------------------------------------------------------------
69
70 --------------------------------------------------------------------------
71 --Start of Comments
72 --Name: process
73 --Pre-reqs: None
74 --Modifies:
75 --Locks:
76 -- None
77 --Function:
78 -- perform derive, default, validate and insert/update logic on all records
79 -- in interface tables
80 --Parameters:
81 --IN: None
82 --IN OUT: None
83 --OUT: None
84 --Returns: None
85 --Notes:
86 --Testing:
87 --End of Comments
88 --------------------------------------------------------------------------
89 PROCEDURE process IS
90
91 d_api_name CONSTANT VARCHAR2(30) := 'process';
92 d_module CONSTANT VARCHAR2(255) := d_pkg_name || d_api_name || '.';
93 d_position NUMBER;
94
95 BEGIN
96 d_position := 0;
97
98 IF (PO_LOG.d_proc) THEN
99 PO_LOG.proc_begin(d_module, 'start main process for header group',
100 PO_PDOI_PARAMS.g_current_round_num);
101 END IF;
102
103 PO_TIMING_UTL.start_time(PO_PDOI_CONSTANTS.g_T_MAIN_PROCESSING);
104
105 -- clean up cache before each group processing
106 PO_PDOI_MAINPROC_UTL_PVT.cleanup;
107
108 d_position := 10;
109
110 -- process each entity from upper to lower level
111 process_headers;
112
113 d_position := 10;
114
115 process_lines;
116
117 d_position := 20;
118
119 IF (PO_PDOI_PARAMS.g_request.document_type IN
120 (PO_PDOI_CONSTANTS.g_DOC_TYPE_BLANKET, PO_PDOI_CONSTANTS.g_DOC_TYPE_QUOTATION)) THEN
121 process_attributes;
122 END IF;
123
124 d_position := 30;
125
126 process_line_locations;
127
128 d_position := 40;
129
130 IF (PO_PDOI_PARAMS.g_request.document_type =
131 PO_PDOI_CONSTANTS.g_DOC_TYPE_STANDARD) THEN
132 process_distributions;
133 END IF;
134
135 d_position := 50;
136
137 process_price_diffs;
138
139 d_position := 60;
140
141 -- Bug 5215781:
142 -- Remove all unprocessed records if error threshold is hit for CATALOG UPLOAD
143 IF (PO_PDOI_PARAMS.g_request.calling_module =
144 PO_PDOI_CONSTANTS.g_CALL_MOD_CATALOG_UPLOAD AND
145 PO_PDOI_PARAMS.g_docs_info(PO_PDOI_PARAMS.g_request.interface_header_id)
146 .err_tolerance_exceeded = FND_API.g_TRUE) THEN
147 IF (PO_LOG.d_stmt) THEN
148 PO_LOG.stmt(d_module, d_position, 'Unprocessed records will be removed for header ',
149 PO_PDOI_PARAMS.g_request.interface_header_id);
150 END IF;
151
152 PO_PDOI_UTL.reject_unprocessed_intf
153 (
154 p_intf_header_id => PO_PDOI_PARAMS.g_request.interface_header_id
155 );
156 END IF;
157
158 PO_TIMING_UTL.stop_time(PO_PDOI_CONSTANTS.g_T_MAIN_PROCESSING);
159
160 IF (PO_LOG.d_proc) THEN
161 PO_LOG.proc_end(d_module);
162 END IF;
163
164 EXCEPTION
165 WHEN OTHERS THEN
166 PO_MESSAGE_S.add_exc_msg
167 (
168 p_pkg_name => d_pkg_name,
169 p_procedure_name => d_api_name || '.' || d_position
170 );
171 RAISE;
172 END process;
173
174 -------------------------------------------------------------------------
175 --------------------- PRIVATE PROCEDURES --------------------------------
176 -------------------------------------------------------------------------
177
178 -------------------------------------------------------------------------
179 --Start of Comments
180 --Name: process_headers
181 --Pre-reqs: None
182 --Modifies:
183 --Locks:
184 -- None
185 --Function:
186 -- handle the logic to derive, default, validate and insert records
187 -- from po_headers_interface table
188 --Parameters:
189 --IN: None
190 --IN OUT: None
191 --OUT: None
192 --Returns:
193 --Notes:
194 --Testing:
195 --End of Comments
196 ------------------------------------------------------------------------
197 PROCEDURE process_headers IS
198
199 d_api_name CONSTANT VARCHAR2(30) := 'process_headers';
200 d_module CONSTANT VARCHAR2(255) := d_pkg_name || d_api_name || '.';
201 d_position NUMBER;
202
203 -- cursor variable to point to currently processing row
204 l_headers_csr PO_PDOI_TYPES.intf_cursor_type;
205
206 -- all header attribute values within a batch
207 l_headers PO_PDOI_TYPES.headers_rec_type;
208
209 -- variable to track the largest intf_header_id processed so far
210 l_max_intf_header_id NUMBER := -1;
211
212 -- variables to track the records that need to be rejected due
213 -- to errors in the processing
214 l_count NUMBER := 0;
215 l_rej_intf_header_id_tbl PO_TBL_NUMBER := PO_TBL_NUMBER();
216
217 --Bug 16730873
218 l_delete_tbl PO_TBL_VARCHAR1 := PO_TBL_VARCHAR1();
219 l_record_already_exist_tbl PO_TBL_VARCHAR1 := PO_TBL_VARCHAR1();
220 l_cat_upload_head_exists BOOLEAN;
221
222 BEGIN
223 d_position := 0;
224
225 IF (PO_LOG.d_proc) THEN
226 PO_LOG.proc_begin(d_module);
227 END IF;
228
229 PO_TIMING_UTL.start_time(PO_PDOI_CONSTANTS.g_T_HEADER_PROCESS);
230
231 -- open cursor for the query which retrieve the header info
232 PO_PDOI_HEADER_PROCESS_PVT.open_headers
233 (
234 p_max_intf_header_id => l_max_intf_header_id,
235 x_headers_csr => l_headers_csr
236 );
237
238 d_position := 10;
239
240 -- fetch records from header interface table and process the records
241 LOOP
242 BEGIN
243 -- fetch one batch of header records from query result
244 PO_PDOI_HEADER_PROCESS_PVT.fetch_headers
245 (
246 x_headers_csr => l_headers_csr,
247 x_headers => l_headers
248 );
249
250 d_position := 20;
251
252 -- number of records read in current batch
253 l_headers.rec_count := l_headers.intf_header_id_tbl.COUNT;
254
255 IF (PO_LOG.d_stmt) THEN
256 PO_LOG.stmt(d_module, d_position, 'header count within batch',
257 l_headers.rec_count);
258 END IF;
259
260 EXIT WHEN l_headers.rec_count = 0;
261
262 -- set up hashtable between interface_header_id and index
263 l_headers.intf_id_index_tbl.DELETE;
264
265 FOR i IN 1..l_headers.rec_count
266 LOOP
267 l_headers.intf_id_index_tbl(l_headers.intf_header_id_tbl(i)) := i;
268 END LOOP;
269
270 -- derive logic
271 PO_PDOI_HEADER_PROCESS_PVT.derive_headers
272 (
273 x_headers => l_headers
274 );
275
276 d_position := 30;
277
278 -- default logic
279 PO_PDOI_HEADER_PROCESS_PVT.default_headers
280 (
281 x_headers => l_headers
282 );
283
284 d_position := 40;
285
286 -- validate logic
287 PO_PDOI_HEADER_PROCESS_PVT.validate_headers
288 (
289 x_headers => l_headers
290 );
291
292 d_position := 50;
293
294 -- insert valid header records into draft tables
295 PO_PDOI_MOVE_TO_DRAFT_TABS_PVT.insert_headers
296 (
297 p_headers => l_headers
298 );
299
300 d_position := 60;
301
302 -- Rejected header records with errors
303 l_rej_intf_header_id_tbl.EXTEND(l_headers.rec_count);
304 FOR i IN 1..l_headers.rec_count
305 LOOP
306 IF (l_headers.error_flag_tbl(i) = FND_API.g_TRUE) THEN
307 IF (PO_LOG.d_stmt) THEN
308 PO_LOG.stmt(d_module, d_position, 'rejected intf header id',
309 l_headers.intf_header_id_tbl(i));
310 END IF;
311
312 l_count := l_count + 1;
313 l_rej_intf_header_id_tbl(l_count) := l_headers.intf_header_id_tbl(i);
314 END IF;
315 END LOOP;
316 PO_PDOI_UTL.reject_headers_intf
317 (
318 p_id_param_type => PO_PDOI_CONSTANTS.g_INTERFACE_HEADER_ID,
319 p_id_tbl => l_rej_intf_header_id_tbl,
320 p_cascade => FND_API.g_TRUE
321 );
322 l_rej_intf_header_id_tbl.DELETE;
323
324 d_position := 70;
325
326 -- conditional commit
327 PO_PDOI_UTL.commit_work;
328
329 -- set maximal intf_header_id read so far(used in next batch read)
330 l_max_intf_header_id := l_headers.intf_header_id_tbl(l_headers.rec_count);
331
332 -- exit if this is the last batch
333 IF (l_headers.rec_count < PO_PDOI_CONSTANTS.g_DEF_BATCH_SIZE) THEN
334 EXIT;
335 END IF;
336 EXCEPTION
337 WHEN g_snap_shot_too_old THEN
338 d_position := 80;
339
340 PO_MESSAGE_S.add_exc_msg
341 (
342 p_pkg_name => d_pkg_name,
343 p_procedure_name => d_api_name || '.' || d_position
344 );
345
346 -- commit changes
347 PO_PDOI_UTL.commit_work;
348
349 IF (l_headers_csr%ISOPEN) THEN
350 CLOSE l_headers_csr;
351 PO_PDOI_HEADER_PROCESS_PVT.open_headers
352 (
353 p_max_intf_header_id => l_max_intf_header_id,
354 x_headers_csr => l_headers_csr
355 );
356 END IF;
357 END;
358 END LOOP;
359
360 d_position := 90;
361
362 -- close cursor
363 IF (l_headers_csr%ISOPEN) THEN
364 CLOSE l_headers_csr;
365 END IF;
366
367
368 -- Bug:16730873
369 -- From Catalog Upload process the action in po_headers_interface
370 -- table is stamped as 'UPDATE', and in the sql used in open_headers proc
371 -- we look for the data in po_headers_interface with
372 -- actions in ('ORIGINAL',REPLACE'). So No data is returned and hence
373 -- No data is dumped in PO_headers_draft_all [This is the beahvior since begining]
374 -- When there is Some change made by Cat. Admin/Supplier which is not yet sent to Buyer
375 -- Would lie in Drafts Table and the data state would be like this
376 -- 1 record in PO_DRAFT with status= 'DRAFT'
377 -- No data in po_headers_draft_all
378 -- Modified Number of records in po_lines_draft_all
379 -- At this stage, the Cat. admin should be able to query the agreement and
380 -- do further changes on it and send it for approval if he/she wants.
381 -- But After CLM changes in place,the Po_headers_merge_v has been modified and
382 -- the case when theer is a draft record existing with status=DRAFT and
383 -- No data in po_headers_draft_all stopped working as now it expects
384 -- If draft_id <>-1 ,then data should exists in PO_headers_draft_all
385 -- Draft_Id =-1 would come if there is No Data in Po_Drafts Or it should be 'COMPLETED'
386 -- or 'WITHDRAWN' status
387 -- So, Agreement coluld not be opened for Cat. admin any more.
388 -- So ,in order to support that case, inserting data in po_headers_draft_all
389 -- when the process in initiated from CATALOG_UPLOAD and action in po_headers_interface ='UPDATE'
390
391 d_position := 100;
392
393 IF (PO_PDOI_PARAMS.g_request.calling_module =
394 PO_PDOI_CONSTANTS.g_call_mod_CATALOG_UPLOAD)
395 THEN
396
397 l_cat_upload_head_exists :=TRUE;
398
399 BEGIN
400
401 SELECT
402 draft_id,
403 po_header_id,
404 'N'
405 BULK COLLECT INTO
406 l_headers.draft_id_tbl,
407 l_headers.po_header_id_tbl,
408 l_delete_tbl
409
410 FROM po_headers_interface
411 WHERE processing_id = PO_PDOI_PARAMS.g_processing_id
412 AND processing_round_num = PO_PDOI_PARAMS.g_current_round_num
413 AND interface_header_id > l_max_intf_header_id
414 AND action = PO_PDOI_CONSTANTS.g_ACTION_UPDATE
415 ORDER by interface_header_id;
416
417 IF (PO_LOG.d_stmt) THEN
418 PO_LOG.stmt(d_module, d_position, 'l_headers.draft_id_tbl.count',
419 l_headers.draft_id_tbl.count);
420 END IF;
421
422
423 EXCEPTION WHEN No_Data_Found THEN
424
425 d_position := 120;
426
427 IF (PO_LOG.d_stmt) THEN
428 PO_LOG.stmt(d_module, d_position, 'Setting l_cat_upload_head_exists in Exception');
429 END IF;
430
431 l_cat_upload_head_exists :=FALSE;
432 END;
433
434 IF (PO_LOG.d_stmt) THEN
435 PO_LOG.stmt(d_module, d_position, 'l_cat_upload_head_exists',
436 l_cat_upload_head_exists);
437 END IF;
438
439
440 d_position :=110;
441
442 IF l_cat_upload_head_exists THEN
443
444 IF (PO_LOG.d_stmt) THEN
445 PO_LOG.stmt(d_module, d_position, 'Before Inserting into Po_Headers_Draft_All');
446 END IF;
447
448
449 PO_HEADERS_DRAFT_PKG.sync_draft_from_txn(
450 p_po_header_id_tbl => l_headers.po_header_id_tbl,
451 p_draft_id_tbl => l_headers.draft_id_tbl,
452 p_delete_flag_tbl => l_delete_tbl,
453 x_record_already_exist_tbl => l_record_already_exist_tbl
454 );
455
456 IF (PO_LOG.d_stmt) THEN
457 PO_LOG.stmt(d_module, d_position, 'After Inserting into Po_Headers_Draft_All');
458 END IF;
459
460
461 END IF;
462
463 END IF;
464
465 -- Bug:16730873 End
466
467 PO_TIMING_UTL.stop_time(PO_PDOI_CONSTANTS.g_T_HEADER_PROCESS);
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 process_headers;
482
483 -------------------------------------------------------------------------
484 --Start of Comments
485 --Name: process_lines
486 --Pre-reqs: None
487 --Modifies:
488 --Locks:
489 -- None
490 --Function:
491 -- process the records in po_lines_interface table;
492 -- the records in the interface table will be divided into four sets
493 -- according to their header and line level actions:
494 -- First set: all the lines with header action equal to 'ORIGINAL'or
495 -- 'REPLACE'; If header action is 'UPDATE', the document
496 -- must be Standard PO
497 -- Second Set: Header level action is 'UPDATE' and document type is
498 -- 'BLANKET' or 'QUOTATION'; And line level action is 'ADD'
499 -- Third Set: Header level action is 'UPDATE' and document type is
500 -- 'BLANKET' or 'QUOTATION'; And line level action is 'SYNC'
501 -- or Null; And either of the following criteria is true:
502 -- 1. one of attributes {item, vendor_product_num, job} is not null
503 -- 2. if {item, vendor_product_num, job) are all null, then
504 -- description must be null
505 -- Fourth Set: Header level action is 'UPDATE' and document type is
506 -- 'BLANKET' or 'QUOTATION'; And line level action is 'SYNC'
507 -- or Null; {item, vendor_product_num, job) are all null and
508 -- description is not null
509 --Parameters:
510 --IN: None
511 --IN OUT: None
512 --OUT: None
513 --Returns:
514 --Notes:
515 --Testing:
516 --End of Comments
517 ------------------------------------------------------------------------
518 PROCEDURE process_lines IS
519
520 d_api_name CONSTANT VARCHAR2(30) := 'process_lines';
521 d_module CONSTANT VARCHAR2(255) := d_pkg_name || d_api_name || '.';
522 d_position NUMBER;
523
524 BEGIN
525 d_position := 0;
526
527 IF (PO_LOG.d_proc) THEN
528 PO_LOG.proc_begin(d_module);
529 END IF;
530
531 PO_TIMING_UTL.start_time(PO_PDOI_CONSTANTS.g_T_LINE_PROCESS);
532
533 -- reject lines with existing line_num when updating standard PO
534 IF (PO_PDOI_PARAMS.g_request.document_type =
535 PO_PDOI_CONSTANTS.g_DOC_TYPE_STANDARD) THEN
536 PO_PDOI_LINE_PROCESS_PVT.reject_dup_lines_for_spo;
537 END IF;
538
539 -- reject lines with invalid line level action.
540 -- line level action can only be NULL or 'ADD';
541 -- the only exception for this is when we re-process
542 -- the notified lines, the system has set the line
543 -- level action to either 'ADD' or 'UPADTE', we don't
544 -- need to check line level action for NOTOFIED lines
545 IF (PO_PDOI_PARAMS.g_request.process_code <>
546 PO_PDOI_CONSTANTS.g_PROCESS_CODE_NOTIFIED) THEN
547 PO_PDOI_LINE_PROCESS_PVT.reject_invalid_action_lines;
548 END IF;
549
550 d_position := 10;
551
552 -- first data set
553 process_lines_add
554 (
555 p_data_set_type => PO_PDOI_CONSTANTS.g_LINE_CSR_ADD
556 );
557
558 d_position := 20;
559
560 -- second data set
561 process_lines_add
562 (
563 p_data_set_type => PO_PDOI_CONSTANTS.g_LINE_CSR_FORCE_ADD
564 );
565
566 d_position := 30;
567
568 -- third data set
569 process_lines_sync
570 (
571 p_data_set_type => PO_PDOI_CONSTANTS.g_LINE_CSR_SYNC
572 );
573
574 d_position := 40;
575
576 -- Fourth data set
577 process_lines_sync
578 (
579 p_data_set_type => PO_PDOI_CONSTANTS.g_LINE_CSR_SYNC_ON_DESC
580 );
581
582 d_position := 50;
583
584 -- PDOI CLM Integration
585 -- Adding a fifth data set to process the info lines
586 process_info_lines
587 (
588 p_data_set_type => PO_PDOI_CONSTANTS.g_LINE_CSR_INFO_LINE_ADD
589 );
590 --Bug13343886
591 if PO_PDOI_CONSTANTS.g_GATHER_STATS = 'Y' THEN
592 d_position := 55;
593 gather_stats('PO_LINES_DRAFT_ALL',d_api_name,d_position);
594 END IF;
595 --Bug13343886
596
597 -- delete all locations from po_line_locations_interface that are obsoleted
598 DELETE FROM po_line_locations_interface
599 WHERE process_code = PO_PDOI_CONSTANTS.g_PROCESS_CODE_OBSOLETE
600 AND processing_id = PO_PDOI_PARAMS.g_processing_id;
601
602 PO_TIMING_UTL.stop_time(PO_PDOI_CONSTANTS.g_T_LINE_PROCESS);
603
604 IF (PO_LOG.d_proc) THEN
605 PO_LOG.proc_end(d_module);
606 END IF;
607
608 EXCEPTION
609 WHEN OTHERS THEN
610 PO_MESSAGE_S.add_exc_msg
611 (
612 p_pkg_name => d_pkg_name,
613 p_procedure_name => d_api_name || '.' || d_position
614 );
615 RAISE;
616 END process_lines;
617
618 -----------------------------------------------------------------------
619 --Start of Comments
620 --Name: process_lines_add
621 --Function: This procedure will deal with two kinds of data set:
622 -- First set: all the lines with header action equal to 'ORIGINAL'or
623 -- 'REPLACE'; If header action is 'UPDATE', the document
624 -- must be Standard PO
625 -- Second Set: Header level action is 'UPDATE' and document type is
626 -- 'BLANKET' or 'QUOTATION'; And line level action is 'ADD'
627 -- The two data set share similiar processing logic except for the data
628 -- to be processed. There is also an extra matching logic for First Set.
629 --Parameters:
630 --IN:
631 --p_data_set_type
632 -- the value determines which data set is going to be processed:
633 -- PO_PDOI_CONSTANTS.g_LINE_CSR_ADD: first data set
634 -- PO_PDOI_CONSTANTS.g_LINE_CSR_FORCE_ADD: second data set
635 --IN OUT:
636 --OUT:
637 --End of Comments
638 ------------------------------------------------------------------------
639 PROCEDURE process_lines_add
640 (
641 p_data_set_type IN NUMBER -- choice on data set to be processed
642 ) IS
643
644 d_api_name CONSTANT VARCHAR2(30) := 'process_lines_add';
645 d_module CONSTANT VARCHAR2(255) := d_pkg_name || d_api_name || '.';
646 d_position NUMBER;
647
648 -- cursor variable defined for the query
649 l_lines_csr PO_PDOI_TYPES.intf_cursor_type;
650
651 -- all line attribute values within a batch
652 l_lines PO_PDOI_TYPES.lines_rec_type;
653
654 -- variable to track the largest intf_line_id processed so far
655 l_max_intf_line_id NUMBER := -1;
656
657 -- variables to track the records that need to be rejected due
658 -- to errors in the processing
659 l_rej_intf_line_id_tbl PO_TBL_NUMBER := PO_TBL_NUMBER();
660
661 -- bug#13367649- variable to track the number of records fetched
662 -- for each loop iteration
663 l_lines_count NUMBER;
664
665 BEGIN
666 d_position := 0;
667
668 IF (PO_LOG.d_proc) THEN
669 PO_LOG.proc_begin(d_module, 'p_data_set_type', p_data_set_type);
670 END IF;
671
672 /*
673 -- code added for debugging purpose
674 select interface_header_id
675 into PO_PDOI_PARAMS.g_request.interface_header_id
676 from po_headers_interface
677 where processing_id = PO_PDOI_PARAMS.g_processing_id
678 and processing_round_num = 1;
679 */
680
681 -- Bug 5215781:
682 -- exit immediately if error threshold is hit for CATALOG UPLOAD
683 IF (PO_PDOI_PARAMS.g_request.calling_module =
684 PO_PDOI_CONSTANTS.g_CALL_MOD_CATALOG_UPLOAD AND
685 PO_PDOI_PARAMS.g_docs_info(PO_PDOI_PARAMS.g_request.interface_header_id)
686 .err_tolerance_exceeded = FND_API.g_TRUE) THEN
687 IF (PO_LOG.d_stmt) THEN
688 PO_LOG.stmt(d_module, d_position, 'Exit from process_lines_add since' ||
689 ' error threshold is hit for header ',
690 PO_PDOI_PARAMS.g_request.interface_header_id);
691 END IF;
692
693 RETURN;
694 END IF;
695
696 d_position := 5;
697
698 -- open cursor for the correct query
699 PO_PDOI_LINE_PROCESS_PVT.open_lines
700 (
701 p_data_set_type => p_data_set_type,
702 p_max_intf_line_id => l_max_intf_line_id,
703 x_lines_csr => l_lines_csr
704 );
705
706 d_position := 10;
707
708 -- fetch records from line interface table and process the records
709 LOOP
710 -- Bug 5215781:
711 -- check whether num of error lines exceeds the error
712 -- threshold for each batch
713 IF (PO_PDOI_PARAMS.g_request.calling_module =
714 PO_PDOI_CONSTANTS.g_CALL_MOD_CATALOG_UPLOAD AND
715 PO_PDOI_PARAMS.g_docs_info(PO_PDOI_PARAMS.g_request.interface_header_id)
716 .err_tolerance_exceeded = FND_API.g_TRUE) THEN
717 IF (PO_LOG.d_stmt) THEN
718 PO_LOG.stmt(d_module, d_position, 'error tolerance exceeded for',
719 PO_PDOI_PARAMS.g_request.interface_header_id);
720 END IF;
721
722 -- no need to process remaining lines if error threshold is reached
723 EXIT;
724 END IF;
725
726 BEGIN
727 -- fetch one batch of line records from query result
728 PO_PDOI_LINE_PROCESS_PVT.fetch_lines
729 (
730 x_lines_csr => l_lines_csr,
731 x_lines => l_lines
732 );
733
734 d_position := 20;
735
736 -- number of records read in current batch
737 l_lines.rec_count := l_lines.intf_line_id_tbl.COUNT;
738
739 --
740 -- bug#13367649- number of records fetched for
741 -- this iteration
742 --
743 l_lines_count := l_lines.intf_line_id_tbl.COUNT;
744
745 IF (PO_LOG.d_stmt) THEN
746 PO_LOG.stmt(d_module, d_position, 'line count in batch',
747 l_lines.rec_count);
748 END IF;
749
750 EXIT WHEN l_lines.rec_count = 0;
751
752 -- bug#13367649- set the maximal interface_line_id fetched in this batch
753 l_max_intf_line_id := l_lines.intf_line_id_tbl(l_lines.rec_count);
754
755 -- set up hashtable between interface_line_id and index
756 l_lines.intf_id_index_tbl.DELETE;
757
758 FOR i IN 1..l_lines.rec_count
759 LOOP
760 l_lines.intf_id_index_tbl(l_lines.intf_line_id_tbl(i)) := i;
761 END LOOP;
762
763 -- calculate max_line_num for all document in this batch
764 -- the result is saved and used in line processing
765 PO_PDOI_MAINPROC_UTL_PVT.calculate_max_line_num
766 (
767 p_po_header_id_tbl => l_lines.hd_po_header_id_tbl,
768 p_draft_id_tbl => l_lines.draft_id_tbl
769 );
770
771 d_position := 30;
772
773 -- derive logic
774 PO_PDOI_LINE_PROCESS_PVT.derive_lines
775 (
776 x_lines => l_lines
777 );
778
779 d_position := 40;
780
781 -- default logic
782 PO_PDOI_LINE_PROCESS_PVT.default_lines
783 (
784 x_lines => l_lines
785 );
786
787 d_position := 50;
788
789 -- match related lines based on line_num/item info
790 PO_PDOI_LINE_PROCESS_PVT.match_lines
791 (
792 p_data_set_type => p_data_set_type, -- bug5129752
793 x_lines => l_lines
794 );
795
796
797 d_position := 60;
798
799 -- bug5129752
800 -- After doing match line action, l_lines may become empty (this is the
801 -- case if all the lines can be matched to lines in the draft table
802
803
804 -- validate lines
805 PO_PDOI_LINE_PROCESS_PVT.validate_lines
806 (
807 x_lines => l_lines
808 );
809
810 d_position := 70;
811
812 -- create items if necessary
813 IF (PO_PDOI_PARAMS.g_request.create_items = 'Y') THEN
814 IF (PO_LOG.d_stmt) THEN
815 PO_LOG.stmt(d_module, d_position, 'create items for lines');
816 END IF;
817
818 PO_PDOI_ITEM_PROCESS_PVT.create_items
819 (
820 x_lines => l_lines
821 );
822 END IF;
823
824 d_position := 80;
825
826 -- insert lines into line draft table
827 PO_PDOI_MOVE_TO_DRAFT_TABS_PVT.insert_lines
828 (
829 x_lines => l_lines
830 );
831
832 d_position := 90;
833
834 -- update po_lines_interface with po_line_id and line level action
835 PO_PDOI_LINE_PROCESS_PVT.update_line_intf_tbl
836 (
837 x_lines => l_lines
838 );
839
840 IF Nvl(PO_PDOI_PARAMS.g_request.clm_flag,'N') = 'Y'
841 THEN
842 --Call the api to convert base_line_num from interface to draft
843 set_intf_base_line_num_to_dft;
844 END IF;
845
846 d_position := 100;
847
848 -- reject lines with errors
849 FOR i IN 1..l_lines.rec_count
850 LOOP
851 IF (l_lines.error_flag_tbl(i) = FND_API.g_TRUE OR
852 l_lines.need_to_reject_flag_tbl(i) = FND_API.g_TRUE) THEN
853 IF (PO_LOG.d_stmt) THEN
854 PO_LOG.stmt(d_module, d_position, 'error flag',
855 l_lines.error_flag_tbl(i));
856 PO_LOG.stmt(d_module, d_position, 'reject flag',
857 l_lines.need_to_reject_flag_tbl(i));
858 PO_LOG.stmt(d_module, d_position, 'rejected intf line id',
859 l_lines.intf_line_id_tbl(i));
860 END IF;
861
862 l_rej_intf_line_id_tbl.EXTEND;
863 l_rej_intf_line_id_tbl(l_rej_intf_line_id_tbl.COUNT) := l_lines.intf_line_id_tbl(i);
864 END IF;
865 END LOOP;
866 PO_PDOI_UTL.reject_lines_intf
867 (
868 p_id_param_type => PO_PDOI_CONSTANTS.g_INTERFACE_LINE_ID,
869 p_id_tbl => l_rej_intf_line_id_tbl,
870 p_cascade => FND_API.g_TRUE
871 );
872 l_rej_intf_line_id_tbl.DELETE;
873
874 d_position := 110;
875
876 -- commit changes
877 PO_PDOI_UTL.commit_work;
878
879 -- set the maximal interface_line_id processed in this batch
880 -- bug#13367649- move line to after fetch as l_lines.rec_count
881 -- now is number of records to create, not the original number
882 -- of records fetched for this iteration. After match_lines,
883 -- l_lines.rec_count contains number of po_lines to be created
884
885 -- l_max_intf_line_id := l_lines.intf_line_id_tbl(l_lines.rec_count);
886
887 --
888 -- bug#13367649- use local variable l_lines_count instead as
889 -- l_lines.rec_count now contains number of po_lines to be created
890 -- for this fetch, which can be less than the batch size
891
892 -- IF (l_lines.rec_count < PO_PDOI_CONSTANTS.g_DEF_BATCH_SIZE) THEN
893
894 IF (l_lines_count < PO_PDOI_CONSTANTS.g_DEF_BATCH_SIZE) THEN
895 EXIT;
896 END IF;
897 EXCEPTION
898 WHEN g_snap_shot_too_old THEN
899 d_position := 120;
900 -- log errors
901 PO_MESSAGE_S.add_exc_msg
902 (
903 p_pkg_name => d_pkg_name,
904 p_procedure_name => d_api_name || '.' || d_position
905 );
906
907 -- commit changes
908 PO_PDOI_UTL.commit_work;
909
910 IF (l_lines_csr%ISOPEN) THEN
911 CLOSE l_lines_csr;
912 PO_PDOI_LINE_PROCESS_PVT.open_lines
913 (
914 p_data_set_type => p_data_set_type,
915 p_max_intf_line_id => l_max_intf_line_id,
916 x_lines_csr => l_lines_csr
917 );
918 END IF;
919 END;
920 END LOOP;
921
922 d_position := 130;
923
924 -- close the cursor
925 IF (l_lines_csr%ISOPEN) THEN
926 CLOSE l_lines_csr;
927 END IF;
928
929 d_position := 140;
930
931 -- reject lines that are price breaks if main po line failed
932 SELECT interface_line_id
933 BULK COLLECT INTO l_rej_intf_line_id_tbl
934 FROM po_lines_interface intf_line1
935 WHERE price_break_flag = 'Y'
936 AND processing_id = PO_PDOI_PARAMS.g_processing_id
937 AND EXISTS(
938 SELECT 'Y'
939 FROM po_lines_interface intf_line2
940 WHERE intf_line1.interface_header_id = intf_line2.interface_header_id
941 AND intf_line1.po_line_id = intf_line2.po_line_id
942 AND NVL(intf_line2.process_code, PO_PDOI_CONSTANTS.g_PROCESS_CODE_PENDING)
943 = PO_PDOI_CONSTANTS.g_PROCESS_CODE_REJECTED
944 AND NVL(intf_line2.price_break_flag, 'N') = 'N');
945 d_position := 150;
946 PO_PDOI_UTL.reject_lines_intf
947 (
948 p_id_param_type => PO_PDOI_CONSTANTS.g_INTERFACE_LINE_ID,
949 p_id_tbl => l_rej_intf_line_id_tbl,
950 p_cascade => FND_API.g_TRUE
951 );
952
953 d_position := 160;
954
955 -- set status to NOTIFIED for price break lines if main po line is NOTIFIED
956 UPDATE po_lines_interface intf_line1
957 SET intf_line1.process_code = PO_PDOI_CONSTANTS.g_PROCESS_CODE_NOTIFIED
958 WHERE intf_line1.processing_id = PO_PDOI_PARAMS.g_processing_id
959 AND intf_line1.price_break_flag = 'Y'
960 AND EXISTS(
961 SELECT 'Y'
962 FROM po_lines_interface intf_line2
963 WHERE intf_line2.interface_header_id = intf_line1.interface_header_id
964 AND intf_line2.po_line_id = intf_line1.po_line_id
965 AND NVL(intf_line2.process_code, PO_PDOI_CONSTANTS.g_PROCESS_CODE_PENDING)
966 = PO_PDOI_CONSTANTS.g_PROCESS_CODE_NOTIFIED
967 AND NVL(intf_line2.price_break_flag, 'N') = 'N');
968
969 IF (PO_LOG.d_proc) THEN
970 PO_LOG.proc_end(d_module);
971 END IF;
972
973 EXCEPTION
974 WHEN OTHERS THEN
975 PO_MESSAGE_S.add_exc_msg
976 (
977 p_pkg_name => d_pkg_name,
978 p_procedure_name => d_api_name || '.' || d_position
979 );
980 RAISE;
981 END process_lines_add;
982
983 -----------------------------------------------------------------------
984 --Start of Comments
985 --Name: process_lines_sync
986 --Function: This procedure will deal with two kinds of data set from
987 -- calling procedure:
988 -- Third Set: Header level action is 'UPDATE' and document type is
989 -- 'BLANKET' or 'QUOTATION'; And line level action is 'SYNC'
990 -- or Null; And either of the following criteria is true:
991 -- 1. one of attributes {item, vendor_product_num, job} is not null
992 -- 2. if {item, vendor_product_num, job) are all null, then
993 -- description must be null
994 -- Fourth Set: Header level action is 'UPDATE' and document type is
995 -- 'BLANKET' or 'QUOTATION'; And line level action is 'SYNC'
996 -- or Null; {item, vendor_product_num, job) are all null and
997 -- description is not null
998 --
999 --Parameters:
1000 --IN:
1001 -- p_data_set_type
1002 -- the value determines which data set is going to be processed:
1003 -- PO_PDOI_CONSTANTS.g_LINE_CSR_SYNC: third data set
1004 -- PO_PDOI_CONSTANTS.g_LINE_CSR_SYNC_ON_DESC: fourth data set
1005 --IN OUT:
1006 --OUT:
1007 --End of Comments
1008 ------------------------------------------------------------------------
1009 PROCEDURE process_lines_sync
1010 (
1011 p_data_set_type IN NUMBER
1012 ) IS
1013
1014 d_api_name CONSTANT VARCHAR2(30) := 'process_lines_sync';
1015 d_module CONSTANT VARCHAR2(255) := d_pkg_name || d_api_name || '.';
1016 d_position NUMBER;
1017
1018 -- cursor variable defined for the query
1019 l_lines_csr PO_PDOI_TYPES.intf_cursor_type;
1020
1021 -- all line attribute values within a batch
1022 l_lines PO_PDOI_TYPES.lines_rec_type;
1023
1024 -- variable to track the largest intf_line_id processed so far
1025 l_max_intf_line_id NUMBER := -1;
1026
1027 -- lines that are going to be created/updated
1028 l_create_lines PO_PDOI_TYPES.lines_rec_type;
1029 l_update_lines PO_PDOI_TYPES.lines_rec_type;
1030
1031 /* bug 6926550 Added the following variable to null the
1032 l_create_lines and l_update_lines inside the procedure*/
1033 l_null_lines PO_PDOI_TYPES.lines_rec_type;
1034
1035 -- line grouping num
1036 l_group_num NUMBER := 0;
1037
1038 -- variable to track records that have not been processed
1039 l_processing_row_tbl DBMS_SQL.NUMBER_TABLE;
1040
1041 -- variable to track lines that need to be expired
1042 l_expire_line_id_tbl DBMS_SQL.NUMBER_TABLE;
1043
1044 l_rej_intf_line_id_tbl PO_TBL_NUMBER := PO_TBL_NUMBER();
1045 l_notified_intf_line_id_tbl PO_TBL_NUMBER := PO_TBL_NUMBER();
1046
1047 BEGIN
1048 d_position := 0;
1049
1050 IF (PO_LOG.d_proc) THEN
1051 PO_LOG.proc_begin(d_module, 'p_data_set_type', p_data_set_type);
1052 END IF;
1053
1054 -- Bug 5215781:
1055 -- exit immediately if error threshold is hit for CATALOG UPLOAD
1056 IF (PO_PDOI_PARAMS.g_request.calling_module =
1057 PO_PDOI_CONSTANTS.g_CALL_MOD_CATALOG_UPLOAD AND
1058 PO_PDOI_PARAMS.g_docs_info(PO_PDOI_PARAMS.g_request.interface_header_id)
1059 .err_tolerance_exceeded = FND_API.g_TRUE) THEN
1060 IF (PO_LOG.d_stmt) THEN
1061 PO_LOG.stmt(d_module, d_position, 'Exit from process_lines_sync since' ||
1062 ' error threshold is hit for header ',
1063 PO_PDOI_PARAMS.g_request.interface_header_id);
1064 END IF;
1065
1066 RETURN;
1067 END IF;
1068
1069 d_position := 5;
1070
1071 -- open cursor for the correct query
1072 PO_PDOI_LINE_PROCESS_PVT.open_lines
1073 (
1074 p_data_set_type => p_data_set_type,
1075 p_max_intf_line_id => l_max_intf_line_id,
1076 x_lines_csr => l_lines_csr
1077 );
1078
1079 d_position := 10;
1080
1081 -- fetch records from line interface table and process the records
1082 LOOP
1083 -- Bug 5215781:
1084 -- check whether num of error lines exceeds the error
1085 -- threshold for the previous batch
1086 IF (PO_PDOI_PARAMS.g_request.calling_module =
1087 PO_PDOI_CONSTANTS.g_CALL_MOD_CATALOG_UPLOAD AND
1088 PO_PDOI_PARAMS.g_docs_info(PO_PDOI_PARAMS.g_request.interface_header_id)
1089 .err_tolerance_exceeded = FND_API.g_TRUE) THEN
1090 d_position := 20;
1091
1092 IF (PO_LOG.d_stmt) THEN
1093 PO_LOG.stmt(d_module, d_position, 'error tolerance exceeded for',
1094 PO_PDOI_PARAMS.g_request.interface_header_id);
1095 END IF;
1096
1097 EXIT;
1098 END IF;
1099
1100 BEGIN
1101 -- fetch one batch of line records from query result
1102 PO_PDOI_LINE_PROCESS_PVT.fetch_lines
1103 (
1104 x_lines_csr => l_lines_csr,
1105 x_lines => l_lines
1106 );
1107
1108 d_position := 30;
1109
1110 -- number of records read in current batch
1111 l_lines.rec_count := l_lines.intf_line_id_tbl.COUNT;
1112
1113 IF (PO_LOG.d_stmt) THEN
1114 PO_LOG.stmt(d_module, d_position, 'line count in batch',
1115 l_lines.rec_count);
1116 END IF;
1117
1118 EXIT WHEN l_lines.rec_count = 0;
1119
1120 /* <bug 6926550> null the l_create_lines and l_update_lines
1121 before calling split lines procedure in the inner loop*/
1122 l_create_lines := l_null_lines;
1123 l_update_lines := l_null_lines;
1124
1125 -- set up hashtable between interface_line_id and index
1126 l_lines.intf_id_index_tbl.DELETE;
1127
1128 FOR i IN 1..l_lines.rec_count
1129 LOOP
1130 l_lines.intf_id_index_tbl(l_lines.intf_line_id_tbl(i)) := i;
1131 END LOOP;
1132
1133 -- calculate max_line_num for all document in this batch
1134 -- the result is saved and used in line processing
1135 PO_PDOI_MAINPROC_UTL_PVT.calculate_max_line_num
1136 (
1137 p_po_header_id_tbl => l_lines.hd_po_header_id_tbl,
1138 p_draft_id_tbl => l_lines.draft_id_tbl
1139 );
1140
1141 d_position := 40;
1142
1143 -- check whether provided line_num is unique across interface,
1144 -- draft and txn tables
1145 PO_PDOI_MAINPROC_UTL_PVT.check_line_num_unique
1146 (
1147 p_po_header_id_tbl => l_lines.hd_po_header_id_tbl,
1148 p_draft_id_tbl => l_lines.draft_id_tbl,
1149 p_intf_line_id_tbl => l_lines.intf_line_id_tbl,
1150 p_line_num_tbl => l_lines.line_num_tbl,
1151 x_line_num_unique_tbl => l_lines.line_num_unique_tbl
1152 );
1153
1154 d_position := 50;
1155
1156 -- setup table to track rows that have not been processed
1157 PO_PDOI_UTL.generate_ordered_num_list
1158 (
1159 p_size => l_lines.rec_count,
1160 x_num_list => l_processing_row_tbl
1161 );
1162
1163 -- inner loop to process line records in groups
1164 -- If same line is created and updated within the same batch,
1165 -- they must be processed in separate groups
1166 LOOP
1167 -- exit when all rows are processed
1168 IF (l_processing_row_tbl.COUNT = 0) THEN
1169 d_position := 60;
1170
1171 IF (PO_LOG.d_stmt) THEN
1172 PO_LOG.stmt(d_module, d_position, 'exit after all lines are processed');
1173 END IF;
1174
1175 EXIT;
1176 END IF;
1177
1178 -- increment group number
1179 l_group_num := l_group_num + 1;
1180
1181 IF (PO_LOG.d_stmt) THEN
1182 PO_LOG.stmt(d_module, d_position, 'group_num', l_group_num);
1183 END IF;
1184
1185 -- perform uniqueness check on all the records and
1186 -- mark the group number on the records that can be processed
1187 -- within a group
1188 PO_PDOI_LINE_PROCESS_PVT.uniqueness_check
1189 (
1190 p_type => p_data_set_type,
1191 p_group_num => l_group_num,
1192 x_processing_row_tbl => l_processing_row_tbl,
1193 x_lines => l_lines,
1194 x_expire_line_id_tbl => l_expire_line_id_tbl
1195 );
1196
1197 d_position := 70;
1198
1199 -- separate data records into two set, one for create and one for update
1200 PO_PDOI_LINE_PROCESS_PVT.split_lines
1201 (
1202 p_group_num => l_group_num,
1203 p_lines => l_lines,
1204 x_create_lines => l_create_lines,
1205 x_update_lines => l_update_lines
1206 );
1207
1208 d_position := 80;
1209
1210 -- process all rows that needs to be created
1211 process_create_lines_in_group
1212 (
1213 p_group_num => l_group_num,
1214 p_expire_line_id_tbl => l_expire_line_id_tbl,
1215 x_lines => l_create_lines
1216 );
1217
1218 d_position := 90;
1219
1220 -- process all the lines that need to be updated
1221 process_update_lines_in_group
1222 (
1223 p_group_num => l_group_num,
1224 x_lines => l_update_lines
1225 );
1226 END LOOP;
1227
1228 PO_PDOI_UTL.commit_work;
1229
1230 -- set the maximal interface_line_id processed in this batch
1231 l_max_intf_line_id := l_lines.intf_line_id_tbl(l_lines.rec_count);
1232
1233 IF (l_lines.rec_count < PO_PDOI_CONSTANTS.g_DEF_BATCH_SIZE) THEN
1234 EXIT;
1235 END IF;
1236 EXCEPTION
1237 WHEN g_snap_shot_too_old THEN
1238 d_position := 100;
1239
1240 -- log error
1241 PO_MESSAGE_S.add_exc_msg
1242 (
1243 p_pkg_name => d_pkg_name,
1244 p_procedure_name => d_api_name || '.' || d_position
1245 );
1246
1247 -- commit changes
1248 PO_PDOI_UTL.commit_work;
1249
1250 IF (l_lines_csr%ISOPEN) THEN
1251 CLOSE l_lines_csr;
1252 PO_PDOI_LINE_PROCESS_PVT.open_lines
1253 (
1254 p_data_set_type => p_data_set_type,
1255 p_max_intf_line_id => l_max_intf_line_id,
1256 x_lines_csr => l_lines_csr
1257 );
1258 END IF;
1259 END;
1260 END LOOP;
1261
1262 d_position := 110;
1263
1264 -- close the cursor
1265 IF (l_lines_csr%ISOPEN) THEN
1266 CLOSE l_lines_csr;
1267 END IF;
1268
1269 d_position := 120;
1270
1271 -- reject lines that are price breaks if main po line failed
1272 SELECT v.interface_line_id
1273 BULK COLLECT INTO l_rej_intf_line_id_tbl
1274 FROM po_lines_interface intf_line1,
1275 (SELECT intf_line2.interface_line_id, max(intf_line3.interface_line_id) AS match_intf_line_id
1276 FROM po_lines_interface intf_line2, po_lines_interface intf_line3,
1277 po_headers_interface intf_headers
1278 WHERE intf_line2.interface_header_id = intf_headers.interface_header_id
1279 AND intf_headers.processing_id = PO_PDOI_PARAMS.g_processing_id
1280 AND intf_headers.processing_round_num = PO_PDOI_PARAMS.g_current_round_num
1281 AND intf_line2.price_break_flag = 'Y'
1282 AND intf_line2.processing_id = PO_PDOI_PARAMS.g_processing_id
1283 AND intf_line2.interface_header_id = intf_line3.interface_header_id
1284 AND intf_line2.po_line_id = intf_line3.po_line_id
1285 AND NVL(intf_line3.price_break_flag, 'N') = 'N'
1286 AND intf_line3.interface_line_id < intf_line2.interface_line_id
1287 GROUP BY intf_line2.interface_line_id) v
1288 WHERE intf_line1.interface_line_id = v.match_intf_line_id
1289 AND NVL(intf_line1.process_code, PO_PDOI_CONSTANTS.g_PROCESS_CODE_PENDING)
1290 = PO_PDOI_CONSTANTS.g_PROCESS_CODE_REJECTED;
1291
1292 d_position := 130;
1293
1294 PO_PDOI_UTL.reject_lines_intf
1295 (
1296 p_id_param_type => PO_PDOI_CONSTANTS.g_INTERFACE_LINE_ID,
1297 p_id_tbl => l_rej_intf_line_id_tbl,
1298 p_cascade => FND_API.g_TRUE
1299 );
1300
1301 d_position := 140;
1302
1303 -- set status to NOTIFIED for price break lines if main po line is NOTIFIED
1304 SELECT v.interface_line_id
1305 BULK COLLECT INTO l_notified_intf_line_id_tbl
1306 FROM po_lines_interface intf_line1,
1307 (SELECT intf_line2.interface_line_id, max(intf_line3.interface_line_id) AS match_intf_line_id
1308 FROM po_lines_interface intf_line2, po_lines_interface intf_line3,
1309 po_headers_interface intf_headers
1310 WHERE intf_line2.interface_header_id = intf_headers.interface_header_id
1311 AND intf_headers.processing_id = PO_PDOI_PARAMS.g_processing_id
1312 AND intf_headers.processing_round_num = PO_PDOI_PARAMS.g_current_round_num
1313 AND intf_line2.price_break_flag = 'Y'
1314 AND intf_line2.processing_id = PO_PDOI_PARAMS.g_processing_id
1315 AND intf_line2.interface_header_id = intf_line3.interface_header_id
1316 AND intf_line2.po_line_id = intf_line3.po_line_id
1317 AND NVL(intf_line3.price_break_flag, 'N') = 'N'
1318 AND intf_line3.interface_line_id < intf_line2.interface_line_id
1319 GROUP BY intf_line2.interface_line_id) v
1320 WHERE intf_line1.interface_line_id = v.match_intf_line_id
1321 AND NVL(intf_line1.process_code, PO_PDOI_CONSTANTS.g_PROCESS_CODE_PENDING)
1322 = PO_PDOI_CONSTANTS.g_PROCESS_CODE_NOTIFIED;
1323
1324 d_position := 150;
1325
1326 FORALL i IN 1..l_notified_intf_line_id_tbl.COUNT
1327 UPDATE po_lines_interface
1328 SET process_code = PO_PDOI_CONSTANTS.g_PROCESS_CODE_NOTIFIED
1329 WHERE interface_line_id = l_notified_intf_line_id_tbl(i);
1330
1331 d_position := 160;
1332
1333 IF (PO_LOG.d_proc) THEN
1334 PO_LOG.proc_end(d_module);
1335 END IF;
1336
1337 EXCEPTION
1338 WHEN OTHERS THEN
1339 PO_MESSAGE_S.add_exc_msg
1340 (
1341 p_pkg_name => d_pkg_name,
1342 p_procedure_name => d_api_name || '.' || d_position
1343 );
1344 RAISE;
1345 END process_lines_sync;
1346
1347 -----------------------------------------------------------------------
1348 --Start of Comments
1349 --Name: process_create_lines_in_group
1350 --Function: Data set 3 and 4 contains lines of mixed actions. After the
1351 -- action is determined by uniqueness logic, lines with same
1352 -- actions will be grouped together and processed separately
1353 -- from lines with different actions.
1354 -- This procedure is to deal with lines whose action is 'ADD'.
1355 --Parameters:
1356 --IN:
1357 -- p_group_num
1358 -- the current processing group number. Only lines belonging to
1359 -- current group will be processed.
1360 -- p_expire_line_id_tbl
1361 -- The lines that need to be expired
1362 --IN OUT:
1363 -- x_lines
1364 -- contains all lines within the batch
1365 --OUT:
1366 --End of Comments
1367 ------------------------------------------------------------------------
1368 PROCEDURE process_create_lines_in_group
1369 (
1370 p_group_num IN NUMBER,
1371 p_expire_line_id_tbl IN DBMS_SQL.NUMBER_TABLE,
1372 x_lines IN OUT NOCOPY PO_PDOI_TYPES.lines_rec_type
1373 ) IS
1374
1375 d_api_name CONSTANT VARCHAR2(30) := 'process_create_lines_in_group';
1376 d_module CONSTANT VARCHAR2(255) := d_pkg_name || d_api_name || '.';
1377 d_position NUMBER;
1378
1379 -- variables to track the records that need to be rejected due
1380 -- to errors in the processing
1381 l_count NUMBER := 0;
1382 l_rej_intf_line_id_tbl PO_TBL_NUMBER := PO_TBL_NUMBER();
1383
1384 BEGIN
1385 d_position := 0;
1386
1387 IF (PO_LOG.d_proc) THEN
1388 PO_LOG.proc_begin(d_module, 'p_group_num', p_group_num);
1389 PO_LOG.proc_begin(d_module, 'count of lines', x_lines.rec_count);
1390 END IF;
1391
1392 -- return if there is no line to be processed
1393 IF (x_lines.rec_count = 0) THEN
1394 IF (PO_LOG.d_proc) THEN
1395 PO_LOG.proc_end(d_module);
1396 END IF;
1397
1398 RETURN;
1399 END IF;
1400
1401 -- derive logic
1402 PO_PDOI_LINE_PROCESS_PVT.derive_lines
1403 (
1404 x_lines => x_lines
1405 );
1406
1407 d_position := 10;
1408
1409 -- default logic
1410 PO_PDOI_LINE_PROCESS_PVT.default_lines
1411 (
1412 x_lines => x_lines
1413 );
1414
1415 d_position := 20;
1416
1417 -- validate lines
1418 PO_PDOI_LINE_PROCESS_PVT.validate_lines
1419 (
1420 x_lines => x_lines
1421 );
1422
1423 d_position := 30;
1424
1425 -- check whether line location needs to be created for the line
1426 PO_PDOI_LINE_PROCESS_PVT.check_line_locations
1427 (
1428 x_lines => x_lines
1429 );
1430
1431 d_position := 40;
1432
1433 -- create items if necessary
1434 IF (PO_PDOI_PARAMS.g_request.create_items = 'Y') THEN
1435 IF (PO_LOG.d_stmt) THEN
1436 PO_LOG.stmt(d_module, d_position, 'create items from line info');
1437 END IF;
1438
1439 PO_PDOI_ITEM_PROCESS_PVT.create_items
1440 (
1441 x_lines => x_lines
1442 );
1443 END IF;
1444
1445 d_position := 50;
1446
1447 -- insert lines into draft table
1448 PO_PDOI_MOVE_TO_DRAFT_TABS_PVT.insert_lines
1449 (
1450 x_lines => x_lines
1451 );
1452
1453 d_position := 60;
1454
1455 -- update po_lines_interface with po_line_id and line level action
1456 PO_PDOI_LINE_PROCESS_PVT.update_line_intf_tbl
1457 (
1458 x_lines => x_lines
1459 );
1460
1461 d_position := 70;
1462
1463 -- reject lines with errors
1464 l_rej_intf_line_id_tbl.EXTEND(x_lines.rec_count);
1465 FOR i IN 1..x_lines.rec_count
1466 LOOP
1467 IF (x_lines.error_flag_tbl(i) = FND_API.g_TRUE OR
1468 x_lines.need_to_reject_flag_tbl(i) = FND_API.g_TRUE) THEN
1469 IF (PO_LOG.d_stmt) THEN
1470 PO_LOG.stmt(d_module, d_position, 'error flag',
1471 x_lines.error_flag_tbl(i));
1472 PO_LOG.stmt(d_module, d_position, 'reject flag',
1473 x_lines.need_to_reject_flag_tbl(i));
1474 PO_LOG.stmt(d_module, d_position, 'rejected intf line id',
1475 x_lines.intf_line_id_tbl(i));
1476 END IF;
1477
1478 l_count := l_count + 1;
1479 l_rej_intf_line_id_tbl(l_count) := x_lines.intf_line_id_tbl(i);
1480 END IF;
1481 END LOOP;
1482 PO_PDOI_UTL.reject_lines_intf
1483 (
1484 p_id_param_type => PO_PDOI_CONSTANTS.g_INTERFACE_LINE_ID,
1485 p_id_tbl => l_rej_intf_line_id_tbl,
1486 p_cascade => FND_API.g_TRUE
1487 );
1488 l_rej_intf_line_id_tbl.DELETE;
1489
1490 d_position := 80;
1491
1492 -- expire blanket lines being replaced. They are replaced since it has
1493 -- release shipment and uom is changed in the new request
1494 FORALL i IN 1..p_expire_line_id_tbl.COUNT
1495 UPDATE po_lines_all
1496 SET expiration_date = TRUNC(sysdate - 1)
1497 WHERE po_line_id = p_expire_line_id_tbl(i);
1498
1499 IF (PO_LOG.d_proc) THEN
1500 PO_LOG.proc_end(d_module);
1501 END IF;
1502
1503 EXCEPTION
1504 WHEN OTHERS THEN
1505 PO_MESSAGE_S.add_exc_msg
1506 (
1507 p_pkg_name => d_pkg_name,
1508 p_procedure_name => d_api_name || '.' || d_position
1509 );
1510 RAISE;
1511 END process_create_lines_in_group;
1512
1513 -----------------------------------------------------------------------
1514 --Start of Comments
1515 --Name: process_update_lines_in_group
1516 --Function: Data set 3 and 4 contains lines of mixed actions. After the
1517 -- action is determined by uniqueness logic, lines with same
1518 -- actions will be grouped together and processed separately
1519 -- from lines with different actions.
1520 -- This procedure is to deal with lines whose action is 'UPDATE'
1521 --Parameters:
1522 -- p_group_num
1523 -- the current processing group number. Only lines belonging to
1524 -- current group will be processed.
1525 --IN OUT:
1526 -- x_lines
1527 -- contains all lines within the batch
1528 --OUT:
1529 --End of Comments
1530 ------------------------------------------------------------------------
1531 PROCEDURE process_update_lines_in_group
1532 (
1533 p_group_num IN NUMBER,
1534 x_lines IN OUT NOCOPY PO_PDOI_TYPES.lines_rec_type
1535 ) IS
1536
1537 d_api_name CONSTANT VARCHAR2(30) := 'process_update_lines_in_group';
1538 d_module CONSTANT VARCHAR2(255) := d_pkg_name || d_api_name || '.';
1539 d_position NUMBER;
1540
1541 -- variables to track the records that need to be rejected due
1542 -- to errors in the processing
1543 l_count NUMBER := 0;
1544 l_rej_intf_line_id_tbl PO_TBL_NUMBER := PO_TBL_NUMBER();
1545
1546 BEGIN
1547 d_position := 0;
1548
1549 IF (PO_LOG.d_proc) THEN
1550 PO_LOG.proc_begin(d_module, 'p_group_num', p_group_num);
1551 PO_LOG.proc_begin(d_module, 'count of lines', x_lines.rec_count);
1552 END IF;
1553
1554 -- return if there is no line to be processed
1555 IF (x_lines.rec_count = 0) THEN
1556 IF (PO_LOG.d_proc) THEN
1557 PO_LOG.proc_end(d_module);
1558 END IF;
1559
1560 RETURN;
1561 END IF;
1562
1563 -- derive internal identifier for updatable attributes
1564 PO_PDOI_LINE_PROCESS_PVT.derive_lines_for_update
1565 (
1566 x_lines => x_lines
1567 );
1568
1569 -- default certain attributes for processing purpose
1570 PO_PDOI_LINE_PROCESS_PVT.default_lines_for_update
1571 (
1572 x_lines => x_lines
1573 );
1574
1575 -- validate lines
1576 PO_PDOI_LINE_PROCESS_PVT.validate_lines
1577 (
1578 p_action => 'UPDATE',
1579 x_lines => x_lines
1580 );
1581
1582 d_position := 10;
1583
1584 -- check whether line location needs to be created for the line
1585 PO_PDOI_LINE_PROCESS_PVT.check_line_locations
1586 (
1587 x_lines => x_lines
1588 );
1589
1590 d_position := 20;
1591
1592 -- update lines on draft table
1593 PO_PDOI_MOVE_TO_DRAFT_TABS_PVT.update_lines
1594 (
1595 x_lines => x_lines
1596 );
1597
1598 d_position := 30;
1599
1600 -- update po_lines_interface with po_line_id and line level action
1601 PO_PDOI_LINE_PROCESS_PVT.update_line_intf_tbl
1602 (
1603 x_lines => x_lines
1604 );
1605
1606 d_position := 40;
1607
1608 -- set rejected status to lines and lower levels
1609 l_rej_intf_line_id_tbl.EXTEND(x_lines.rec_count);
1610 FOR i IN 1..x_lines.rec_count
1611 LOOP
1612 IF (x_lines.error_flag_tbl(i) = FND_API.g_TRUE OR
1613 x_lines.need_to_reject_flag_tbl(i) = FND_API.g_TRUE) THEN
1614 IF (PO_LOG.d_stmt) THEN
1615 PO_LOG.stmt(d_module, d_position, 'error flag',
1616 x_lines.error_flag_tbl(i));
1617 PO_LOG.stmt(d_module, d_position, 'reject flag',
1618 x_lines.need_to_reject_flag_tbl(i));
1619 PO_LOG.stmt(d_module, d_position, 'rejected intf line id',
1620 x_lines.intf_line_id_tbl(i));
1621 END IF;
1622
1623 l_count := l_count + 1;
1624 l_rej_intf_line_id_tbl(l_count) := x_lines.intf_line_id_tbl(i);
1625 END IF;
1626 END LOOP;
1627 PO_PDOI_UTL.reject_lines_intf
1628 (
1629 p_id_param_type => PO_PDOI_CONSTANTS.g_INTERFACE_LINE_ID,
1630 p_id_tbl => l_rej_intf_line_id_tbl,
1631 p_cascade => FND_API.g_TRUE
1632 );
1633 l_rej_intf_line_id_tbl.DELETE;
1634
1635 IF (PO_LOG.d_proc) THEN
1636 PO_LOG.proc_end(d_module);
1637 END IF;
1638
1639 EXCEPTION
1640 WHEN OTHERS THEN
1641 PO_MESSAGE_S.add_exc_msg
1642 (
1643 p_pkg_name => d_pkg_name,
1644 p_procedure_name => d_api_name || '.' || d_position
1645 );
1646 RAISE;
1647 END process_update_lines_in_group;
1648
1649 -------------------------------------------------------------------------
1650 --Start of Comments
1651 --Name: process_line_locations
1652 --Pre-reqs: None
1653 --Modifies:
1654 --Locks:
1655 -- None
1656 --Function:
1657 -- handle the logic to derive, default, validate and insert records
1658 -- from po_line_locations_interface table
1659 --Parameters:
1660 --IN: None
1661 --IN OUT: None
1662 --OUT: None
1663 --Returns:
1664 --Notes:
1665 --Testing:
1666 --End of Comments
1667 ------------------------------------------------------------------------
1668 PROCEDURE process_line_locations IS
1669
1670 d_api_name CONSTANT VARCHAR2(30) := 'process_line_locations';
1671 d_module CONSTANT VARCHAR2(255) := d_pkg_name || d_api_name || '.';
1672 d_position NUMBER;
1673
1674 -- cursor variable defined for the query
1675 l_line_locs_csr PO_PDOI_TYPES.intf_cursor_type;
1676
1677 -- all line location attribute values within a batch
1678 l_line_locs PO_PDOI_TYPES.line_locs_rec_type;
1679
1680 -- variables to track the records that need to be rejected due
1681 -- to errors in the processing
1682 l_rej_intf_line_loc_id_tbl PO_TBL_NUMBER := PO_TBL_NUMBER();
1683
1684 -- keep record of lines processed in this request
1685 -- the record will be used in post line location processing
1686 l_processed_line_id_tbl DBMS_SQL.number_table;
1687 l_processed_draft_id_tbl DBMS_SQL.number_table;
1688 l_line_ref_tbl DBMS_SQL.number_table;
1689
1690 -- maximal interface_line_location_id_processed
1691 l_max_intf_line_loc_id NUMBER := -1;
1692
1693 l_count NUMBER;
1694 BEGIN
1695 d_position := 0;
1696
1697 IF (PO_LOG.d_proc) THEN
1698 PO_LOG.proc_begin(d_module);
1699 END IF;
1700
1701 -- Bug 5215781:
1702 -- exit immediately if error threshold is hit for CATALOG UPLOAD
1703 IF (PO_PDOI_PARAMS.g_request.calling_module =
1704 PO_PDOI_CONSTANTS.g_CALL_MOD_CATALOG_UPLOAD AND
1705 PO_PDOI_PARAMS.g_docs_info(PO_PDOI_PARAMS.g_request.interface_header_id)
1706 .err_tolerance_exceeded = FND_API.g_TRUE) THEN
1707 IF (PO_LOG.d_stmt) THEN
1708 PO_LOG.stmt(d_module, d_position, 'Exit from process_line_locations since' ||
1709 ' error threshold is hit for header ',
1710 PO_PDOI_PARAMS.g_request.interface_header_id);
1711 END IF;
1712
1713 RETURN;
1714 END IF;
1715
1716 d_position := 5;
1717
1718 PO_TIMING_UTL.start_time(PO_PDOI_CONSTANTS.g_T_LINE_LOC_PROCESS);
1719
1720 -- open cursor for the correct query
1721 PO_PDOI_LINE_LOC_PROCESS_PVT.open_line_locs
1722 (
1723 p_max_intf_line_loc_id => l_max_intf_line_loc_id,
1724 x_line_locs_csr => l_line_locs_csr
1725 );
1726
1727 d_position := 10;
1728
1729 -- fetch records from line location interface table and process the records
1730 LOOP
1731 -- Bug 5215781:
1732 -- check whether num of error lines exceeds the error
1733 -- threshold for the previous batch
1734 IF (PO_PDOI_PARAMS.g_request.calling_module =
1735 PO_PDOI_CONSTANTS.g_CALL_MOD_CATALOG_UPLOAD AND
1736 PO_PDOI_PARAMS.g_docs_info(PO_PDOI_PARAMS.g_request.interface_header_id)
1737 .err_tolerance_exceeded = FND_API.g_TRUE) THEN
1738 d_position := 20;
1739
1740 IF (PO_LOG.d_stmt) THEN
1741 PO_LOG.stmt(d_module, d_position, 'error tolerance exceeded for',
1742 PO_PDOI_PARAMS.g_request.interface_header_id);
1743 END IF;
1744
1745 EXIT;
1746 END IF;
1747
1748 BEGIN
1749 -- fetch one batch of line location records from query result
1750 PO_PDOI_LINE_LOC_PROCESS_PVT.fetch_line_locs
1751 (
1752 x_line_locs_csr => l_line_locs_csr,
1753 x_line_locs => l_line_locs
1754 );
1755
1756 d_position := 20;
1757
1758 -- number of records read in current batch
1759 l_line_locs.rec_count := l_line_locs.intf_line_loc_id_tbl.COUNT;
1760
1761 IF (PO_LOG.d_stmt) THEN
1762 PO_LOG.stmt(d_module, d_position, 'loc count in batch',
1763 l_line_locs.rec_count);
1764 END IF;
1765
1766 EXIT WHEN l_line_locs.rec_count = 0;
1767
1768 -- set up hashtable between interface_line_location_id and index
1769 l_line_locs.intf_id_index_tbl.DELETE;
1770
1771 FOR i IN 1..l_line_locs.rec_count
1772 LOOP
1773 l_line_locs.intf_id_index_tbl(l_line_locs.intf_line_loc_id_tbl(i)) := i;
1774 END LOOP;
1775
1776 -- calculate max_shipment_num for each line in this batch
1777 -- the result is saved and used in line location processing
1778 PO_PDOI_MAINPROC_UTL_PVT.calculate_max_shipment_num
1779 (
1780 p_po_line_id_tbl => l_line_locs.ln_po_line_id_tbl,
1781 p_draft_id_tbl => l_line_locs.draft_id_tbl
1782 );
1783
1784 d_position := 30;
1785
1786 -- check whether provided shipment_num is unqiue across interface,
1787 -- draft and txn tables.
1788 -- logic is performed for Standard PO only
1789 IF (PO_PDOI_PARAMS.g_request.document_type =
1790 PO_PDOI_CONSTANTS.g_DOC_TYPE_STANDARD) THEN
1791 PO_PDOI_MAINPROC_UTL_PVT.check_shipment_num_unique
1792 (
1793 p_po_line_id_tbl => l_line_locs.ln_po_line_id_tbl,
1794 p_draft_id_tbl => l_line_locs.draft_id_tbl,
1795 p_intf_line_loc_id_tbl => l_line_locs.intf_line_loc_id_tbl,
1796 p_shipment_num_tbl => l_line_locs.shipment_num_tbl,
1797 x_shipment_num_unique_tbl => l_line_locs.shipment_num_unique_tbl
1798 );
1799 END IF;
1800
1801 d_position := 40;
1802
1803 -- derive logic
1804 PO_PDOI_LINE_LOC_PROCESS_PVT.derive_line_locs
1805 (
1806 x_line_locs => l_line_locs
1807 );
1808
1809 d_position := 50;
1810
1811 -- default logic
1812 PO_PDOI_LINE_LOC_PROCESS_PVT.default_line_locs
1813 (
1814 x_line_locs => l_line_locs
1815 );
1816
1817 d_position := 60;
1818
1819 -- validate logic
1820 PO_PDOI_LINE_LOC_PROCESS_PVT.validate_line_locs
1821 (
1822 x_line_locs => l_line_locs
1823 );
1824
1825 d_position := 70;
1826
1827 -- insert line locations into line location draft table
1828 PO_PDOI_MOVE_TO_DRAFT_TABS_PVT.insert_line_locs
1829 (
1830 p_line_locs => l_line_locs
1831 );
1832
1833 d_position := 80;
1834
1835 -- update po_line_locations_interface with line_location_id
1836 PO_PDOI_LINE_LOC_PROCESS_PVT.update_line_loc_interface
1837 (
1838 p_intf_line_loc_id_tbl => l_line_locs.intf_line_loc_id_tbl,
1839 p_line_loc_id_tbl => l_line_locs.line_loc_id_tbl,
1840 p_error_flag_tbl => l_line_locs.error_flag_tbl
1841 );
1842
1843 d_position := 90;
1844
1845 -- set rejected status to line locations and lower levels
1846 FOR i IN 1..l_line_locs.rec_count
1847 LOOP
1848 IF (l_line_locs.error_flag_tbl(i) = FND_API.G_TRUE) THEN
1849 l_rej_intf_line_loc_id_tbl.EXTEND;
1850 l_rej_intf_line_loc_id_tbl(l_rej_intf_line_loc_id_tbl.COUNT) := l_line_locs.intf_line_loc_id_tbl(i);
1851
1852 -- bug 5215781:
1853 -- remove the logic here, same logic is moved to PO_PDOI_LINE_LOC_PROCESS_PVT
1854 /*
1855 -- bug4662687 START
1856 -- Report the lines that have shipment/price break errors
1857 IF (NOT PO_PDOI_PARAMS.g_errored_lines.EXISTS(l_line_locs.intf_line_id_tbl(i))) THEN
1858 PO_PDOI_PARAMS.g_errored_lines(l_line_locs.intf_line_id_tbl(i)) := 'Y';
1859 PO_PDOI_PARAMS.g_docs_info(l_line_locs.intf_header_id_tbl(i)).number_of_errored_lines
1860 := PO_PDOI_PARAMS.g_docs_info(l_line_locs.intf_header_id_tbl(i)).number_of_errored_lines +1;
1861
1862 END IF;
1863 -- bug4662687 END
1864 */
1865 END IF;
1866 END LOOP;
1867
1868 IF (PO_LOG.d_stmt) THEN
1869 PO_LOG.stmt(d_module, d_position, 'to-be-rejected locs',
1870 l_rej_intf_line_loc_id_tbl);
1871 END IF;
1872
1873 PO_PDOI_UTL.reject_line_locations_intf
1874 (
1875 p_id_param_type => PO_PDOI_CONSTANTS.g_INTERFACE_LINE_LOCATION_ID,
1876 p_id_tbl => l_rej_intf_line_loc_id_tbl,
1877 p_cascade => FND_API.g_TRUE
1878 );
1879 l_rej_intf_line_loc_id_tbl.DELETE;
1880
1881 d_position := 100;
1882
1883 -- keep track of lines that have location records processed
1884 l_count := 0;
1885 FOR i IN 1..l_line_locs.rec_count
1886 LOOP
1887 IF (NOT l_line_ref_tbl.EXISTS(l_line_locs.ln_po_line_id_tbl(i)) AND
1888 l_line_locs.error_flag_tbl(i) = FND_API.g_FALSE) THEN
1889 l_count := l_count + 1;
1890 l_processed_line_id_tbl(l_count) := l_line_locs.ln_po_line_id_tbl(i);
1891 l_processed_draft_id_tbl(l_count) := l_line_locs.draft_id_tbl(i);
1892 l_line_ref_tbl(l_line_locs.ln_po_line_id_tbl(i)) := i;
1893 END IF;
1894 END LOOP;
1895
1896 -- commit
1897 PO_PDOI_UTL.commit_work;
1898
1899 IF (l_line_locs.rec_count < PO_PDOI_CONSTANTS.g_DEF_BATCH_SIZE) THEN
1900 EXIT;
1901 END IF;
1902
1903 l_max_intf_line_loc_id := l_line_locs.intf_line_loc_id_tbl(l_line_locs.rec_count);
1904 EXCEPTION
1905 WHEN g_snap_shot_too_old THEN
1906 d_position := 110;
1907
1908 -- log error
1909 PO_MESSAGE_S.add_exc_msg
1910 (
1911 p_pkg_name => d_pkg_name,
1912 p_procedure_name => d_api_name || '.' || d_position
1913 );
1914
1915 -- commit changes
1916 PO_PDOI_UTL.commit_work;
1917
1918 IF (l_line_locs_csr%ISOPEN) THEN
1919 CLOSE l_line_locs_csr;
1920 PO_PDOI_LINE_LOC_PROCESS_PVT.open_line_locs
1921 (
1922 p_max_intf_line_loc_id => l_max_intf_line_loc_id,
1923 x_line_locs_csr => l_line_locs_csr
1924 );
1925 END IF;
1926 END;
1927 END LOOP;
1928
1929 d_position := 120;
1930
1931 -- close the cursor
1932 IF (l_line_locs_csr%ISOPEN) THEN
1933 CLOSE l_line_locs_csr;
1934 END IF;
1935
1936 -- line location post processing
1937 IF (PO_PDOI_PARAMS.g_request.document_type =
1938 PO_PDOI_CONSTANTS.g_DOC_TYPE_STANDARD) THEN
1939 d_position := 130;
1940
1941 -- update amount or quantity value on po_lines_draft_all based
1942 -- on the values on shipment for Standard PO.
1943 PO_PDOI_LINE_LOC_PROCESS_PVT.update_amount_quantity_on_line
1944 (
1945 p_po_line_id_tbl => l_processed_line_id_tbl,
1946 p_draft_id_tbl => l_processed_draft_id_tbl
1947 );
1948 ELSIF (PO_PDOI_PARAMS.g_request.document_type =
1949 PO_PDOI_CONSTANTS.g_DOC_TYPE_QUOTATION) THEN
1950 d_position := 140;
1951
1952 -- delete all existing price breaks for quotation update
1953 PO_PDOI_LINE_LOC_PROCESS_PVT.delete_exist_price_breaks
1954 (
1955 p_po_line_id_tbl => l_processed_line_id_tbl,
1956 p_draft_id_tbl => l_processed_draft_id_tbl
1957 );
1958 ELSE -- document_type = blanket
1959 d_position := 150;
1960
1961 -- In previous implementation, price discount is updated based
1962 -- on price and price break. The logic is removed in R12.
1963 NULL;
1964 END IF;
1965
1966 PO_TIMING_UTL.stop_time(PO_PDOI_CONSTANTS.g_T_LINE_LOC_PROCESS);
1967
1968 IF (PO_LOG.d_proc) THEN
1969 PO_LOG.proc_end(d_module);
1970 END IF;
1971
1972 EXCEPTION
1973 WHEN OTHERS THEN
1974 PO_MESSAGE_S.add_exc_msg
1975 (
1976 p_pkg_name => d_pkg_name,
1977 p_procedure_name => d_api_name || '.' || d_position
1978 );
1979 RAISE;
1980 END process_line_locations;
1981
1982 -------------------------------------------------------------------------
1983 --Start of Comments
1984 --Name: process_distributions
1985 --Pre-reqs: None
1986 --Modifies:
1987 --Locks:
1988 -- None
1989 --Function:
1990 -- handle the logic to derive, default, validate and insert records
1991 -- from po_distributions_interface table
1992 --Parameters:
1993 --IN: None
1994 --IN OUT: None
1995 --OUT: None
1996 --Returns:
1997 --Notes:
1998 --Testing:
1999 --End of Comments
2000 ------------------------------------------------------------------------
2001 PROCEDURE process_distributions IS
2002
2003 d_api_name CONSTANT VARCHAR2(30) := 'process_distributions';
2004 d_module CONSTANT VARCHAR2(255) := d_pkg_name || d_api_name || '.';
2005 d_position NUMBER;
2006
2007 -- record to hold distribution values read within a batch
2008 l_dists PO_PDOI_TYPES.distributions_rec_type;
2009
2010 -- cursor variable to point to currently processing row
2011 l_dists_csr PO_PDOI_TYPES.intf_cursor_type;
2012
2013 -- variables to track the records that need to be rejected due
2014 -- to errors in the processing
2015 l_rej_intf_dist_id_tbl PO_TBL_NUMBER := PO_TBL_NUMBER();
2016
2017 -- maximal interface_line_location_id_processed
2018 l_max_intf_dist_id NUMBER := -1;
2019
2020 BEGIN
2021 d_position := 0;
2022
2023 IF (PO_LOG.d_proc) THEN
2024 PO_LOG.proc_begin(d_module);
2025 END IF;
2026
2027 PO_TIMING_UTL.start_time(PO_PDOI_CONSTANTS.g_T_DIST_PROCESS);
2028
2029 -- open cursor for the correct query
2030 PO_PDOI_DIST_PROCESS_PVT.open_dists
2031 (
2032 p_max_intf_dist_id => l_max_intf_dist_id,
2033 x_dists_csr => l_dists_csr
2034 );
2035
2036 d_position := 10;
2037
2038 -- fetch records from distribution interface table and process the records
2039 LOOP
2040 BEGIN
2041 -- fetch one batch of distribution records from query result
2042 PO_PDOI_DIST_PROCESS_PVT.fetch_dists
2043 (
2044 x_dists_csr => l_dists_csr,
2045 x_dists => l_dists
2046 );
2047
2048 d_position := 20;
2049
2050 -- number of records read in current batch
2051 l_dists.rec_count := l_dists.intf_dist_id_tbl.COUNT;
2052
2053 IF (PO_LOG.d_stmt) THEN
2054 PO_LOG.stmt(d_module, d_position, 'dist count in batch',
2055 l_dists.rec_count);
2056 END IF;
2057
2058 EXIT WHEN l_dists.rec_count = 0;
2059
2060 -- calculate max distribution num for each line location
2061 -- in this batch
2062 -- the result is saved and used in distribution processing
2063 PO_PDOI_MAINPROC_UTL_PVT.calculate_max_dist_num
2064 (
2065 p_line_loc_id_tbl => l_dists.loc_line_loc_id_tbl,
2066 p_draft_id_tbl => l_dists.draft_id_tbl
2067 );
2068
2069 d_position := 30;
2070
2071 -- check whether the distribution num is unique per line location
2072 PO_PDOI_MAINPROC_UTL_PVT.check_dist_num_unique
2073 (
2074 p_line_loc_id_tbl => l_dists.loc_line_loc_id_tbl,
2075 p_draft_id_tbl => l_dists.draft_id_tbl,
2076 p_intf_dist_id_tbl => l_dists.intf_dist_id_tbl,
2077 p_dist_num_tbl => l_dists.dist_num_tbl,
2078 x_dist_num_unique_tbl => l_dists.dist_num_unique_tbl
2079 );
2080
2081 d_position := 40;
2082
2083 -- derive logic
2084 PO_PDOI_DIST_PROCESS_PVT.derive_dists
2085 (
2086 x_dists => l_dists
2087 );
2088
2089 d_position := 50;
2090
2091 -- default logic
2092 PO_PDOI_DIST_PROCESS_PVT.default_dists
2093 (
2094 x_dists => l_dists
2095 );
2096
2097 d_position := 60;
2098
2099 -- validate logic
2100 PO_PDOI_DIST_PROCESS_PVT.validate_dists
2101 (
2102 x_dists => l_dists
2103 );
2104
2105 d_position := 70;
2106
2107 -- insert distributions into draft table
2108 PO_PDOI_MOVE_TO_DRAFT_TABS_PVT.insert_dists
2109 (
2110 p_dists => l_dists
2111 );
2112
2113 d_position := 80;
2114
2115 -- set rejected status to distributions
2116 FOR i IN 1..l_dists.rec_count
2117 LOOP
2118 IF (l_dists.error_flag_tbl(i) = FND_API.G_TRUE) THEN
2119 l_rej_intf_dist_id_tbl.EXTEND;
2120 l_rej_intf_dist_id_tbl(l_rej_intf_dist_id_tbl.COUNT) := l_dists.intf_dist_id_tbl(i);
2121 END IF;
2122 END LOOP;
2123
2124 IF (PO_LOG.d_stmt) THEN
2125 PO_LOG.stmt(d_module, d_position, 'to-be-rejected dists',
2126 l_rej_intf_dist_id_tbl);
2127 END IF;
2128
2129 d_position := 90;
2130
2131 PO_PDOI_UTL.reject_distributions_intf
2132 (
2133 p_id_param_type => PO_PDOI_CONSTANTS.g_INTERFACE_DISTRIBUTION_ID,
2134 p_id_tbl => l_rej_intf_dist_id_tbl
2135 );
2136 l_rej_intf_dist_id_tbl.DELETE;
2137
2138 d_position := 100;
2139
2140 -- set status to ACCEPTED for records without errors on intf table
2141 FORALL i IN 1..l_dists.intf_dist_id_tbl.COUNT
2142 UPDATE po_distributions_interface
2143 SET process_code = PO_PDOI_CONSTANTS.g_PROCESS_CODE_ACCEPTED
2144 WHERE interface_distribution_id = l_dists.intf_dist_id_tbl(i)
2145 AND l_dists.error_flag_tbl(i) = FND_API.g_FALSE;
2146
2147 d_position := 110;
2148
2149 PO_PDOI_UTL.commit_work;
2150
2151 IF (l_dists.rec_count < PO_PDOI_CONSTANTS.g_DEF_BATCH_SIZE) THEN
2152 EXIT;
2153 END IF;
2154
2155 l_max_intf_dist_id := l_dists.intf_dist_id_tbl(l_dists.rec_count);
2156 EXCEPTION
2157 WHEN g_snap_shot_too_old THEN
2158 d_position := 120;
2159
2160 -- log error
2161 PO_MESSAGE_S.add_exc_msg
2162 (
2163 p_pkg_name => d_pkg_name,
2164 p_procedure_name => d_api_name || '.' || d_position
2165 );
2166
2167 -- commit changes
2168 PO_PDOI_UTL.commit_work;
2169
2170 IF (l_dists_csr%ISOPEN) THEN
2171 CLOSE l_dists_csr;
2172 PO_PDOI_DIST_PROCESS_PVT.open_dists
2173 (
2174 p_max_intf_dist_id => l_max_intf_dist_id,
2175 x_dists_csr => l_dists_csr
2176 );
2177 END IF;
2178 END;
2179 END LOOP;
2180
2181 d_position := 130;
2182
2183 -- close the cursor
2184 IF (l_dists_csr%ISOPEN) THEN
2185 CLOSE l_dists_csr;
2186 END IF;
2187
2188 PO_TIMING_UTL.stop_time(PO_PDOI_CONSTANTS.g_T_DIST_PROCESS);
2189
2190 IF (PO_LOG.d_proc) THEN
2191 PO_LOG.proc_end(d_module);
2192 END IF;
2193
2194 EXCEPTION
2195 WHEN OTHERS THEN
2196 PO_MESSAGE_S.add_exc_msg
2197 (
2198 p_pkg_name => d_pkg_name,
2199 p_procedure_name => d_api_name || '.' || d_position
2200 );
2201 RAISE;
2202 END process_distributions;
2203
2204 -------------------------------------------------------------------------
2205 --Start of Comments
2206 --Name: process_price_diffs
2207 --Pre-reqs: None
2208 --Modifies:
2209 --Locks:
2210 -- None
2211 --Function:
2212 -- handle the logic to validate and insert records
2213 -- from po_price_diffs_interface table
2214 --Parameters:
2215 --IN: None
2216 --IN OUT: None
2217 --OUT: None
2218 --Returns:
2219 --Notes:
2220 --Testing:
2221 --End of Comments
2222 ------------------------------------------------------------------------
2223 PROCEDURE process_price_diffs IS
2224
2225 d_api_name CONSTANT VARCHAR2(30) := 'process_price_diffs';
2226 d_module CONSTANT VARCHAR2(255) := d_pkg_name || d_api_name || '.';
2227 d_position NUMBER;
2228
2229 -- record to hold price differential values read within a batch
2230 l_price_diffs PO_PDOI_TYPES.price_diffs_rec_type;
2231
2232 -- cursor variable to point to currently processing row
2233 l_price_diffs_csr PO_PDOI_TYPES.intf_cursor_type;
2234
2235 -- variables to track the records that need to be rejected due
2236 -- to errors in the processing
2237 l_rej_intf_price_diff_id_tbl PO_TBL_NUMBER := PO_TBL_NUMBER();
2238
2239 -- maximal interface_price_diff_id_processed
2240 l_max_intf_price_diff_id NUMBER := -1;
2241
2242 BEGIN
2243 d_position := 0;
2244
2245 IF (PO_LOG.d_proc) THEN
2246 PO_LOG.proc_begin(d_module);
2247 END IF;
2248
2249 -- Bug 5215781:
2250 -- exit immediately if error threshold is hit for CATALOG UPLOAD
2251 IF (PO_PDOI_PARAMS.g_request.calling_module =
2252 PO_PDOI_CONSTANTS.g_CALL_MOD_CATALOG_UPLOAD AND
2253 PO_PDOI_PARAMS.g_docs_info(PO_PDOI_PARAMS.g_request.interface_header_id)
2254 .err_tolerance_exceeded = FND_API.g_TRUE) THEN
2255 IF (PO_LOG.d_stmt) THEN
2256 PO_LOG.stmt(d_module, d_position, 'Exit from process_price_diffs since' ||
2257 ' error threshold is hit for header ',
2258 PO_PDOI_PARAMS.g_request.interface_header_id);
2259 END IF;
2260
2261 RETURN;
2262 END IF;
2263
2264 d_position := 5;
2265
2266 PO_TIMING_UTL.start_time(PO_PDOI_CONSTANTS.g_T_PRICE_DIFF_PROCESS);
2267
2268 -- open cursor for the correct query
2269 PO_PDOI_PRICE_DIFF_PROCESS_PVT.open_price_diffs
2270 (
2271 p_max_intf_price_diff_id => l_max_intf_price_diff_id,
2272 x_price_diffs_csr => l_price_diffs_csr
2273 );
2274
2275 d_position := 10;
2276
2277 -- fetch records from price differential interface table and process the records
2278 LOOP
2279 -- Bug 5215781:
2280 -- check whether num of error lines exceeds the error
2281 -- threshold for the previous batch
2282 IF (PO_PDOI_PARAMS.g_request.calling_module =
2283 PO_PDOI_CONSTANTS.g_CALL_MOD_CATALOG_UPLOAD AND
2284 PO_PDOI_PARAMS.g_docs_info(PO_PDOI_PARAMS.g_request.interface_header_id)
2285 .err_tolerance_exceeded = FND_API.g_TRUE) THEN
2286 d_position := 20;
2287
2288 IF (PO_LOG.d_stmt) THEN
2289 PO_LOG.stmt(d_module, d_position, 'error tolerance exceeded for',
2290 PO_PDOI_PARAMS.g_request.interface_header_id);
2291 END IF;
2292
2293 EXIT;
2294 END IF;
2295
2296 BEGIN
2297 -- fetch one batch of records from query result
2298 PO_PDOI_PRICE_DIFF_PROCESS_PVT.fetch_price_diffs
2299 (
2300 x_price_diffs_csr => l_price_diffs_csr,
2301 x_price_diffs => l_price_diffs
2302 );
2303
2304 d_position := 30;
2305
2306 -- number of records read in current batch
2307 l_price_diffs.rec_count := l_price_diffs.intf_price_diff_id_tbl.COUNT;
2308
2309 IF (PO_LOG.d_stmt) THEN
2310 PO_LOG.stmt(d_module, d_position, 'price diffs in batch',
2311 l_price_diffs.rec_count);
2312 END IF;
2313
2314 EXIT WHEN l_price_diffs.rec_count = 0;
2315
2316 PO_PDOI_PRICE_DIFF_PROCESS_PVT.default_price_diffs
2317 (
2318 x_price_diffs => l_price_diffs
2319 );
2320
2321 d_position := 40;
2322
2323 -- validate logic
2324 PO_PDOI_PRICE_DIFF_PROCESS_PVT.validate_price_diffs
2325 (
2326 x_price_diffs => l_price_diffs
2327 );
2328
2329 d_position := 50;
2330
2331 -- insert into draft table
2332 PO_PDOI_MOVE_TO_DRAFT_TABS_PVT.insert_price_diffs
2333 (
2334 p_price_diffs => l_price_diffs
2335 );
2336
2337 d_position := 60;
2338
2339 -- set rejected status
2340 FOR i IN 1..l_price_diffs.rec_count
2341 LOOP
2342 IF (l_price_diffs.error_flag_tbl(i) = FND_API.G_TRUE) THEN
2343 l_rej_intf_price_diff_id_tbl.EXTEND;
2344 l_rej_intf_price_diff_id_tbl(l_rej_intf_price_diff_id_tbl.COUNT) := l_price_diffs.intf_price_diff_id_tbl(i);
2345 END IF;
2346 END LOOP;
2347
2348 IF (PO_LOG.d_stmt) THEN
2349 PO_LOG.stmt(d_module, d_position, 'to-be-rejected price diffs',
2350 l_rej_intf_price_diff_id_tbl);
2351 END IF;
2352
2353 PO_PDOI_UTL.reject_price_diff_intf
2354 (
2355 p_id_param_type => PO_PDOI_CONSTANTS.g_PRICE_DIFF_INTERFACE_ID,
2356 p_id_tbl => l_rej_intf_price_diff_id_tbl
2357 );
2358 l_rej_intf_price_diff_id_tbl.DELETE;
2359
2360 d_position := 70;
2361
2362 -- set status to ACCEPTED for records without errors on intf table
2363 FORALL i IN 1..l_price_diffs.intf_price_diff_id_tbl.COUNT
2364 UPDATE po_price_diff_interface
2365 SET process_code = PO_PDOI_CONSTANTS.g_PROCESS_CODE_ACCEPTED
2366 WHERE price_diff_interface_id = l_price_diffs.intf_price_diff_id_tbl(i)
2367 AND l_price_diffs.error_flag_tbl(i) = FND_API.g_FALSE;
2368
2369 PO_PDOI_UTL.commit_work;
2370
2371 IF (l_price_diffs.rec_count < PO_PDOI_CONSTANTS.g_DEF_BATCH_SIZE) THEN
2372 EXIT;
2373 END IF;
2374
2375 l_max_intf_price_diff_id := l_price_diffs.intf_price_diff_id_tbl(l_price_diffs.rec_count);
2376 EXCEPTION
2377 WHEN g_snap_shot_too_old THEN
2378 d_position := 80;
2379
2380 -- log error
2381 PO_MESSAGE_S.add_exc_msg
2382 (
2383 p_pkg_name => d_pkg_name,
2384 p_procedure_name => d_api_name || '.' || d_position
2385 );
2386
2387 -- commit changes
2388 PO_PDOI_UTL.commit_work;
2389
2390 IF (l_price_diffs_csr%ISOPEN) THEN
2391 CLOSE l_price_diffs_csr;
2392 PO_PDOI_PRICE_DIFF_PROCESS_PVT.open_price_diffs
2393 (
2394 p_max_intf_price_diff_id => l_max_intf_price_diff_id,
2395 x_price_diffs_csr => l_price_diffs_csr
2396 );
2397 END IF;
2398 END;
2399 END LOOP;
2400
2401 d_position := 90;
2402
2403 -- close the cursor
2404 IF (l_price_diffs_csr%ISOPEN) THEN
2405 CLOSE l_price_diffs_csr;
2406 END IF;
2407
2408 PO_TIMING_UTL.stop_time(PO_PDOI_CONSTANTS.g_T_PRICE_DIFF_PROCESS);
2409
2410 IF (PO_LOG.d_proc) THEN
2411 PO_LOG.proc_end(d_module);
2412 END IF;
2413
2414 EXCEPTION
2415 WHEN OTHERS THEN
2416 PO_MESSAGE_S.add_exc_msg
2417 (
2418 p_pkg_name => d_pkg_name,
2419 p_procedure_name => d_api_name || '.' || d_position
2420 );
2421 RAISE;
2422 END process_price_diffs;
2423
2424 -------------------------------------------------------------------------
2425 --Start of Comments
2426 --Name: process_attributes
2427 --Pre-reqs: None
2428 --Modifies:
2429 --Locks:
2430 -- None
2431 --Function:
2432 -- handle the logic to validate and insert records
2433 -- from po_attr_values_interface table and
2434 -- po_attr_values_tlp_interface table
2435 --Parameters:
2436 --IN: None
2437 --IN OUT: None
2438 --OUT: None
2439 --Returns:
2440 --Notes:
2441 --Testing:
2442 --End of Comments
2443 ------------------------------------------------------------------------
2444 PROCEDURE process_attributes IS
2445
2446 d_api_name CONSTANT VARCHAR2(30) := 'process_attributes';
2447 d_module CONSTANT VARCHAR2(255) := d_pkg_name || d_api_name || '.';
2448 d_position NUMBER;
2449
2450 BEGIN
2451 d_position := 0;
2452
2453 IF (PO_LOG.d_proc) THEN
2454 PO_LOG.proc_begin(d_module);
2455 END IF;
2456
2457 -- Bug 5215781:
2458 -- exit immediately if error threshold is hit for CATALOG UPLOAD
2459 IF (PO_PDOI_PARAMS.g_request.calling_module =
2460 PO_PDOI_CONSTANTS.g_CALL_MOD_CATALOG_UPLOAD AND
2461 PO_PDOI_PARAMS.g_docs_info(PO_PDOI_PARAMS.g_request.interface_header_id)
2462 .err_tolerance_exceeded = FND_API.g_TRUE) THEN
2463 IF (PO_LOG.d_stmt) THEN
2464 PO_LOG.stmt(d_module, d_position, 'Exit from process_attributes since' ||
2465 ' error threshold is hit for header ',
2466 PO_PDOI_PARAMS.g_request.interface_header_id);
2467 END IF;
2468
2469 RETURN;
2470 END IF;
2471
2472 d_position := 10;
2473
2474 PO_TIMING_UTL.start_time(PO_PDOI_CONSTANTS.g_T_ATTR_PROCESS);
2475
2476 -- process all lines in po_attr_values_interface table
2477 process_attr_values;
2478
2479 d_position := 20;
2480
2481 -- process all lines in po_attr_values_tlp_interface table
2482 process_attr_values_tlp;
2483
2484 d_position := 30;
2485
2486 -- add default attr_values and attr_values_tlp if not provided
2487 PO_PDOI_ATTR_PROCESS_PVT.add_default_attrs;
2488
2489 d_position := 40;
2490
2491 PO_TIMING_UTL.stop_time(PO_PDOI_CONSTANTS.g_T_ATTR_PROCESS);
2492
2493 IF (PO_LOG.d_proc) THEN
2494 PO_LOG.proc_end(d_module);
2495 END IF;
2496
2497 EXCEPTION
2498 WHEN OTHERS THEN
2499 PO_MESSAGE_S.add_exc_msg
2500 (
2501 p_pkg_name => d_pkg_name,
2502 p_procedure_name => d_api_name || '.' || d_position
2503 );
2504 RAISE;
2505 END process_attributes;
2506
2507 -------------------------------------------------------------------------
2508 --Start of Comments
2509 --Name: process_attr_values
2510 --Pre-reqs: None
2511 --Modifies:
2512 --Locks:
2513 -- None
2514 --Function:
2515 -- process records in po_attr_values_interface table;
2516 -- currently, there is only validation logic, no
2517 -- derivation and defaulting logic
2518 --Parameters:
2519 --IN: None
2520 --IN OUT: None
2521 --OUT: None
2522 --Returns:
2523 --Notes:
2524 --Testing:
2525 --End of Comments
2526 ------------------------------------------------------------------------
2527 PROCEDURE process_attr_values IS
2528
2529 d_api_name CONSTANT VARCHAR2(30) := 'process_attr_values';
2530 d_module CONSTANT VARCHAR2(255) := d_pkg_name || d_api_name || '.';
2531 d_position NUMBER;
2532
2533 -- record to hold attribute values read within a batch
2534 l_attr_values PO_PDOI_TYPES.attr_values_rec_type;
2535
2536 -- cursor variable to point to currently processing row
2537 l_attr_values_csr PO_PDOI_TYPES.intf_cursor_type;
2538
2539 -- pl/sql table to track rows that needs to be created or updated
2540 l_merge_row_tbl DBMS_SQL.NUMBER_TABLE;
2541
2542 -- pl/sql table to track rows that need to be synced from txn
2543 -- table to draft table
2544 l_sync_attr_id_tbl PO_TBL_NUMBER;
2545 l_sync_draft_id_tbl PO_TBL_NUMBER;
2546
2547 -- maximal interface_attr_values_id_processed
2548 l_max_intf_attr_values_id NUMBER := -1;
2549
2550 -- index for the loop
2551 l_index NUMBER;
2552
2553 l_processing_row_tbl DBMS_SQL.NUMBER_TABLE;
2554
2555 BEGIN
2556 d_position := 0;
2557
2558 IF (PO_LOG.d_proc) THEN
2559 PO_LOG.proc_begin(d_module);
2560 END IF;
2561
2562 -- open cursor for query to retrieve attr value records
2563 PO_PDOI_ATTR_PROCESS_PVT.open_attr_values
2564 (
2565 p_max_intf_attr_values_id => l_max_intf_attr_values_id,
2566 x_attr_values_csr => l_attr_values_csr
2567 );
2568
2569 d_position := 10;
2570
2571 -- fetch records from attr values interface table and process the records
2572 LOOP
2573 BEGIN
2574 -- fetch one batch of records from query result
2575 PO_PDOI_ATTR_PROCESS_PVT.fetch_attr_values
2576 (
2577 x_attr_values_csr => l_attr_values_csr,
2578 x_attr_values => l_attr_values
2579 );
2580
2581 d_position := 20;
2582
2583 -- number of records read in current batch
2584 l_attr_values.rec_count := l_attr_values.intf_attr_values_id_tbl.COUNT;
2585
2586 IF (PO_LOG.d_stmt) THEN
2587 PO_LOG.stmt(d_module, d_position, 'attr values in batch',
2588 l_attr_values.rec_count);
2589 END IF;
2590
2591 EXIT WHEN l_attr_values.rec_count = 0;
2592
2593 -- process each record to determine the action;
2594 -- if multiple records are pointing to same
2595 -- po_line_id, the record will be processed
2596 -- in different groups
2597
2598 -- first setup table to track rows that have not been processed
2599 PO_PDOI_UTL.generate_ordered_num_list
2600 (
2601 p_size => l_attr_values.rec_count,
2602 x_num_list => l_processing_row_tbl
2603 );
2604
2605 -- second, process records in groups
2606 LOOP
2607 d_position := 30;
2608
2609 -- exit when all rows are processed
2610 IF (l_processing_row_tbl.COUNT = 0) THEN
2611 IF (PO_LOG.d_stmt) THEN
2612 PO_LOG.stmt(d_module, d_position, 'exit after all rows are processed');
2613 END IF;
2614
2615 EXIT;
2616 END IF;
2617
2618 -- determine the action for each attr value record
2619 PO_PDOI_ATTR_PROCESS_PVT.check_attr_actions
2620 (
2621 x_processing_row_tbl => l_processing_row_tbl,
2622 x_attr_values => l_attr_values,
2623 x_merge_row_tbl => l_merge_row_tbl,
2624 x_sync_attr_id_tbl => l_sync_attr_id_tbl,
2625 x_sync_draft_id_tbl => l_sync_draft_id_tbl
2626 );
2627
2628 d_position := 40;
2629
2630 -- insert records into draft table
2631 PO_PDOI_MOVE_TO_DRAFT_TABS_PVT.merge_attr_values
2632 (
2633 p_processing_row_tbl => l_merge_row_tbl,
2634 p_sync_attr_id_tbl => l_sync_attr_id_tbl,
2635 p_sync_draft_id_tbl => l_sync_draft_id_tbl,
2636 p_attr_values => l_attr_values
2637 );
2638 END LOOP;
2639
2640 d_position := 50;
2641
2642 -- set status to ACCEPTED for all records
2643 FORALL i IN 1..l_attr_values.intf_attr_values_id_tbl.COUNT
2644 UPDATE po_attr_values_interface
2645 SET process_code = PO_PDOI_CONSTANTS.g_PROCESS_CODE_ACCEPTED
2646 WHERE interface_attr_values_id = l_attr_values.intf_attr_values_id_tbl(i)
2647 AND l_attr_values.error_flag_tbl(i) = FND_API.g_FALSE;
2648
2649 --Bug13343886
2650 if PO_PDOI_CONSTANTS.g_GATHER_STATS = 'Y' THEN
2651 d_position := 55;
2652 gather_stats('PO_ATTRIBUTE_VALUES_DRAFT',d_api_name,d_position);
2653 END IF;
2654 --Bug13343886
2655 PO_PDOI_UTL.commit_work;
2656
2657 IF (l_attr_values.rec_count < PO_PDOI_CONSTANTS.g_DEF_BATCH_SIZE) THEN
2658 EXIT;
2659 END IF;
2660
2661 l_max_intf_attr_values_id := l_attr_values.intf_attr_values_id_tbl(l_attr_values.rec_count);
2662 EXCEPTION
2663 WHEN g_snap_shot_too_old THEN
2664 d_position := 60;
2665
2666 -- log error
2667 PO_MESSAGE_S.add_exc_msg
2668 (
2669 p_pkg_name => d_pkg_name,
2670 p_procedure_name => d_api_name || '.' || d_position
2671 );
2672
2673 -- commit changes
2674 PO_PDOI_UTL.commit_work;
2675
2676 IF (l_attr_values_csr%ISOPEN) THEN
2677 CLOSE l_attr_values_csr;
2678 PO_PDOI_ATTR_PROCESS_PVT.open_attr_values
2679 (
2680 p_max_intf_attr_values_id => l_max_intf_attr_values_id,
2681 x_attr_values_csr => l_attr_values_csr
2682 );
2683 END IF;
2684 END;
2685 END LOOP;
2686
2687 d_position := 70;
2688
2689 -- close the cursor
2690 IF (l_attr_values_csr%ISOPEN) THEN
2691 CLOSE l_attr_values_csr;
2692 END IF;
2693
2694 IF (PO_LOG.d_proc) THEN
2695 PO_LOG.proc_end(d_module);
2696 END IF;
2697
2698 EXCEPTION
2699 WHEN OTHERS THEN
2700 PO_MESSAGE_S.add_exc_msg
2701 (
2702 p_pkg_name => d_pkg_name,
2703 p_procedure_name => d_api_name || '.' || d_position
2704 );
2705 RAISE;
2706 END process_attr_values;
2707
2708 -------------------------------------------------------------------------
2709 --Start of Comments
2710 --Name: process_attr_values_tlp
2711 --Pre-reqs: None
2712 --Modifies:
2713 --Locks:
2714 -- None
2715 --Function:
2716 -- handle the logic on records from po_attr_values_tlp_interface table
2717 --Parameters:
2718 --IN: None
2719 --IN OUT: None
2720 --OUT: None
2721 --Returns:
2722 --Notes:
2723 --Testing:
2724 --End of Comments
2725 ------------------------------------------------------------------------
2726 PROCEDURE process_attr_values_tlp IS
2727
2728 d_api_name CONSTANT VARCHAR2(30) := 'process_attr_values_tlp';
2729 d_module CONSTANT VARCHAR2(255) := d_pkg_name || d_api_name || '.';
2730 d_position NUMBER;
2731
2732 -- record to hold attribute tlp values read within a batch
2733 l_attr_values_tlp PO_PDOI_TYPES.attr_values_tlp_rec_type;
2734
2735 -- cursor variable to point to currently processing row
2736 l_attr_values_tlp_csr PO_PDOI_TYPES.intf_cursor_type;
2737
2738 -- pl/sql table to track rows that needs to be created or updated
2739 l_merge_row_tbl DBMS_SQL.NUMBER_TABLE;
2740
2741 -- pl/sql table to track rows that need to be synced from txn
2742 -- table to draft table
2743 l_sync_attr_tlp_id_tbl PO_TBL_NUMBER;
2744 l_sync_draft_id_tbl PO_TBL_NUMBER;
2745
2746 -- maximal interface_attr_values_tlp_id_processed
2747 l_max_intf_attr_values_tlp_id NUMBER := -1;
2748
2749 l_processing_row_tbl DBMS_SQL.NUMBER_TABLE;
2750 l_index NUMBER;
2751
2752 BEGIN
2753 d_position := 0;
2754
2755 IF (PO_LOG.d_proc) THEN
2756 PO_LOG.proc_begin(d_module);
2757 END IF;
2758
2759 -- open cursor for query to retrieve attr value records
2760 PO_PDOI_ATTR_PROCESS_PVT.open_attr_values_tlp
2761 (
2762 p_max_intf_attr_values_tlp_id => l_max_intf_attr_values_tlp_id,
2763 x_attr_values_tlp_csr => l_attr_values_tlp_csr
2764 );
2765
2766 d_position := 10;
2767
2768 -- fetch records from attr values tlp interface table and process the records
2769 LOOP
2770 BEGIN
2771 -- fetch one batch of records from query result
2772 PO_PDOI_ATTR_PROCESS_PVT.fetch_attr_values_tlp
2773 (
2774 x_attr_values_tlp_csr => l_attr_values_tlp_csr,
2775 x_attr_values_tlp => l_attr_values_tlp
2776 );
2777
2778 d_position := 20;
2779
2780 -- number of records read in current batch
2781 l_attr_values_tlp.rec_count := l_attr_values_tlp.intf_attr_values_tlp_id_tbl.COUNT;
2782
2783 IF (PO_LOG.d_stmt) THEN
2784 PO_LOG.stmt(d_module, d_position, 'attr values tlp in batch',
2785 l_attr_values_tlp.rec_count);
2786 END IF;
2787
2788 EXIT WHEN l_attr_values_tlp.rec_count = 0;
2789
2790 -- process each record to determine the action;
2791 -- if multiple records are pointing to same
2792 -- po_line_id and language, the record will be processed
2793 -- in different groups
2794
2795 -- first setup table to track rows that have not been processed
2796 PO_PDOI_UTL.generate_ordered_num_list
2797 (
2798 p_size => l_attr_values_tlp.rec_count,
2799 x_num_list => l_processing_row_tbl
2800 );
2801
2802 -- second, process records in groups
2803 LOOP
2804 d_position := 20;
2805
2806 -- exit when all rows are processed
2807 IF (l_processing_row_tbl.COUNT = 0) THEN
2808 IF (PO_LOG.d_stmt) THEN
2809 PO_LOG.stmt(d_module, d_position, 'exit after all rows are processed');
2810 END IF;
2811
2812 EXIT;
2813 END IF;
2814
2815 -- determine the action for each attr value tlp record
2816 PO_PDOI_ATTR_PROCESS_PVT.check_attr_tlp_actions
2817 (
2818 x_processing_row_tbl => l_processing_row_tbl,
2819 x_attr_values_tlp => l_attr_values_tlp,
2820 x_merge_row_tbl => l_merge_row_tbl,
2821 x_sync_attr_tlp_id_tbl => l_sync_attr_tlp_id_tbl,
2822 x_sync_draft_id_tbl => l_sync_draft_id_tbl
2823 );
2824
2825 d_position := 30;
2826
2827 -- merge records into draft table
2828 PO_PDOI_MOVE_TO_DRAFT_TABS_PVT.merge_attr_values_tlp
2829 (
2830 p_processing_row_tbl => l_merge_row_tbl,
2831 p_sync_attr_tlp_id_tbl => l_sync_attr_tlp_id_tbl,
2832 p_sync_draft_id_tbl => l_sync_draft_id_tbl,
2833 p_attr_values_tlp => l_attr_values_tlp
2834 );
2835 END LOOP;
2836
2837 d_position := 40;
2838
2839 -- set status to ACCEPTED for all records
2840 FORALL i IN 1..l_attr_values_tlp.intf_attr_values_tlp_id_tbl.COUNT
2841 UPDATE po_attr_values_tlp_interface
2842 SET process_code = PO_PDOI_CONSTANTS.g_PROCESS_CODE_ACCEPTED
2843 WHERE interface_attr_values_tlp_id = l_attr_values_tlp.intf_attr_values_tlp_id_tbl(i)
2844 AND l_attr_values_tlp.error_flag_tbl(i) = FND_API.g_FALSE;
2845
2846 --Bug13343886
2847 if PO_PDOI_CONSTANTS.g_GATHER_STATS = 'Y' THEN
2848 d_position := 45;
2849 gather_stats('PO_ATTRIBUTE_VALUES_TLP_DRAFT',d_api_name,d_position);
2850 END IF;
2851 --Bug13343886
2852
2853 PO_PDOI_UTL.commit_work;
2854
2855 IF (l_attr_values_tlp.rec_count < PO_PDOI_CONSTANTS.g_DEF_BATCH_SIZE) THEN
2856 EXIT;
2857 END IF;
2858
2859 l_max_intf_attr_values_tlp_id := l_attr_values_tlp.intf_attr_values_tlp_id_tbl(l_attr_values_tlp.rec_count);
2860 EXCEPTION
2861 WHEN g_snap_shot_too_old THEN
2862 d_position := 50;
2863
2864 -- log error
2865 PO_MESSAGE_S.add_exc_msg
2866 (
2867 p_pkg_name => d_pkg_name,
2868 p_procedure_name => d_api_name || '.' || d_position
2869 );
2870
2871 -- commit changes
2872 PO_PDOI_UTL.commit_work;
2873
2874 IF (l_attr_values_tlp_csr%ISOPEN) THEN
2875 CLOSE l_attr_values_tlp_csr;
2876 PO_PDOI_ATTR_PROCESS_PVT.open_attr_values_tlp
2877 (
2878 p_max_intf_attr_values_tlp_id => l_max_intf_attr_values_tlp_id,
2879 x_attr_values_tlp_csr => l_attr_values_tlp_csr
2880 );
2881 END IF;
2882 END;
2883 END LOOP;
2884
2885 d_position := 60;
2886
2887 -- close the cursor
2888 IF (l_attr_values_tlp_csr%ISOPEN) THEN
2889 CLOSE l_attr_values_tlp_csr;
2890 END IF;
2891
2892 IF (PO_LOG.d_proc) THEN
2893 PO_LOG.proc_end(d_module);
2894 END IF;
2895
2896 EXCEPTION
2897 WHEN OTHERS THEN
2898 PO_MESSAGE_S.add_exc_msg
2899 (
2900 p_pkg_name => d_pkg_name,
2901 p_procedure_name => d_api_name || '.' || d_position
2902 );
2903 RAISE;
2904 END process_attr_values_tlp;
2905
2906
2907 --------------------------------------------------------------------------------------------
2908 --------------------------------------------------------------------------------------------
2909
2910 PROCEDURE process_info_lines
2911 (
2912 p_data_set_type IN number
2913 )IS
2914
2915 d_api_name CONSTANT VARCHAR2(30) := 'process_info_lines';
2916 d_module CONSTANT VARCHAR2(255) := d_pkg_name || d_api_name || '.';
2917 d_position NUMBER;
2918
2919 -- cursor variable defined for the query
2920 l_lines_csr PO_PDOI_TYPES.intf_cursor_type;
2921
2922 -- all line attribute values within a batch
2923 l_lines PO_PDOI_TYPES.lines_rec_type;
2924
2925 -- variable to track the largest intf_line_id processed so far
2926 l_max_intf_line_id NUMBER := -1;
2927
2928 -- variables to track the records that need to be rejected due
2929 -- to errors in the processing
2930 l_rej_intf_line_id_tbl PO_TBL_NUMBER := PO_TBL_NUMBER();
2931 l_po_line_id NUMBER := 0;
2932 BEGIN
2933 d_position := 0;
2934
2935 IF (PO_LOG.d_proc) THEN
2936 PO_LOG.proc_begin(d_module, 'p_data_set_type', p_data_set_type);
2937 END IF;
2938
2939 -- open cursor for the correct query
2940 PO_PDOI_LINE_PROCESS_PVT.open_lines
2941 (
2942 p_data_set_type => p_data_set_type,
2943 p_max_intf_line_id => l_max_intf_line_id,
2944 x_lines_csr => l_lines_csr
2945 );
2946
2947 d_position := 10;
2948
2949 -- fetch records from line interface table and process the records
2950 LOOP
2951 -- check whether num of error lines exceeds the error
2952 -- threshold for each batch
2953 IF (PO_PDOI_PARAMS.g_request.calling_module =
2954 PO_PDOI_CONSTANTS.g_CALL_MOD_CATALOG_UPLOAD AND
2955 PO_PDOI_PARAMS.g_docs_info(PO_PDOI_PARAMS.g_request.interface_header_id)
2956 .err_tolerance_exceeded = FND_API.g_TRUE) THEN
2957 IF (PO_LOG.d_stmt) THEN
2958 PO_LOG.stmt(d_module, d_position, 'error tolerance exceeded for',
2959 PO_PDOI_PARAMS.g_request.interface_header_id);
2960 END IF;
2961
2962 -- no need to process remaining lines if error threshold is reached
2963 EXIT;
2964 END IF;
2965
2966 BEGIN
2967
2968 -- fetch one batch of line records from query result
2969 PO_PDOI_LINE_PROCESS_PVT.fetch_lines
2970 (
2971 x_lines_csr => l_lines_csr,
2972 x_lines => l_lines
2973 );
2974
2975 d_position := 20;
2976
2977 -- number of records read in current batch
2978 l_lines.rec_count := l_lines.intf_line_id_tbl.COUNT;
2979
2980 IF (PO_LOG.d_stmt) THEN
2981 PO_LOG.stmt(d_module, d_position, 'line count in batch',
2982 l_lines.rec_count);
2983 END IF;
2984
2985 EXIT WHEN l_lines.rec_count = 0;
2986
2987 -- set up hashtable between interface_line_id and index
2988 l_lines.intf_id_index_tbl.DELETE;
2989
2990 FOR i IN 1..l_lines.rec_count
2991 LOOP
2992 l_lines.intf_id_index_tbl(l_lines.intf_line_id_tbl(i)) := i;
2993 END LOOP;
2994
2995 --default who columns
2996 PO_PDOI_MAINPROC_UTL_PVT.default_who_columns
2997 (
2998 x_last_update_date_tbl => l_lines.last_update_date_tbl,
2999 x_last_updated_by_tbl => l_lines.last_updated_by_tbl,
3000 x_last_update_login_tbl => l_lines.last_update_login_tbl,
3001 x_creation_date_tbl => l_lines.creation_date_tbl,
3002 x_created_by_tbl => l_lines.created_by_tbl,
3003 x_request_id_tbl => l_lines.request_id_tbl,
3004 x_program_application_id_tbl => l_lines.program_application_id_tbl,
3005 x_program_id_tbl => l_lines.program_id_tbl,
3006 x_program_update_date_tbl => l_lines.program_update_date_tbl
3007 );
3008 --Loop through all info line records
3009 FOR i IN 1.. l_lines.rec_count LOOP
3010
3011 l_lines.error_flag_tbl(i) := FND_API.g_FALSE;
3012
3013 l_lines.need_to_reject_flag_tbl(i) := FND_API.g_FALSE;
3014
3015 --l_lines.draft_id_tbl(i) := p_draft_id;
3016
3017 --Info line basic validations
3018 IF(l_lines.line_num_tbl(i) IS NULL) THEN
3019 l_lines.error_flag_tbl(i) := FND_API.g_TRUE;
3020 d_position := 10;
3021 IF (PO_LOG.d_proc) THEN
3022 PO_LOG.stmt(d_module, d_position, 'line_num cannot be null for info line : ', l_lines.intf_line_id_tbl(i));
3023 END IF;
3024 d_position := 20;
3025 IF (PO_LOG.d_proc) THEN
3026 PO_LOG.stmt(d_module, d_position, 'item_desc cannot be null for info line : ', l_lines.intf_line_id_tbl(i));
3027 END IF;
3028
3029 ELSIF(Nvl(l_lines.clm_info_flag_tbl(i),'N') = 'N') THEN
3030 l_lines.error_flag_tbl(i) := FND_API.g_TRUE;
3031 d_position := 30;
3032 IF (PO_LOG.d_proc) THEN
3033 PO_LOG.stmt(d_module, d_position, 'Incorrect info flag : ', l_lines.intf_line_id_tbl(i));
3034 END IF;
3035
3036 END IF;
3037
3038 d_position := 40;
3039 IF(Nvl(l_lines.error_flag_tbl(i),FND_API.g_FALSE) = FND_API.g_FALSE) THEN
3040 SELECT po_lines_s.nextval INTO l_po_line_id FROM sys.dual;
3041 --Stamping po_line_id & po_header_id
3042 l_lines.po_line_id_tbl(i) := l_po_line_id;
3043 l_lines.po_header_id_tbl(i) := l_lines.hd_po_header_id_tbl(i);
3044 IF (PO_LOG.d_proc) THEN
3045 PO_LOG.stmt(d_module, d_position, 'Stamped po_line_id : ', l_po_line_id);
3046 PO_LOG.stmt(d_module, d_position, 'Stamped po_header_id : ', l_lines.hd_po_header_id_tbl(i));
3047 END IF;
3048 END IF;
3049
3050 END LOOP;
3051
3052
3053 -- insert lines into line draft table
3054 PO_PDOI_MOVE_TO_DRAFT_TABS_PVT.insert_lines
3055 (
3056 x_lines => l_lines
3057 );
3058
3059 d_position := 90;
3060
3061 -- update po_lines_interface with po_line_id and line level action
3062 PO_PDOI_LINE_PROCESS_PVT.update_line_intf_tbl
3063 (
3064 x_lines => l_lines
3065 );
3066 --CLM PDOI Integration
3067 IF Nvl(PO_PDOI_PARAMS.g_request.clm_flag,'N') = 'Y'
3068 THEN
3069 --Call the set_clm_structure api to set clin slin structure
3070 set_clm_structure;
3071 --Call the api to convert base_line_num from interface to draft
3072 set_intf_base_line_num_to_dft;
3073 END IF;
3074
3075 -- reject lines with errors
3076 FOR i IN 1..l_lines.rec_count
3077 LOOP
3078 IF (l_lines.error_flag_tbl(i) = FND_API.g_TRUE OR
3079 l_lines.need_to_reject_flag_tbl(i) = FND_API.g_TRUE) THEN
3080 IF (PO_LOG.d_stmt) THEN
3081 PO_LOG.stmt(d_module, d_position, 'error flag',
3082 l_lines.error_flag_tbl(i));
3083 PO_LOG.stmt(d_module, d_position, 'reject flag',
3084 l_lines.need_to_reject_flag_tbl(i));
3085 PO_LOG.stmt(d_module, d_position, 'rejected intf line id',
3086 l_lines.intf_line_id_tbl(i));
3087 END IF;
3088
3089 l_rej_intf_line_id_tbl.EXTEND;
3090 l_rej_intf_line_id_tbl(l_rej_intf_line_id_tbl.COUNT) := l_lines.intf_line_id_tbl(i);
3091 END IF;
3092 END LOOP;
3093 PO_PDOI_UTL.reject_lines_intf
3094 (
3095 p_id_param_type => PO_PDOI_CONSTANTS.g_INTERFACE_LINE_ID,
3096 p_id_tbl => l_rej_intf_line_id_tbl,
3097 p_cascade => FND_API.g_TRUE
3098 );
3099 l_rej_intf_line_id_tbl.DELETE;
3100
3101 d_position := 110;
3102
3103 d_position := 100;
3104 EXCEPTION
3105 WHEN g_snap_shot_too_old THEN
3106 d_position := 120;
3107
3108 -- log errors
3109 PO_MESSAGE_S.add_exc_msg
3110 (
3111 p_pkg_name => d_pkg_name,
3112 p_procedure_name => d_api_name || '.' || d_position
3113 );
3114
3115 -- commit changes
3116 PO_PDOI_UTL.commit_work;
3117
3118 IF (l_lines_csr%ISOPEN) THEN
3119 CLOSE l_lines_csr;
3120 PO_PDOI_LINE_PROCESS_PVT.open_lines
3121 (
3122 p_data_set_type => p_data_set_type,
3123 p_max_intf_line_id => l_max_intf_line_id,
3124 x_lines_csr => l_lines_csr
3125 );
3126 END IF;
3127 END;
3128 END LOOP;
3129
3130 d_position := 130;
3131
3132 -- close the cursor
3133 IF (l_lines_csr%ISOPEN) THEN
3134 CLOSE l_lines_csr;
3135 END IF;
3136 IF (PO_LOG.d_proc) THEN
3137 PO_LOG.proc_end(d_module);
3138 END IF;
3139
3140 EXCEPTION
3141 WHEN OTHERS THEN
3142 IF (l_lines_csr%ISOPEN) THEN
3143 CLOSE l_lines_csr;
3144 END IF;
3145 PO_MESSAGE_S.add_exc_msg
3146 (
3147 p_pkg_name => d_pkg_name,
3148 p_procedure_name => d_api_name || '.' || d_position
3149 );
3150 RAISE;
3151 END process_info_lines;
3152
3153
3154
3155
3156 --------------------------------------------------------------------------------------------
3157 --------------------------------------------------------------------------------------------
3158
3159 /*This procedure will
3160 1. collect all slins in a cursor
3161 2. loop through each slin and stamp the group_line_id accordingly in po_lines_draft_all
3162 */
3163 PROCEDURE set_clm_structure
3164 IS
3165
3166 d_api_name CONSTANT VARCHAR2(30) := 'set_clm_structure';
3167 d_module CONSTANT VARCHAR2(255) := d_pkg_name || d_api_name || '.';
3168 d_position NUMBER;
3169 --Cursor to collect all slins
3170 CURSOR c_slins
3171 IS
3172 SELECT intf_lines.group_line_id, draft_lines.po_line_id,
3173 draft_lines.draft_id, draft_lines.po_header_id
3174 FROM po_lines_draft_all draft_lines, po_lines_interface intf_lines,
3175 po_headers_interface intf_headers
3176 WHERE intf_lines.group_line_id IS NOT NULL
3177 AND intf_lines.interface_header_id =
3178 intf_headers.interface_header_id
3179 AND intf_lines.line_num = draft_lines.line_num
3180 AND intf_headers.po_header_id = draft_lines.po_header_id
3181 AND intf_lines.processing_id = PO_PDOI_PARAMS.g_processing_id
3182 AND intf_headers.processing_round_num = PO_PDOI_PARAMS.g_current_round_num
3183 AND intf_headers.processing_id = PO_PDOI_PARAMS.g_processing_id
3184 AND draft_lines.draft_id = intf_headers.draft_id;
3185 BEGIN
3186
3187 IF (PO_LOG.d_proc) THEN
3188 PO_LOG.proc_begin(d_module);
3189 END IF;
3190 --loop through all slins
3191 FOR l_rec IN c_slins
3192 LOOP
3193 UPDATE po_lines_draft_all
3194 SET group_line_id =
3195 (SELECT pld.po_line_id
3196 FROM po_lines_interface pli, po_lines_draft_all pld
3197 WHERE 1 = 1
3198 AND pld.po_header_id = l_rec.po_header_id
3199 AND pld.group_line_id IS NULL
3200 AND pld.line_num = pli.line_num
3201 AND pli.interface_line_id = l_rec.group_line_id
3202 AND Nvl(pld.draft_id,l_rec.draft_id) = l_rec.draft_id)
3203 WHERE po_line_id = l_rec.po_line_id
3204 AND Nvl(draft_id,l_rec.draft_id) = l_rec.draft_id;
3205 END LOOP;
3206 IF (PO_LOG.d_proc) THEN
3207 PO_LOG.proc_end(d_module);
3208 END IF;
3209 EXCEPTION
3210 WHEN OTHERS
3211 THEN
3212 PO_MESSAGE_S.add_exc_msg
3213 (
3214 p_pkg_name => d_pkg_name,
3215 p_procedure_name => d_api_name || '.' || d_position
3216 );
3217 RAISE;
3218
3219 END set_clm_structure;
3220
3221
3222
3223
3224 PROCEDURE set_intf_base_line_num_to_dft
3225 IS
3226 d_api_name CONSTANT VARCHAR2(30) := 'set_intf_base_line_num_to_dft';
3227 d_module CONSTANT VARCHAR2(255) := d_pkg_name || d_api_name || '.';
3228 d_position NUMBER;
3229 l_clm_base_line_num_tbl PO_TBL_NUMBER;
3230 l_po_line_id_tbl PO_TBL_NUMBER;
3231
3232 BEGIN
3233
3234 IF (PO_LOG.d_proc) THEN
3235 PO_LOG.proc_begin(d_module);
3236 END IF;
3237 --collect po_line_id and corressponding clm_base_line_num for all base lines
3238 SELECT clm_base_line_num,
3239 po_line_id
3240 BULK COLLECT INTO l_clm_base_line_num_tbl, l_po_line_id_tbl
3241 FROM po_lines_interface
3242 WHERE processing_id = PO_PDOI_PARAMS.g_processing_id
3243 AND Nvl(clm_option_indicator,'*') = 'O';
3244
3245 d_position := 10;
3246 IF (PO_LOG.d_proc) THEN
3247 PO_LOG.stmt(d_module, d_position, 'clm base line num : ', l_po_line_id_tbl);
3248 END IF;
3249
3250 FORALL i IN 1..l_clm_base_line_num_tbl.Count
3251 UPDATE po_lines_draft_all
3252 SET clm_base_line_num = ( SELECT po_line_id FROM po_lines_interface
3253 WHERE interface_line_id = l_clm_base_line_num_tbl(i)
3254 )
3255 WHERE l_clm_base_line_num_tbl(i) IS NOT NULL
3256 AND po_line_id = l_po_line_id_tbl(i);
3257
3258 IF (PO_LOG.d_proc) THEN
3259 PO_LOG.proc_end(d_module);
3260 END IF;
3261
3262 EXCEPTION
3263 WHEN OTHERS
3264 THEN
3265 PO_MESSAGE_S.add_exc_msg
3266 (
3267 p_pkg_name => d_pkg_name,
3268 p_procedure_name => d_api_name || '.' || d_position
3269 );
3270 RAISE;
3271
3272 END set_intf_base_line_num_to_dft;
3273
3274 --Bug 13343886
3275 PROCEDURE gather_stats(p_table_name IN VARCHAR2,p_api_name IN VARCHAR2,p_position IN VARCHAR2)
3276 IS
3277 l_status VARCHAR2(1);
3278 l_industry VARCHAR2(1);
3279 l_schema VARCHAR2(30);
3280 l_return_status BOOLEAN;
3281 BEGIN
3282 l_return_status := FND_INSTALLATION.get_app_info('PO', l_status,
3283 l_industry, l_schema);
3284 IF (l_return_status) THEN
3285 FND_STATS.gather_table_stats ( ownname => l_schema, tabname => p_table_name);
3286 END IF;
3287 EXCEPTION
3288 WHEN OTHERS THEN
3289 PO_MESSAGE_S.add_exc_msg
3290 ( p_pkg_name => d_pkg_name,
3291 p_procedure_name => p_api_name || '.' || p_position
3292 );
3293 RAISE;
3294 END GATHER_STATS;
3295 --Bug 13343886
3296 END PO_PDOI_MAINPROC_PVT;