DBA Data[Home] [Help]

PACKAGE BODY: APPS.OPI_DBI_COMMON_MOD_INIT_PKG

Source


1 PACKAGE BODY opi_dbi_common_mod_init_pkg AS
2 /*$Header: OPIDCMODIB.pls 120.1 2005/08/10 01:59:36 sberi noship $ */
3 
4 /*++++++++++++++++++++++++++++++++++++++++*/
5 /* Function and procedure declarations in this file but not in spec*/
6 /*++++++++++++++++++++++++++++++++++++++++*/
7 
8 PROCEDURE seed_run_log_initial (errbuf OUT NOCOPY VARCHAR2,
9                                 retcode OUT NOCOPY NUMBER,
10                                 p_global_start_date IN DATE);
11 
12 FUNCTION txn_id_init_setup (p_etl_id IN NUMBER, p_source IN NUMBER)
13     RETURN BOOLEAN;
14 
15 FUNCTION collect_date_init_setup (p_etl_id IN NUMBER, p_source IN NUMBER)
16     RETURN BOOLEAN;
17 
18 /*----------------------------------------*/
19 
20 
21 /*++++++++++++++++++++++++++++++++++++++++*/
22 /* PACKAGE LEVEL CONSTANTS */
23 /*++++++++++++++++++++++++++++++++++++++++*/
24 
25 s_pkg_name CONSTANT VARCHAR2 (50) := 'opi_dbi_common_mod_init_pkg';
26 s_ERROR CONSTANT NUMBER := -1;   -- concurrent manager error code
27 s_WARNING CONSTANT NUMBER := 1;  -- concurrent manager warning code
28 s_SUCCESS CONSTANT NUMBER := 0;  -- concurrent manager success code
29 
30 /*++++++++++++++++++++++++++++++++++++++++*/
31 /*  Package level variables for session info-
32     including schema name for truncating and
33     collecting stats */
34 /*++++++++++++++++++++++++++++++++++++++++*/
35 
36 s_opi_schema      VARCHAR2(30);
37 s_status          VARCHAR2(30);
38 s_industry        VARCHAR2(30);
39 
40 /*----------------------------------------*/
41 
42 /*++++++++++++++++++++++++++++++++++++++++*/
43 /*  Package level variables for the logged
44     in user.
45 /*++++++++++++++++++++++++++++++++++++++++*/
46 
47 s_user_id NUMBER := nvl(fnd_global.user_id, -1);
48 s_login_id NUMBER := nvl(fnd_global.login_id, -1);
49 s_program_id NUMBER:= nvl (fnd_global.conc_program_id, -1);
50 s_program_login_id NUMBER := nvl (fnd_global.conc_login_id, -1);
51 s_program_application_id NUMBER := nvl (fnd_global.prog_appl_id,  -1);
52 s_request_id NUMBER := nvl (fnd_global.conc_request_id, -1);
53 
54 /*----------------------------------------*/
55 
56 /*++++++++++++++++++++++++++++++++++++++++*/
57 /*  Package level exceptions defined for
58     clearer error handling. */
59 /*++++++++++++++++++++++++++++++++++++++++*/
60 
61 -- exception to raise if unable to get schema information
62 schema_info_not_found EXCEPTION;
63 PRAGMA EXCEPTION_INIT (schema_info_not_found, -20000);
64 
65 -- exception to raise if unable to ge
66 txn_id_bounds_missing EXCEPTION;
67 PRAGMA EXCEPTION_INIT (txn_id_bounds_missing, -20001);
68 
69 -- exception to raise if unable find NULL collection dates
70 collect_date_bounds_missing EXCEPTION;
71 PRAGMA EXCEPTION_INIT (collect_date_bounds_missing, -20002);
72 
73 -- exception to raise if global parameters such as global
74 -- start date and global currency code are not available
75 global_setup_missing EXCEPTION;
76 PRAGMA EXCEPTION_INIT (global_setup_missing, -20003);
77 
78 
79 -- Stage failure.
80 stage_failure EXCEPTION;
81 PRAGMA EXCEPTION_INIT (stage_failure, -20004);
82 
83 -- Common Module Initial Load has not been run
84 run_common_mod_init EXCEPTION;
85 PRAGMA EXCEPTION_INIT (run_common_mod_init, -20005);
86 
87 /*----------------------------------------*/
88 
89 /*  run_common_module_init
90 
91     The common Module initial load is responsible for:
92     1. Computing ETL bounds for the first time
93 
94     This function does not return with an exception in case of error
95     but ends with a retcode of error. However helper functions are
96     expected to throw exceptions. We do not look at the retcode/errbuf
97     for helper functions. If a helper function fails, it is expected
98     to write a error message to the log and to throw an exception
99     back to this wrapper function.
100 
101     Date        Author              Action
102     04/17/03    Dinkar Gupta        Wrote Function
103     07/01/05	Sandeep Beri	    Modified Procedure for R12
104 				    Commom Module does not call WIP
105 				    Completions and Job Master after
106 				    its successful completion.
107 */
108 
109 PROCEDURE run_common_module_init (errbuf OUT NOCOPY VARCHAR2,
110                                   retcode OUT NOCOPY NUMBER)
111 IS
112 
113     l_proc_name VARCHAR2 (60) := 'run_common_module_init';
114     l_stmt_id NUMBER := 0;
115 
116     l_global_start_date DATE := NULL;
117 
118     l_bounds_warning BOOLEAN := false;
119 
120 BEGIN
121 
122     -- get session parameters
123     l_stmt_id := 10;
124     IF (NOT (fnd_installation.get_app_info('OPI', s_status, s_industry,
125                                            s_opi_schema))) THEN
126         RAISE schema_info_not_found;
127     END IF;
128 
129     -- check if the global set up is good
130     l_stmt_id := 20;
131     IF (NOT (check_global_setup ())) THEN
132         RAISE global_setup_missing;
133     END IF;
134 
135     -- get the DBI global start date
136     l_stmt_id := 30;
137     l_global_start_date := trunc (bis_common_parameters.get_global_start_date);
138 
139     -- compute the ETL bounds for the first time.
140     l_stmt_id := 40;
141     compute_initial_etl_bounds (errbuf, retcode, l_global_start_date,
142                                 s_opi_schema);
143 
144     -- check if stage succeeded
145     l_stmt_id := 41;
146     IF (retcode = s_ERROR) THEN
147         RAISE stage_failure;
148     END IF;
149 
150     -- check if some bounds are uncosted before calling any other
151     -- procedure that can wipe out the stop reason code
152     l_stmt_id := 50;
153     l_bounds_warning := bounds_uncosted ();
154 
155     -- Print the discrete org collection bounds
156     l_stmt_id := 60;
157     print_opi_org_bounds;
158 
159     -- if uncosted transactions were found, return a warning.
160     l_stmt_id := 70;
161     IF (l_bounds_warning) THEN
162 
163         BIS_COLLECTION_UTILITIES.PUT_LINE
164             ('Common Module Initial Load terminated with warnings.');
165         retcode := s_WARNING;
166         errbuf := 'Common Module Initial Load Found Uncosted Transactions. ';
167 
168     ELSE
169         -- terminate successfully
170         BIS_COLLECTION_UTILITIES.PUT_LINE
171             ('Common Module Initial Load terminated successfully.');
172         retcode := s_SUCCESS;
173         errbuf := '';
174     END IF;
175 
176 EXCEPTION
177 
178     WHEN schema_info_not_found THEN
179         rollback;
180 
181         BIS_COLLECTION_UTILITIES.PUT_LINE (s_pkg_name || '.' ||
182                                            l_proc_name || ' ' ||
183                                            '#' || l_stmt_id ||
184                                            ': ' ||  SQLERRM);
185 
186         retcode := s_ERROR;
187         errbuf := s_pkg_name || '.' || l_proc_name || ' ' || '#' ||
188                   l_stmt_id || ': ' ||
189                   'Common Module Initial Load failed to get OPI schema info.';
190         return;
191 
192     WHEN global_setup_missing THEN
193         rollback;
194 
195         BIS_COLLECTION_UTILITIES.PUT_LINE (s_pkg_name || '.' ||
196                                            l_proc_name || ' ' ||
197                                            '#' || l_stmt_id ||
198                                            ': ' ||  SQLERRM);
199 
200         retcode := s_ERROR;
201         errbuf := s_pkg_name || '.' || l_proc_name || ' ' || '#' ||
202                   l_stmt_id || ': ' ||
203                   'Common Module Initial Load could not find global setup of global start date and global currency code.';
204         return;
205 
206     WHEN stage_failure THEN
207         rollback;
208 
209         BIS_COLLECTION_UTILITIES.PUT_LINE (s_pkg_name || '.' ||
210                                            l_proc_name || ' ' ||
211                                            '#' || l_stmt_id ||
212                                            ': ' ||  SQLERRM);
213         retcode := s_ERROR;
214         errbuf := s_pkg_name || '.' || l_proc_name || ' ' || '#' ||
215                   l_stmt_id || ': ' ||
216                   'Common Module Initial Load failed.';
217         return;
218 
219     WHEN OTHERS THEN
220         rollback;
221 
222         BIS_COLLECTION_UTILITIES.PUT_LINE (s_pkg_name || '.' ||
223                                            l_proc_name || ' ' ||
224                                            '#' || l_stmt_id ||
225                                            ': ' ||  SQLERRM);
226 
227         retcode := s_ERROR;
228         errbuf := s_pkg_name || '.' || l_proc_name || ' ' || '#' ||
229                   l_stmt_id || ': ' || 'Common Module Initial Load Failed.';
230         return;
231 
232 END run_common_module_init;
233 
234 
235 /*  compute_initial_etl_bounds
236 
237     Computing the initial bounds for the all the ETLs.
238 
239     These include:
240         Job Transactions ETL - WIP Completions, Actual Usage and Scrap
241         Actual Resource Usage
242         Resource Variance
243         Job Master
244 
245     The computation can be broken down into the following stages:
246 
247     1.  Truncate the log and audit tables, OPI_DBI_RUN_LOG_CURR and
248         OPI_DBI_RUN_LOG_AUDIT respectively.
249     2.  Populate the initial data for all the different ETLs in the
250         current log table OPI_DBI_RUN_LOG_CURR.
251     3.  Compute the end bounds for all the rows in the current log table,
252         OPI_DBI_RUN_LOG_CURR.
253 
254     Data is committed when all steps are successful.
255 
256     Parameters:
257     p_global_start_date - DBI global start date. Expecting it to be
258                           trunc'ed already.
259     p_opi_schema - Schema name for OPI.
260 
261     Date        Author              Action
262     04/17/03    Dinkar Gupta        Wrote Function
263     08/14/03    Dinkar Gupta        Changed the bounds computation to
264                                     perform only inserts for the initial load.
265                                     All updates removed on recommendation
266                                     of performance team.
267 */
268 
269 
270 PROCEDURE compute_initial_etl_bounds (errbuf OUT NOCOPY VARCHAR2,
271                                       retcode OUT NOCOPY NUMBER,
272                                       p_global_start_date IN DATE,
273                                       p_opi_schema IN VARCHAR2)
274 IS
275     l_proc_name VARCHAR2 (60) := 'compute_initial_etl_bounds';
276     l_stmt_id NUMBER := 0;
277 
278 
279 BEGIN
280 
281     -- initial load requires clean tables.
282     l_stmt_id := 10;
283     EXECUTE IMMEDIATE ('TRUNCATE TABLE ' || p_opi_schema || '.' ||
284                        'OPI_DBI_RUN_LOG_AUDIT');
285 
286     l_stmt_id := 20;
287     EXECUTE IMMEDIATE ('TRUNCATE TABLE ' || p_opi_schema || '.' ||
288                        'OPI_DBI_RUN_LOG_CURR');
289 
290     -- Create all the data for all the different MAnufacuturing Management
291     -- ETLs in OPI_DBI_RUN_LOG_CURR
292     l_stmt_id := 30;
293     seed_run_log_initial (errbuf, retcode, p_global_start_date);
294 
295     -- success so far, then commit everything in one shot
296     l_stmt_id := 50;
297     commit;
298 
299     -- terminate successfully
300     retcode := s_SUCCESS;
301     errbuf := '';
302 
303 EXCEPTION
304 
305     WHEN OTHERS THEN
306         rollback;
307 
308         BIS_COLLECTION_UTILITIES.PUT_LINE (s_pkg_name || '.' ||
309                                            l_proc_name || ' ' ||
310                                            '#' || l_stmt_id ||
311                                            ': ' ||  SQLERRM);
312 
313         retcode := s_ERROR;
314         errbuf := s_pkg_name || '.' || l_proc_name || ' ' ||
315                   '#' || l_stmt_id || ': ' ||
316                   'Failed to compute bounds for the initial load.';
317         RAISE;   -- propagate exception to wrapper
318 
319 END compute_initial_etl_bounds;
320 
321 
322 /* seed_run_log_initial
323 
324     The following ETL bounds need to be computed and seeded in the
325     OPI_DBI_RUN_LOG_CURR table:
326 
327     1. Job Transaction ETL  (WIP Completions, Actual Usage and Scrap)
328             OPI sourced rows --
329                 One row per discrete org with the start_txn_id as the first
330                 transaction id in MMT after global start date.
331 
332             OPM sourced rows --
333                 One row with the from bound date as Global Start Date and to
334 		bound date as the sysdate with date and time taken during the
335 		run of this program. The organization id for thsi one row would
336 		be NULL.
337 
338     4. Actual Resource Usage ETL
339             OPI sourced rows --
340                 One row with start_txn_id as the first transaction id
341                 in WT after global start date.
342 
343 	    OPM sourced rows --
344                 One row with the from bound date as Global Start Date and to
345 		bound date as the sysdate with date and time taken during the
346 		run of this program. The organization id for thsi one row would
347 		be NULL.
348 
349     5. Resource Variance  ETL
350             OPI sourced rows --
351                 One row with the from bound date as Global Start Date and to
352 		bound date as the sysdate with date and time taken during the
353 		run of this program.
354 
355             OPM sourced rows --
356                 One row with the from bound date as Global Start Date and to
357 		bound date as the sysdate with date and time taken during the
358 		run of this program.
359 
360     6. Resource Variance  ETL
361             OPI sourced rows --
362                 One row with the from bound date as Global Start Date and to
363 		bound date as the sysdate with date and time taken during the
364 		run of this program.
365 
369 		run of this program.
366             OPM sourced rows --
367                 One row with the from bound date as Global Start Date and to
368 		bound date as the sysdate with date and time taken during the
370 
371 
372     The goal of one centralized seeding function is to minimize the
373     number of SQLs to populate the data.
374 
375     Thus for OPI sourced rows:
376         The Job Transactions ETL -Scrap, WIP Completion and Actual Usage
377         rows will be populated in the one SQL from MMT.
378 
379         The Actual Resource ETL row will be populated in one SQL from WT.
380 
381     For the OPM rows:
382         All OPM Rows for all ETL's would be populated in one SQL which would set
383 	the from bound date as the Global Start Date and the to bound date as
384 	the sysdate.
385 
386     Comment on max bounds on tables (OPI):
387     Note that for all bounds, we pick max + 1. That is because the
388     the upper bound is meant to be strictly higher than the
389     id's to be collected. Since all the id sequences are discrete
390     and increasing, just adding +1 ensures that if we start next time
391     at the max + 1 of this run, then no transaction_id will be
392     ignored.
393     Also, max + 1 is not a real transaction_id and may never be.
394     Since the bounds should never be NULL, and the start id's are
395     always seeded to be 0, next_Start must be 0 for empty tables.
396 
397 
398     DO NOT COMMIT ANY DATA HERE!!! LEAVE THAT FOR THE CALLING FUNCTION.
399 
400     Paramters:
401     p_global_start_date - DBI global start date. Expect it to be
402                           trunc'ed already.
403 
404     Date        Author              Action
405     04/17/03    Dinkar Gupta        Wrote Function
406     07/01/05    Sandeep Beri	    Modified OPM logic of computing bounds
407 				    Bounds for all OPM ETL's are now date bounds.
408 				    Store GSD (trunc'd) as the from bound date
409 				    and a snapshot of the sysdate(with date time)
410 				    as the to bound date. OPM bounds no longer come
411 				    from GL_SUBR_LED.
412 */
413 
414 
415 PROCEDURE seed_run_log_initial (errbuf OUT NOCOPY VARCHAR2,
416                                 retcode OUT NOCOPY NUMBER,
417                                 p_global_start_date IN DATE)
418 IS
419 
420     l_proc_name VARCHAR2 (60) := 'seed_run_log_initial';
421     l_stmt_id NUMBER := 0;
422 
423     -- the highest transaction in MMT + 1.
424     l_max_mmt_plus_one NUMBER := NULL;
425 
426     -- the first transaction in MMT past global start date
427     l_mmt_start_txn_id NUMBER := NULL;
428 
429     -- the highest transaction in WT + 1.
430     l_max_wt_plus_one NUMBER := NULL;
431 
432     -- the first transaction in WT past global start date
433     l_wt_start_txn_id NUMBER := NULL;
434 
435     -- Snapshotting sysdate with date time in a local variable
436     l_to_bound_date DATE;
437 
438  BEGIN
439 
440     -- Select the max transaction id from MMT
441     -- for the transaction id bounds.
442     -- If the table is empty, then make the start at transaction id 0.
443 
444     l_stmt_id := 10;
445     SELECT nvl (max (transaction_id), -1) + 1
446       INTO l_max_mmt_plus_one
447       FROM mtl_material_transactions;
448 
449     -- Storing sysdate in a local variable for insertion into log as we do not want to miss any
450     -- horizon between OPM and OPI inserts.
451     l_stmt_id := 20;
452     SELECT sysdate
453     INTO l_to_bound_date
454     FROM DUAL;
455 
456     -- Select the start transaction id's in MMT
457     -- past the global start date.
458     -- If there are no transactions past the global start date,
459     -- then just pick a transaction_id one higher than the max of
460     -- of MMT.
461 
462     l_stmt_id := 30;
463     SELECT /*+ parallel(mtl_material_transactions) */
464         nvl (min (transaction_id), l_max_mmt_plus_one)
465       INTO l_mmt_start_txn_id
466       FROM mtl_material_transactions
467       WHERE transaction_date >= p_global_start_date;
468 
469     -- Create a row for each discrete org for the Job Transactions ETL
470     --(Scrap, WIP completions, Material Usage) with the start
471     -- transaction_id set to the first transaction in MMT after the
472     -- global_start_date.
473     -- Note the last_transaction_date here, it is computed for PTP etl.
474     -- Note that this is max transaction date between the start and stop
475     -- transactions, because the last transaction itself could have been
476     -- backdated.
477 
478     l_stmt_id := 50;
479     INSERT /*+ append parallel (opi_dbi_run_log_curr) */
480     INTO opi_dbi_run_log_curr (
481         organization_id,
482         source,
483         last_collection_date,
484         start_txn_id,
485         next_start_txn_id,
486 	from_bound_date,
487 	to_bound_date,
488         etl_id,
489         stop_reason_code,
490         last_transaction_date,
491         last_update_date,
492         creation_date,
493         last_updated_by,
494         created_by,
495         last_update_login,
496 	program_id,
500     SELECT /*+ parallel (bounds) parallel (etls) */
497         program_login_id,
498         program_application_id,
499         request_id)
501         bounds.organization_id,
502         OPI_SOURCE,         -- OPI rows
503         NULL,
504         bounds.start_txn_id,
505         bounds.next_start_txn_id,
506 	NULL,
507 	NULL,
508         JOB_TXN_ETL,
509         bounds.stop_reason_code,
510         decode (bounds.stop_reason_code,
511                 STOP_UNCOSTED, bounds.last_transaction_date,
512                 sysdate),
513         sysdate,
514         sysdate,
515         s_user_id,
516         s_user_id,
517         s_login_id,
518 	s_program_id,
519         s_program_login_id,
520         s_program_application_id,
521         s_request_id
522       FROM
523         (SELECT /*+ parallel (mmt_bounds) parallel (mmt) */
524                mmt_bounds.organization_id,
525                mmt_bounds.start_txn_id,
526                mmt_bounds.next_start_txn_id,
527                trunc (max (mmt.transaction_date))
528                last_transaction_date,
529                mmt_bounds.stop_reason_code
530           FROM
531             (SELECT /* parallel (uncosted) parallel (orgs) */
532                     orgs.organization_id,
533                     l_mmt_start_txn_id start_txn_id,
534                     nvl (uncosted.uncosted_id, l_max_mmt_plus_one)
535                     next_start_txn_id,
536                     decode (uncosted.uncosted_id,
537                             NULL, STOP_ALL_COSTED,
538                             STOP_UNCOSTED) stop_reason_code
539               FROM (SELECT /*+ PARALLEL (mtl_material_transactions) */
540                            min (transaction_id) uncosted_id,
541                            organization_id
542                      FROM mtl_material_transactions
543                      WHERE costed_flag IN ('N', 'E')
544                      AND transaction_id > l_mmt_start_txn_id
545                      GROUP BY organization_id) uncosted,
546                   (SELECT /*+ parallel (mtl_parameters) */
547                           organization_id
548                      FROM mtl_parameters
549                      WHERE process_enabled_flag <> 'Y') orgs
550               WHERE orgs.organization_id = uncosted.organization_id (+))
551              mmt_bounds,
552              mtl_material_transactions mmt
553           WHERE mmt_bounds.organization_id = mmt.organization_id (+)
554             AND (mmt.transaction_id BETWEEN mmt_bounds.start_txn_id AND
555                                        mmt_bounds.next_start_txn_id
556                  OR mmt.transaction_id IS NULL)
557           GROUP BY
558                 mmt_bounds.organization_id,
559                 mmt_bounds.start_txn_id,
560                 mmt_bounds.next_start_txn_id,
561                 mmt_bounds.stop_reason_code) bounds;
562 
563     -- commit due to insert append
564     l_stmt_id := 52;
565     commit;
566 
567     -- Create a row for process for each ETL with the
568     -- from bound date set to the GSD and the to bound
569     -- date as the date time snapshot taken above in
570     -- the local variable l_to_bound_date.
571     -- Organization id would be null for such OPM rows.
572     l_stmt_id := 60;
573     INSERT INTO opi_dbi_run_log_curr (
574         organization_id,
575         source,
576         last_collection_date,
580 	to_bound_date,
577         start_txn_id,
578         next_start_txn_id,
579 	from_bound_date,
581         etl_id,
582         stop_reason_code,
583         last_transaction_date,
584         last_update_date,
585         creation_date,
586         last_updated_by,
587         created_by,
588         last_update_login,
589 	program_id,
590         program_login_id,
591         program_application_id,
592         request_id)
593     SELECT
594         NULL,
595         OPM_SOURCE,         -- OPM rows
596         NULL,
597         NULL,
598         NULL,
599         p_global_start_date,
600         l_to_bound_date,
601         etls.etl_id,
602         NULL,
603         sysdate,
604         sysdate,
605         sysdate,
606         s_user_id,
607         s_user_id,
608         s_login_id,
609 	s_program_id,
610         s_program_login_id,
611         s_program_application_id,
612         s_request_id
613       FROM
614         (SELECT JOB_TXN_ETL etl_id FROM dual
615          UNION ALL
616          SELECT ACTUAL_RES_ETL FROM dual
617 	 UNION ALL
618          SELECT RESOURCE_VAR_ETL FROM dual
619 	 UNION ALL
620          SELECT JOB_MASTER_ETL FROM dual) etls;
621 
622 
623     -- Max bounds for the Actual Resource Utilization ETL
624     l_stmt_id := 70;
625     SELECT nvl (max (transaction_id), -1) + 1
626       INTO l_max_wt_plus_one
627       FROM wip_transactions;
628 
629     -- start bound for actual resource utilization ETL
630     l_stmt_id := 90;
631     SELECT /*+ index_ffs(wip_transactions) parallel_index(wip_transactions) */
632         nvl (min (transaction_id), l_max_wt_plus_one)
633       INTO l_wt_start_txn_id
634       FROM wip_transactions
635       WHERE transaction_date >= p_global_start_date;
636 
637     -- For the Actual Resource Usage create a row:
638     -- for OPI with start_txn_id as the first transaction past global
639     -- start date in WT. There cannot be any uncosted resource transactions.
640 
641         l_stmt_id := 110;
642     INSERT INTO opi_dbi_run_log_curr (
643         organization_id,
644         source,
645         last_collection_date,
646         start_txn_id,
647         next_start_txn_id,
648 	from_bound_date,
649 	to_bound_date,
650         etl_id,
651         stop_reason_code,
652         last_transaction_date,
653         last_update_date,
654         creation_date,
655         last_updated_by,
656         created_by,
657         last_update_login,
658 	program_id,
659         program_login_id,
660         program_application_id,
661         request_id)
662     SELECT
663         NULL,
664         src.source_type,
665         NULL,
666 	l_wt_start_txn_id,
667 	l_max_wt_plus_one,
668         NULL,
669 	NULL,
670         ACTUAL_RES_ETL,
671         NULL,
672         sysdate,
673         sysdate,
674         sysdate,
675         s_user_id,
676         s_user_id,
677         s_login_id,
678 	s_program_id,
679         s_program_login_id,
680         s_program_application_id,
681         s_request_id
682       FROM
683         (SELECT OPI_SOURCE source_type FROM dual
684         ) src;
685 
686 
687     -- For Resource and Job Master ETLs, we need from bound date
688     -- and to bound date for OPI also.
689 
690     l_stmt_id := 120;
691 
692      INSERT INTO opi_dbi_run_log_curr (
693         organization_id,
694         source,
695         last_collection_date,
696         start_txn_id,
697         next_start_txn_id,
698 	from_bound_date,
699 	to_bound_date,
703         last_update_date,
700         etl_id,
701         stop_reason_code,
702         last_transaction_date,
704         creation_date,
705         last_updated_by,
706         created_by,
707         last_update_login,
708 	program_id,
709         program_login_id,
710         program_application_id,
711         request_id)
712     SELECT
713         NULL,
714         OPI_SOURCE,         -- OPI rows
715         NULL,
716         NULL,
717         NULL,
718         p_global_start_date,
719         l_to_bound_date,
720         etls.etl_id,
721         NULL,
722         sysdate,
723         sysdate,
724         sysdate,
725         s_user_id,
726         s_user_id,
727         s_login_id,
728 	s_program_id,
729         s_program_login_id,
730         s_program_application_id,
731         s_request_id
732       FROM
733         (SELECT RESOURCE_VAR_ETL etl_id FROM dual
734 	 UNION ALL
735          SELECT JOB_MASTER_ETL FROM dual) etls;
736         -- terminate successfully
737     l_stmt_id := 130;
738     retcode := s_SUCCESS;
739     errbuf := '';
740 
741 
742 EXCEPTION
743 
744     WHEN OTHERS THEN
745         rollback;
746 
747         BIS_COLLECTION_UTILITIES.PUT_LINE (s_pkg_name || '.' ||
748                                            l_proc_name || ' ' ||
749                                            '#' || l_stmt_id ||
750                                            ': ' ||  SQLERRM);
751 
752         retcode := s_ERROR;
753         errbuf := s_pkg_name || '.' || l_proc_name || ' ' ||
754                   '#' || l_stmt_id || ': ' ||
755                   'Failed to seed initial data into the run log tables.';
756         RAISE;    -- propagate exception to wrapper
757 
758 
759 END seed_run_log_initial;
760 
761 
762 /*  init_end_bounds_setup
763 
764     API called by ETLs to ensure that the bounds they are running for are
765     set up correctly.
766 
767     OPI : For the Material and Actual Resource Usage ETLs,
768     This requires checking if all the next_start_txn_id values are not null
769     for the given ETL and the source.
770 
771     OPM : All ETL's and OPI: Job Master and Resource Variance
772     This requires checking if all the dates voz. from_bound_date,
773     to_bound_date and last_collection_date are set up correctly or not.
774 
775     Parameters:
776     p_etl_id - etl_id of ETL invoking API.
777     p_source - 1 for OPI, 2 for OPM
778 
779     Return:
780     l_bounds_valid - true if the bounds are valid
781                      false o.w.
782 
783     Date        Author              Action
784     04/23/03    Dinkar Gupta        Wrote Function
785     07/01/05	Sandeep Beri	    Modified the IF conditions to the
786 				    transaction id set uo check call as
787 				    in R12, no OPM ETL would have txn id bounds.
788 */
789 FUNCTION init_end_bounds_setup (p_etl_id IN NUMBER, p_source IN NUMBER)
790     RETURN BOOLEAN
791 IS
792 
793     l_proc_name VARCHAR2 (60) := 'init_end_bounds_setup';
794     l_stmt_id NUMBER := 0;
795 
796     l_exists NUMBER := NULL;
797     l_bounds_valid BOOLEAN := true;
798 
799 BEGIN
800 
801     -- Ensure the log table is not empty
802     l_stmt_id := 5;
803     BEGIN
804         SELECT 1
805         INTO l_exists
806         FROM dual
807         WHERE (EXISTS (SELECT source
808                          FROM opi_dbi_run_log_curr
809                          WHERE rownum = 1));
810 
811     EXCEPTION
812         WHEN NO_DATA_FOUND THEN
813             RAISE run_common_mod_init;
814 
815     END;
816 
817     -- For the Job Transactions ETL
818     -- and Actual Resource Usage (OPI), the behaviour is based on transaction
819     -- id's
820     l_stmt_id := 10;
821     IF ( ((p_etl_id = JOB_TXN_ETL) OR
822          (p_etl_id = ACTUAL_RES_ETL)) AND p_source = OPI_SOURCE) THEN
823        --{
824        l_bounds_valid := txn_id_init_setup (p_etl_id, p_source);
825        --}
826 
827     -- For Resource Variance and Job Master in OPI and all OPM ETL's, the behaviour is
828     -- based on dates.
829     ELSE
830     --{
831         l_bounds_valid := collect_date_init_setup (p_etl_id, p_source);
832     --}
833     END IF;
834 
835 
836     return l_bounds_valid;
837 
838 EXCEPTION
839 
840 
841     WHEN run_common_mod_init THEN
842         BIS_COLLECTION_UTILITIES.PUT_LINE (s_pkg_name || '.' ||
843                                            l_proc_name || ' ' ||
844                                            '#' || l_stmt_id ||
845                                            ': ' || 'Run time bounds have not been set up. Please run the initial load request set.');
846 
850 
847         l_bounds_valid := false;
848         return l_bounds_valid;
849 
851     WHEN OTHERS THEN
852         rollback;
853 
854         BIS_COLLECTION_UTILITIES.PUT_LINE (s_pkg_name || '.' ||
855                                            l_proc_name || ' ' ||
856                                            '#' || l_stmt_id ||
857                                            ': ' || SQLERRM);
858 
859         l_bounds_valid := false;
860         return l_bounds_valid;
861 
862 END init_end_bounds_setup;
863 
864 /*  txn_id_init_setup
865 
866     Ensure that all the txn_id bounds are correctly setup for
867     the initial load of the ETL with the source passed in as arguments.
868 
869     Right now, this requires checking that the start_txn_id
870     and next_start_txn_id columns are non-null for all the rows of the ETL
871     and source.
872 
873     Parameters:
874     p_etl_id - etl_id of ETL invoking API.
875     p_source - 1 for OPI, 2 for OPM
876 
877     Return:
878     l_bounds_valid - true if the bounds are valid
879                      false o.w.
880 
881     Date        Author              Action
882     04/23/03    Dinkar Gupta        Wrote Function
883     07/23/03    Dinkar Gupta        Also make sure that the common
884                                     module log table is not empty i.e.
885                                     the basic data has been seeded.
886 */
887 FUNCTION txn_id_init_setup (p_etl_id IN NUMBER, p_source IN NUMBER)
888     RETURN BOOLEAN
889 IS
890 
891     l_proc_name VARCHAR2 (60) := 'txn_id_init_setup';
892     l_stmt_id NUMBER := 0;
893 
894     l_bounds_valid BOOLEAN := true;
895 
896     l_exists NUMBER := NULL;
897 
898 BEGIN
899 
900     -- Ensure that all the start_txn_id's are non-null
901     l_stmt_id := 10;
902     BEGIN
903         SELECT 1
904         INTO l_exists
905         FROM dual
906         WHERE (EXISTS (SELECT start_txn_id
907                          FROM opi_dbi_run_log_curr
908                          WHERE start_txn_id IS NULL
909                            AND source = p_source
910                            AND etl_id = p_etl_id));
911 
912         RAISE txn_id_bounds_missing; -- found a missing next_start_txn_id
913 
914     EXCEPTION
915         WHEN NO_DATA_FOUND THEN
916             l_bounds_valid := true;
917     END;
918 
919     -- Ensure that all the next_start_txn_id's are non-null
920     l_stmt_id := 20;
921     BEGIN
922         SELECT 1
923         INTO l_exists
924         FROM dual
925         WHERE (EXISTS (SELECT next_start_txn_id
926                          FROM opi_dbi_run_log_curr
927                          WHERE next_start_txn_id IS NULL
928                            AND source = p_source
929                            AND etl_id = p_etl_id));
930 
931         RAISE txn_id_bounds_missing; -- found a missing start_txn_id
932 
933     EXCEPTION
934         WHEN NO_DATA_FOUND THEN
935             l_bounds_valid := true;
936     END;
937 
938 
939     return l_bounds_valid;
940 
941 EXCEPTION
942 
943     WHEN txn_id_bounds_missing THEN
944         BIS_COLLECTION_UTILITIES.PUT_LINE (s_pkg_name || '.' || l_proc_name || ' ' ||
945                               '#' || l_stmt_id || ': ' ||
946                               'Found missing transaction_id bounds for ETL ' ||
947                               p_etl_id || ' source ' || p_source || '.');
948         l_bounds_valid := false;
949         return l_bounds_valid;
950 
951     WHEN OTHERS THEN
952         rollback;
953 
954         BIS_COLLECTION_UTILITIES.PUT_LINE (s_pkg_name || '.' ||
955                                            l_proc_name || ' ' ||
956                                            '#' || l_stmt_id ||
957                                            ': ' || SQLERRM);
958 
959         l_bounds_valid := false;
960         return l_bounds_valid;
961 
962 END txn_id_init_setup;
963 
964 /*  collect_date_init_setup
965 
966     Ensure that all the collection date bounds are correctly setup for
967     the initial load of the ETL with the source passed in as arguments.
968 
972 
969     This requires checking that the last_collection_date is
970     NULL. Also it checks that the from_bound_date and the to_bound_date
971     are not null.
973     Parameters:
974     p_etl_id - etl_id of ETL invoking API.
975     p_source - 1 for OPI, 2 for OPM
976 
977     Return:
978     l_bounds_valid - true if the bounds are valid
979                      false o.w.
980 
981     Date        Author              Action
982     04/23/03    Dinkar Gupta        Wrote Function
983 
984 */
985 FUNCTION collect_date_init_setup (p_etl_id IN NUMBER, p_source IN NUMBER)
986     RETURN BOOLEAN
987 IS
988 
989     l_proc_name VARCHAR2 (60) := 'collect_date_init_setup';
990     l_stmt_id NUMBER := 0;
991 
992     l_bounds_valid BOOLEAN := true;
993 
994     l_exists NUMBER := NULL;
995 
996 BEGIN
997 
998     -- Ensure that all the last_collection_date's are null
999     l_stmt_id := 10;
1000     BEGIN
1001         SELECT 1
1002         INTO l_exists
1003           FROM opi_dbi_run_log_curr
1004           WHERE last_collection_date IS NOT NULL
1005             AND source = p_source
1006             AND etl_id = p_etl_id
1007             AND rownum = 1;
1008 
1009         -- found a non-null last_collection_date
1010         RAISE collect_date_bounds_missing;
1011 
1012     EXCEPTION
1013         WHEN NO_DATA_FOUND THEN
1014             l_bounds_valid := true;
1015     END;
1016 
1017     -- Ensure that the from_bound_date's are non null
1018     l_stmt_id := 20;
1019     BEGIN
1020         SELECT 1
1021         INTO l_exists
1022         FROM dual
1023         WHERE (EXISTS (SELECT from_bound_date
1024                          FROM opi_dbi_run_log_curr
1025                          WHERE from_bound_date IS NULL
1026                            AND source = p_source
1027                            AND etl_id = p_etl_id));
1028 
1029         RAISE collect_date_bounds_missing; -- found a null from bound date
1030 
1031     EXCEPTION
1032         WHEN NO_DATA_FOUND THEN
1033             l_bounds_valid := true;
1034     END;
1035 
1036     -- Ensure that the to_bound_date's are non null
1037     l_stmt_id := 30;
1038     BEGIN
1039         SELECT 1
1040         INTO l_exists
1041         FROM dual
1042         WHERE (EXISTS (SELECT to_bound_date
1043                          FROM opi_dbi_run_log_curr
1044                          WHERE to_bound_date IS NULL
1045                            AND source = p_source
1046                            AND etl_id = p_etl_id));
1047 
1048         RAISE collect_date_bounds_missing; -- found a null to bound date
1049 
1050     EXCEPTION
1051         WHEN NO_DATA_FOUND THEN
1052             l_bounds_valid := true;
1053     END;
1054 
1055     return l_bounds_valid;
1056 
1057 EXCEPTION
1058 
1059     WHEN collect_date_bounds_missing THEN
1060         BIS_COLLECTION_UTILITIES.PUT_LINE (s_pkg_name || '.' ||
1061                                            l_proc_name || ' ' ||
1062                                            '#' || l_stmt_id || ': ' ||
1063                                            'Found missing dates for ETL ' ||
1064                                             p_etl_id || ' source ' ||
1065                                             p_source ||
1066                                            ' before initial load was run.');
1067         l_bounds_valid := false;
1068         return l_bounds_valid;
1069 
1070     WHEN OTHERS THEN
1071         rollback;
1072 
1073         BIS_COLLECTION_UTILITIES.PUT_LINE (s_pkg_name || '.' ||
1074                                            l_proc_name || ' ' ||
1075                                            '#' || l_stmt_id ||
1076                                            ': ' || SQLERRM);
1077 
1078         l_bounds_valid := false;
1079         return l_bounds_valid;
1080 
1081 END collect_date_init_setup;
1082 
1083 
1084 /*  run_initial_load
1085 
1086     API for ETL initial loads to that they are mean to run and not the
1087     incremental loads.
1088 
1089     The initial load of an ETL should call this which when it returns true
1090     indicates that it is time to run the initial load and when it returns
1091     false indicates that it is time to run the incremental load
1092  */
1093 FUNCTION run_initial_load (p_etl_id IN NUMBER, p_source IN NUMBER)
1094     RETURN BOOLEAN
1095 IS
1096 
1097     l_proc_name VARCHAR2 (60) := 'run_initial_load';
1098     l_stmt_id NUMBER := 0;
1099 
1100     l_run_init BOOLEAN := false;
1101     l_num_non_init_rows NUMBER := -1;
1102 
1103 BEGIN
1104 
1105     -- All that needs to be done is to ensure that the last collection
1106     -- date is NULL everywhere. If any row does not match is condition, then
1107     -- the initial load cannot be run.
1108     l_stmt_id := 10;
1109     SELECT sum (1)
1110     INTO l_num_non_init_rows
1111     FROM opi_dbi_run_log_curr
1112     WHERE source = p_source
1113       AND etl_id = p_etl_id
1114       AND last_collection_date IS NOT NULL;
1115 
1116 
1117     l_stmt_id := 20;
1118     IF (l_num_non_init_rows IS NULL) THEN
1119         l_run_init := true;
1120     ELSE
1121         l_run_init := false;
1122         BIS_COLLECTION_UTILITIES.PUT_LINE ('The initial load of this concurrent program cannot be run independently. Please run the initial load request set if it has not already been run successfully.');
1123         BIS_COLLECTION_UTILITIES.PUT_LINE (' Alternatively, run the incremental load request set if the initial load request set has already run.');
1124 
1125     END IF;
1126 
1127     l_stmt_id := 30;
1128     return l_run_init;
1129 
1130 EXCEPTION
1134 
1131 
1132     WHEN OTHERS THEN
1133         rollback;
1135         BIS_COLLECTION_UTILITIES.PUT_LINE (s_pkg_name || '.' ||
1136                                            l_proc_name || ' ' ||
1137                                            '#' || l_stmt_id ||
1138                                            ': ' || SQLERRM);
1139 
1140         l_run_init := false;
1141         return l_run_init;
1142 
1143 END run_initial_load;
1144 
1145 
1146 /*  check_global_setup
1147 
1148     Checks to see if basic global parameters are set up.
1149     Currently these include the:
1150     1. Global start date
1151     2. Global currency code
1152 
1153     Parameters: None
1154 
1155     Date        Author              Action
1156     04/23/03    Dinkar Gupta        Wrote Function
1157 */
1158 FUNCTION check_global_setup
1159     RETURN BOOLEAN
1160 IS
1161     l_proc_name VARCHAR2 (60) := 'check_global_setup';
1162     l_stmt_id NUMBER := 0;
1163 
1164     l_setup_good BOOLEAN := false;
1165 
1166     l_list dbms_sql.varchar2_table;
1167 
1168 BEGIN
1169 
1170     -- Parameters we want to check for
1171     l_list(1) := 'BIS_PRIMARY_CURRENCY_CODE';
1172     l_list(2) := 'BIS_GLOBAL_START_DATE';
1173 
1174     l_setup_good := bis_common_parameters.check_global_parameters(l_list);
1175     return l_setup_good;
1176 
1177 EXCEPTION
1178 
1179     WHEN OTHERS THEN
1180         rollback;
1181 
1182         BIS_COLLECTION_UTILITIES.PUT_LINE (s_pkg_name || '.' ||
1183                                            l_proc_name || ' ' ||
1184                                            '#' || l_stmt_id ||
1185                                            ': ' || SQLERRM);
1186 
1187         l_setup_good := false;
1188         return l_setup_good;
1189 
1190 END check_global_setup;
1191 
1192 
1193 /*  bounds_uncosted
1194 
1195     Return true if some rows have bounds that show uncosted transactions.
1196     This can only happen for OPI sourced Material ETLs.
1197 
1198     Such rows will be distinguished by the fact that their stop reason
1199     code will be STOP_UNCOSTED. This means that the stop reason code
1200     must not have been wiped out by the etl_report_success API
1201 
1202     Date        Author              Action
1203     04/23/03    Dinkar Gupta        Wrote Function
1204 
1205 */
1206 FUNCTION bounds_uncosted
1207     RETURN BOOLEAN
1208 IS
1209 
1210     l_proc_name VARCHAR2 (60) := 'bounds_uncosted';
1211     l_stmt_id NUMBER := 0;
1212     l_bounds_uncosted BOOLEAN := false;
1213     l_warning NUMBER := s_SUCCESS;
1214 
1215 BEGIN
1216 
1217     -- check if any row has uncosted transactions
1218     l_stmt_id := 10;
1219     BEGIN
1220         SELECT s_WARNING
1221         INTO l_warning
1222           FROM OPI_DBI_RUN_LOG_CURR
1223           WHERE stop_reason_code = STOP_UNCOSTED
1224           AND rownum = 1;
1225     EXCEPTION
1226         WHEN NO_DATA_FOUND THEN
1227             l_warning := s_SUCCESS;
1228     END;
1229 
1230     -- If there are uncosted transactions, return true
1231     l_stmt_id := 20;
1232     IF (l_warning = s_WARNING) THEN
1233         l_bounds_uncosted := true;
1234     END IF;
1235 
1236     RETURN l_bounds_uncosted;
1237 
1238 END bounds_uncosted;
1239 
1240 
1241 /*  print_opi_org_bounds
1242 
1243     Print the MMT bounds before which the OPI discrete orgs stopped, and the
1244     reason for stopping
1245 */
1246 PROCEDURE print_opi_org_bounds
1247 IS
1248 
1249     l_proc_name VARCHAR2 (60) := 'bounds_uncosted';
1250     l_stmt_id NUMBER := 0;
1251 
1252     -- Cursor for all the org bounds
1253     CURSOR opi_org_bounds_csr IS
1254         SELECT /*+ index(log, OPI_DBI_RUN_LOG_CURR_N1) use_nl(log mp)*/
1255                mp.organization_code,
1256                log.next_start_txn_id,
1257                decode (log.stop_reason_code,
1258                        STOP_ALL_COSTED, 'All Costed',
1259                        STOP_UNCOSTED, 'Uncosted',
1260                        'Data Issue?') stop_reason,
1261                nvl (mmt.transaction_date, sysdate) data_until
1262           FROM opi_dbi_run_log_curr log,
1263                mtl_parameters mp,
1264                mtl_material_transactions mmt
1265           WHERE source = OPI_SOURCE
1266             AND etl_id = JOB_TXN_ETL  -- any ETL is good enough
1267             AND log.next_start_txn_id = mmt.transaction_id (+)
1268             AND log.organization_id = mp.organization_id;
1269 BEGIN
1270 
1271     -- print the header
1272     l_stmt_id := 10;
1273 
1274     BIS_COLLECTION_UTILITIES.PUT_LINE (
1275             RPAD ('Organization Code', 20) ||
1276             RPAD ('Txn Id Stopped Before', 25) ||
1277             RPAD ('Data Collected Until', 25) ||
1278             RPAD ('Reason Stopped', 20));
1279 
1280 
1281     BIS_COLLECTION_UTILITIES.PUT_LINE (
1282             RPAD ('-----------------', 20) ||
1283             RPAD ('---------------------', 25) ||
1284             RPAD ('--------------------', 25) ||
1285             RPAD ('--------------', 20));
1286 
1287 
1288     -- just print all the bounds
1289     l_stmt_id := 20;
1290     FOR opi_org_bounds_rec IN opi_org_bounds_csr
1291     LOOP
1292 
1293         BIS_COLLECTION_UTILITIES.PUT_LINE (
1294                 RPAD (opi_org_bounds_rec.organization_code, 20) ||
1295                 RPAD (opi_org_bounds_rec.next_start_txn_id, 25) ||
1296                 RPAD (opi_org_bounds_rec.data_until, 25) ||
1297                 RPAD (opi_org_bounds_rec.stop_reason, 20));
1298 
1299     END LOOP;
1300 
1301 
1305 
1302     -- print table end
1303     l_stmt_id := 30;
1304     BIS_COLLECTION_UTILITIES.PUT_LINE (LPAD ('', 90, '-'));
1306     RETURN;
1307 
1308 EXCEPTION
1309 
1310     WHEN OTHERS THEN
1311         rollback;
1312 
1313         BIS_COLLECTION_UTILITIES.PUT_LINE (s_pkg_name || '.' ||
1314                                            l_proc_name || ' ' ||
1315                                            'Error when printing org bounds.');
1316 
1317         RAISE;    -- propagate exception to wrapper
1318 
1319 
1320 END print_opi_org_bounds;
1321 
1322 
1323 END opi_dbi_common_mod_init_pkg;