DBA Data[Home] [Help]

PACKAGE BODY: APPS.HRI_OPL_EVENT_CAPTURE

Source


1 PACKAGE BODY HRI_OPL_EVENT_CAPTURE AS
2 /* $Header: hrioetcp.pkb 120.9 2006/12/06 11:02:14 jtitmas noship $ */
3 --
4 -- ----------------------------------------------------------------------------
5 --
6 -- Overview
7 -- ========
8 -- This purpose of this package is to interogate the PEM architecture in a
9 -- single pass, to glean details of all the events that have occurred that are
10 -- relevant to various HRMSi DBI base collections.
11 --
12 -- A single record per assignment, is then stored in the appropriate event
13 -- queue table for a given collection, for each collection that is interested
14 -- in the event.
15 --
16 -- Example
17 -- ~~~~~~~
18 -- For example a supervisor change maybe of interest to the supervisor hierachy
19 -- collection process, the assignments events fact collection, and the
20 -- supervisor status history collection. In this case a row will be maintained
21 -- in each of the queue tables for these object's assignment change.
22 --
23 -- Maintaining the Event Queues
24 -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
25 -- Providing that there is no other change recorded for the assignment in the
26 -- queue already the earliest change for that assignment is simply
27 -- inserted into the qeueue. If there is a row in the queue that has an
28 -- earlier change date, then we will do nothing, otherwise if the change
29 -- pre-dates the record in the queue table, then we will update the record for
30 -- that assignment in the queue to set the change date to the earlier date.
31 --
32 -- Further Information
33 -- ===================
34 -- For details of the process flows in this package it is recomended that you
35 -- look at the detailed design using the following URL:
36 --
37 -- http://files.oraclecorp.com/content/AllPublic/Workspaces/
38 --      HRMS%20Intelligence%20(HRMSi)%20-%20Documents-Public/
39 --      Design%20Specifications/hri_lld_base_incremental_event_capture.doc
40 --
41 -- Process flow
42 -- ============
43 --
44 -- -----------------------------------------------------------------------------
45 -- Process flow
46 -- ============
47 --
48 -- BEFORE MULTI-THREADING
49 -- ----------------------
50 -- PRE_PROCESS
51 --   - Shared HR mode
52 --       - Call the bis process to insert a entry in the bis refresh log
53 --         for the process
54 --   - Full Refresh mode / Process Running for the first time
55 --       - Call the bis process to insert a entry in the bis refresh log
56 --         for the process
57 --   - When the event queue profiles are not set
58 --       - Call the bis process to insert a entry in the bis refresh log
59 --         for the process
60 --   - Incremental Mode
61 --       - Return the SQL based on which the range will be generated
62 --
63 -- PROCESS_RANGE
64 --       - Evaluate the events for every assignment in the range and
65 --         insert/update the records in the event queue
66 --
67 -- POST_PROCESS
68 --       - Call the bis process to insert a entry in the bis refresh log
69 --         for the process
70 --
71 -- -----------------------------------------------------------------------------
72   --
73   -- Start of global variable setup
74   -- ----------------------------------------------------------------------------
75   --
76   --
77   -- Global end of time date initialization from the package hr_general
78   --
79   g_end_of_time            DATE := hr_general.end_of_time;
80   --
81   -- Global DBI collection start date initialization
82   --
83   g_dbi_collection_start_date DATE := hri_bpl_parameter.get_bis_global_start_date;
84   --
85   -- Global flag which determines whether debugging is turned on
86   --
87   g_debug_flag             VARCHAR2(5) := NVL(fnd_profile.value('HRI_ENBL_DTL_LOG'),'N');
88   --
89   -- Global flag which determines whether archiving is turned on
90   --
91   --
92   g_enable_archive_flag VARCHAR2(5);
93   --
94   -- Global Variable to store the profile value for HRI:Populate Assignment Events Queue
95   --
96   g_col_asg_events_eq VARCHAR2(5);
97   --
98   -- Global Variable to store the profile value for HRI:Populate Supervisor Hierarchy Events Queue
99   --
100   g_col_sup_hrchy_eq VARCHAR2(5);
101   --
102   -- Global Variable to store the profile value for HRI:Populate Supervisor Status History Events Queue
103   --
104   g_col_sup_hstry_eq VARCHAR2(5);
105   --
106   -- Global Variable to store the profile value for 'HRI:Absence Dimension Queue' Events Queue
107   --
108   g_col_absence_events_eq VARCHAR2(5);
109   --
110   -- 3716747 Global Variable to store the date track id of the period of service table
111   --
112   g_prd_of_srvc_table_id          NUMBER;
113   g_appraisal_table_id            NUMBER;
114   g_perf_review_table_id          NUMBER;
115   g_asg_table_id                  NUMBER;
116   g_person_type_table_id          NUMBER;
117   g_absence_attendance_table_id   NUMBER;
118   --
119   -- Gloabl variable to store the NLS Date format
120   --
121   g_date_format          VARCHAR2(30);
122   --
123   -- Gloabl variable to store the Minimum date in Supervisor Hierarchy or
124   -- the collection from date for the last full refresh
125   --
126   g_min_suph_date        DATE;
127   --
128   -- Global HRI Multithreading Array
129   --
130   g_mthd_action_array    HRI_ADM_MTHD_ACTIONS%rowtype;
131   g_full_refresh         VARCHAR2(30);
132   --
133   -- End of global variable setup
134   --
135   -- -----------------------------------------------------------------------------
136   --
137   --
138   -- Start of global constant setup
139   --
140   c_object_name            VARCHAR2(30) := 'HRI_OPL_EVENT_CAPTURE';
141   c_ee_id                  NUMBER       := -1;
142   --
143 -- End of global setting
144 --
145 PROCEDURE process_range(p_start_object_id   IN NUMBER
146                        ,p_end_object_id     IN NUMBER ) ;
147 --
148 PROCEDURE Update_Asgn_Evnt_Fct_Evnt_Q
149   (p_assignment_id IN NUMBER
150   ,p_change_date   IN DATE -- The effective change date
151   ,p_start_date    IN DATE -- The date the events were captured from
152   );
153 --
154 -- ----------------------------------------------------------------------------
155 -- Inserts row into concurrent program log
156 -- ----------------------------------------------------------------------------
157 --
158 PROCEDURE msg(p_text  VARCHAR2) IS
159   --
160 BEGIN
161   --
162   HRI_BPL_CONC_LOG.output(p_text);
163   --
164 END msg;
165 --
166 -- ----------------------------------------------------------------------------
167 -- Inserts row into concurrent program log if debugging is enabled
168 -- ----------------------------------------------------------------------------
169 --
170 PROCEDURE dbg(p_text  VARCHAR2) IS
171   --
172 BEGIN
173   --
174   HRI_BPL_CONC_LOG.dbg(p_text);
175   --
176 END dbg;
177 --
178 -- 3716747 Get the date track table id for PER_PERIODS_OF_SERVICE
179 --
180 FUNCTION get_dated_table_id(p_table_name varchar2)
181 RETURN NUMBER
182 IS
183   --
184   CURSOR c_date_table_id (p_table_name varchar2) IS
185   SELECT dated_table_id
186   FROM   pay_dated_tables
187   WHERE  table_name = p_table_name;
188   --
189   l_table_id      NUMBER;
190   --
191 BEGIN
192   --
193   OPEN  c_date_table_id (p_table_name);
194   FETCH c_date_table_id into l_table_id;
195   CLOSE c_date_table_id;
196   --
197   RETURN l_table_id;
198   --
199 END get_dated_table_id;
200 --
201 -- 3716747 This function will be called if the change is to column
202 -- PER_PERIODS_OF_SERVICES.DATE_START. This means that the latest hire
203 -- data has been changed. The output should be least of the old and
204 -- new date. In case there is a formating error the effective_date of
205 -- the transaction will be returned
206 --
207 FUNCTION get_least_date(p_change_values  IN VARCHAR2,
208                         p_effective_date IN DATE)
209 RETURN DATE IS
210   --
211   CURSOR c_date_format_mast IS
212   SELECT VALUE
213   FROM   V$PARAMETER
214   WHERE  NAME = 'nls_date_format';
215   --
216   l_old_value            DATE;
217   l_new_value            DATE;
218   l_length_to_grab       NUMBER;
219   l_effective_date       DATE;
220   --
221 BEGIN
222   --
223   IF g_date_format is null THEN
224     --
225     OPEN  c_date_format_mast;
226     FETCH c_date_format_mast into g_date_format;
227     CLOSE c_date_format_mast;
228     --
229   END IF;
230   --
231   -- The change_value column contains data in this format
232   -- 01-jan-03 -> 01-jan-03
233   -- compare the two dates and return the least
234   --
235   l_length_to_grab := (length(p_change_values) - 4)/2;
236   --
237   l_old_value := to_date(substr(p_change_values,0,l_length_to_grab),g_date_format);
238   --
239   l_new_value := to_date(substr(p_change_values,l_length_to_grab+4),g_date_format);
240   --
241   l_effective_date := least(l_old_value, l_new_value);
242   --
243   RETURN l_effective_date;
244   --
245 EXCEPTION
246   --
247   -- In case an error is raised in formating the date, do not raise an error
248   -- return the effective date on PEM record
249   --
250   WHEN others THEN
251     --
252     dbg('Exception Raised in determine change in latest hire date');
253     dbg(sqlerrm);
254     l_effective_date := p_effective_date;
255     --
256     RETURN l_effective_date;
257     --
258 END get_least_date;
259 --
260 --
261 -- Populate snapshot fact EQs with any new snapshot dates
262 --
263 PROCEDURE check_for_new_snapshot_dates IS
264 
265   l_implement_obiee        VARCHAR2(30);
266   l_implement_obiee_orgh   VARCHAR2(30);
267   l_implement_obiee_mgrh   VARCHAR2(30);
268 
269 BEGIN
270 
271   -- Set OBIEE parameters
272   IF (fnd_profile.value('HRI_IMPL_OBIEE') = 'Y') THEN
273     l_implement_obiee      := 'Y';
274     IF (fnd_profile.value('HRI_COL_SUP_HRCHY_EQ') = 'Y') THEN
275       l_implement_obiee_mgrh := 'Y';
276     ELSE
277       l_implement_obiee_mgrh := 'N';
278     END IF;
279     IF (fnd_profile.value('HRI_COL_ORG_HRCHY_EQ') = 'Y') THEN
280       l_implement_obiee_orgh := 'Y';
281     ELSE
282       l_implement_obiee_orgh := 'N';
283     END IF;
284   ELSE
285     l_implement_obiee      := 'N';
286     l_implement_obiee_mgrh := 'N';
287     l_implement_obiee_orgh := 'N';
288   END IF;
289 
290   -- If OBIEE is implemented, check OBIEE facts
291   IF l_implement_obiee = 'Y' THEN
292 
293     -- If a new month is reached since the last collection run
294     -- then update event queues
295     IF (trunc(g_capture_from_date,'MONTH') < trunc(sysdate, 'MONTH')) THEN
296 
297       dbg('Found new month for OBIEE summaries');
298 
299       EXECUTE IMMEDIATE 'alter session enable parallel dml';
300 
301       commit;
302 
303       -- Insert new snapshots into workforce events fact EQ
304       -- add assignments active between last refresh date and current month end
305       INSERT /*+ APPEND PARALLEL */ INTO hri_eq_wrkfc_mnth
306        (assignment_id
307        ,erlst_evnt_effective_date)
308       SELECT DISTINCT
309        asg_assgnmnt_fk
310       ,add_months(trunc(g_capture_from_date,'MONTH'), 1)
311       FROM
312        hri_mb_wrkfc_evt_ct
313       WHERE g_capture_from_date <= time_day_evt_end_fk
314       AND add_months(trunc(sysdate,'MONTH'), 1) > time_day_evt_fk
315       AND term_or_end_ind = 0;
316 
317       commit;
318 
319       -- Check manager hierarchy implemented
320       IF l_implement_obiee_mgrh = 'Y' THEN
321 
322         -- Insert new snapshots into workforce manager summary EQ
323         -- Add managers active between last refresh date and current month end
324         INSERT /*+ APPEND PARALLEL */ INTO hri_eq_wrkfc_evt_mgrh
325          (sup_person_id
326          ,erlst_evnt_effective_date
327          ,source_code)
328         SELECT DISTINCT
329          mgrs_person_fk
330         ,add_months(trunc(g_capture_from_date,'MONTH'), 1)
331         ,'NEW_SNAP_DATE'
332         FROM
333          hri_cs_mngrsc_ct
334         WHERE g_capture_from_date <= mgrs_date_end
335         AND add_months(trunc(sysdate,'MONTH'), 1) > mgrs_date_start;
336 
337         commit;
338 
339       END IF;
340 
341       -- Check organization hierarchy implemented
342       IF l_implement_obiee_orgh = 'Y' THEN
343 
344         -- Insert new snapshots into workforce organization summary
345         -- Add one record per hierarchy node
346         INSERT /*+ APPEND PARALLEL */ INTO hri_eq_wrkfc_evt_orgh
347          (organization_id
348          ,erlst_evnt_effective_date)
349         SELECT
350          orgh_sup_organztn_fk
351         ,add_months(trunc(g_capture_from_date,'MONTH'), 1)
352         FROM
353          hri_cs_orgh_ct
354         WHERE orgh_relative_level = 0;
355 
356         commit;
357 
358       END IF;
359 
360     END IF;
361 
362   END IF;
363 
364 END check_for_new_snapshot_dates;
365 --
366 --
367 --
368 FUNCTION get_min_suph_date
369 RETURN DATE
370 IS
371   --
372   l_min_suph_date    DATE;
373   --
374   CURSOR c_last_full_suph_col_run IS
375   SELECT period_from
376   FROM   bis_refresh_log
377   WHERE  object_name = 'HRI_CS_SUPH'
378   AND    status='SUCCESS'
379   AND    attribute1 = 'Y'
380   AND    last_update_date =( SELECT max(last_update_date)
381                              FROM   bis_refresh_log
382                              WHERE  object_name= 'HRI_CS_SUPH'
383                              AND    status='SUCCESS'
384                              AND    attribute1 = 'Y')
385   ORDER BY last_update_date DESC;
386   --
387   CURSOR c_min_suph_date IS
388   SELECT min(effective_start_date)
389   FROM   hri_cs_suph;
390   --
391 BEGIN
392   --
393   -- 3906029 The event date to be populated in the supervisor hierarchy
394   -- events queue should not be lesser than the last full refresh date
395   -- or the minimum date in the hierarchy
396   --
397   OPEN   c_last_full_suph_col_run;
398   FETCH  c_last_full_suph_col_run INTO l_min_suph_date;
399   CLOSE  c_last_full_suph_col_run ;
400   --
401   dbg('last collection date='|| l_min_suph_date );
402   --
403   -- In case the collection start date for last full refresh could not
404   -- be found from bis_refresh table, get the data from supervisor hierarchy
405   -- table.
406   --
407   IF g_min_suph_date is null THEN
408     --
409     OPEN   c_min_suph_date;
410     FETCH  c_min_suph_date INTO l_min_suph_date;
411     CLOSE  c_min_suph_date;
412     --
413   END IF;
414   --
415   RETURN NVL(l_min_suph_date,g_dbi_collection_start_date);
416   --
417 END get_min_suph_date;
418 --
419 -- ----------------------------------------------------------------------------
420 -- 3829100 When an event occurs due to changes to PER_PERSON_TYPE_USAGES
421 -- the events can is useful to DBI only if the change is made to a record with
422 -- EMP on CWK system person type, otherwise the event is of no use for DBI
423 -- ----------------------------------------------------------------------------
424 --
425 FUNCTION valid_for_dbi_ptu_rec(p_person_type_usage_id   NUMBER
426                               ,p_effective_date         DATE)
427 RETURN BOOLEAN
428 IS
429   --
430   CURSOR c_ptu IS
431   SELECT 1
432   FROM   per_person_type_usages_f ptu,
433          per_person_types ppt
434   WHERE  1=1
435   AND    ptu.person_type_usage_id = p_person_type_usage_id
436   AND    p_effective_date BETWEEN ptu.effective_start_date and ptu.effective_end_date
437   AND    ptu.person_type_id = ppt.person_type_id
438   AND    ppt.system_person_type in ('EMP','CWK');
439   --
440   l_dummy         NUMBER;
441   --
442 BEGIN
443   --
444   -- Open the cursor to determine if the change has been made to a EMP or CWK
445   --
446   OPEN  c_ptu;
447   FETCH c_ptu INTO l_dummy;
448   CLOSE c_ptu;
449   --
450   IF l_dummy = 1 THEN
451     --
452     -- Change made to EMP or CWK person type so return true
453     --
454     dbg('emp asg change so return true');
455     RETURN TRUE;
456     --
457   ELSE
458     --
459     -- Change not made to EMP or CWK person type so return false
460     --
461     dbg('not a emp asg change so return false');
462     RETURN FALSE;
463     --
464   END IF;
465   --
466 END valid_for_dbi_ptu_rec;
467 --
468 -- ----------------------------------------------------------------------------
469 -- 4469175 The function is invoked when the projected end date is changed or when there
470 -- is a change in primary asg for a person. The function re-evaluates the extension start
471 -- date and returns the value. Additionally the function also creates event records for
472 -- other assignment records for the person to ensure that the extension date is
473 -- correctly set
474 -- ----------------------------------------------------------------------------
475 --
476 FUNCTION get_extnsn_strt_dt(
477                     p_assignment_id  IN NUMBER,
478                     p_effective_date IN DATE)
479 RETURN DATE IS
480   --
481   l_person_id             NUMBER;
482   l_extnsn_strt_dt        DATE;
483   --
484   -- Cursor to get the earlierst extn date from asg events.
485   -- Note: extension starts one day after the projected assignment end specified
486   -- in the assignment record
487   --
488   -- Bug 4533293 - return event date (using NVL) if no projected end date exists in
489   --               per_all_assignments_f but does exist in hri_mb_asgn_events_ct
490   --
491   CURSOR c_extsn_strt_dt IS
492   SELECT asgn.person_id, NVL(min(asgn.projected_assignment_end) + 1, p_effective_date)
493   FROM   per_all_assignments_f asgn
494   WHERE  primary_flag = 'Y'
495   --
496   -- For people with multiple placement (rehire), the extsn date specified during
497   -- a particular term should only be considered for evaluating the extsn date
498   --
499   AND    (person_id,period_of_placement_date_start)  =
500                      ( SELECT asgn.person_id , asgn.period_of_placement_date_start
501                        FROM   per_all_assignments_f asgn
502                        WHERE  asgn.assignment_id = p_assignment_id
503                        AND    rownum = 1)
504   GROUP BY asgn.person_id
505   --
506   -- The cursor should only return a record is the extension date in asg event
507   -- is not equal to the min date in the asg table
508   -- Bug 4533293 - changed subquery to use NVLs so that cursor will return a
509   --               record in the null case i.e. no previous extension existed
510   --               or previous extension removed
511   --
512   HAVING   NVL(min(asgn.projected_assignment_end), g_end_of_time) <>
513    (SELECT NVL(MIN(asg.pow_extn_strt_dt) - 1, g_end_of_time)
514     FROM   hri_mb_asgn_events_ct asg
515     WHERE  asg.assignment_id = p_assignment_id);
516   --
517   CURSOR c_othr_prmry_asg IS
518   SELECT assignment_id,
519          least(min(asgn.effective_change_date),l_extnsn_strt_dt) change_date
520   FROM   hri_mb_asgn_events_ct asgn
521   WHERE  asgn.person_id  = l_person_id
522   AND    pow_extn_strt_dt is not null
523   AND    asgn.pow_extn_strt_dt   <> l_extnsn_strt_dt
524   AND    assignment_id <> p_assignment_id
525   GROUP BY asgn.assignment_id;
526   --
527 BEGIN
528   --
529   dbg('Inside get_least_projected_end_date');
530   --
531   OPEN  c_extsn_strt_dt;
532   FETCH c_extsn_strt_dt INTO l_person_id,l_extnsn_strt_dt;
533   CLOSE c_extsn_strt_dt;
534   --
535   -- The event should be generated for all assignment for the person as it is
536   -- likely that asg event records for the person have some incorrect data
537   --
538   IF l_extnsn_strt_dt is not null THEN
539     --
540     FOR l_asg IN c_othr_prmry_asg LOOP
541       --
542       dbg('creating event for asg = '|| l_asg.assignment_id||
543           ' as the extnsn date is changed to'||l_extnsn_strt_dt);
544       --
545       Update_Asgn_Evnt_Fct_Evnt_Q
546           (p_assignment_id => l_asg.assignment_id
547           ,p_change_date   => l_asg.change_date
548           ,p_start_date    => l_asg.change_date
549           );
550       --
551     END LOOP;
552     --
553   END IF;
554   --
555   dbg('the extension start date is '||l_extnsn_strt_dt);
556   --
557   RETURN l_extnsn_strt_dt;
558   --
559 EXCEPTION
560   --
561   -- In case an error is raised in formating the date, do not raise an error
562   -- return the effective date on PEM record
563   --
564   WHEN others THEN
565     --
566     dbg('Exception Raised in get_least_projected_end_date');
567     dbg(sqlerrm);
568     --
569     RETURN p_effective_date;
570     --
571 END get_extnsn_strt_dt;
572 --
573 -- 3906029, In case of termination events for the supervisor hierarchy
574 -- the date retunred should not be PRE_PERIODS_OF_SERVICE.DATE_START. It should
575 -- be termination_date + 1. This will prevent the hierarchy from recollecting
576 -- the hierarchy from start date for the person. However, in case of rehire
577 -- the effective date should be PRE_PERIODS_OF_SERVICE.DATE_START
578 --
579 --
580 FUNCTION get_changed_termination_date(p_change_values  IN VARCHAR2,
581                                       p_effective_date IN DATE)
582 RETURN DATE IS
583   --
584   CURSOR c_date_format_mast IS
585   SELECT VALUE
586   FROM   V$PARAMETER
587   WHERE  NAME = 'nls_date_format';
588   --
589   l_old_value            DATE;
590   l_new_value            DATE;
591   l_length_to_grab       NUMBER;
592   l_effective_date       DATE;
593   --
594 BEGIN
595   --
596   IF g_date_format is null THEN
597     --
598     OPEN  c_date_format_mast;
599     FETCH c_date_format_mast into g_date_format;
600     CLOSE c_date_format_mast;
601     --
602   END IF;
603   --
604   -- The following changes can be done to actual termination and final
605   -- process date columns
606   --   A date can be assigned which means that the person is terminated
607   --   The date can be changed
608   --   In case of rehire the date will be removed.
609   -- Based of these the change_value column can contains data in the
610   -- following formats
611   --   01-jan-03 -> 01-jan-04    Change is termination date
612   --   <null> -> 11-OCT-04       Termination
613   --   31-OCT-04 -> <null>       Rehire
614   -- Find out the exact format and pass out the values
615   --
616   IF instr(p_change_values,'<null>') = 0 THEN
617     --
618     -- The format is 01-jan-03 -> 01-jan-04
619     -- So the person's termination date has changed
620     --
621     l_length_to_grab := (length(p_change_values) - 4)/2;
622     --
623     l_old_value := to_date(substr(p_change_values,0,l_length_to_grab),g_date_format);
624     --
625     l_new_value := to_date(substr(p_change_values,l_length_to_grab+4),g_date_format);
626     --
627     l_effective_date := least(l_old_value, l_new_value);
628     --
629   ELSIF instr(p_change_values,'<null>') = 1 THEN
630     --
631     -- The format is <null> -> 11-OCT-04
632     -- So the person has been terminated
633     -- A person termination one day after the end date of the record, so add 1
634     l_effective_date := to_date(substr(p_change_values,11),g_date_format) + 1;
635     --
636   ELSE
637     --
638     -- The format is 31-OCT-04 -> <null>
639     -- So the person has been rehired, create the event as of the
640     -- effective date
641     --
642     l_effective_date := p_effective_date;
643     --
644   END IF;
645   --
646   dbg('the termination event date is '||l_effective_date);
647   RETURN l_effective_date;
648   --
649 EXCEPTION
650   --
651   -- In case an error is raised in formating the date, do not raise an error
652   -- return the effective date on PEM record
653   --
654   WHEN others THEN
655     --
656     dbg('Exception Raised in determine termination date, returning effective date');
657     dbg(sqlerrm);
658     l_effective_date := p_effective_date;
659     --
660     RETURN l_effective_date;
661     --
662 END get_changed_termination_date;
663 --
664 -- ----------------------------------------------------------------------------
665 -- The function evaluates the dates for all one off cases, and adjust the
666 -- effective date so that the event is created on a correct date
667 -- ----------------------------------------------------------------------------
668 --
669 FUNCTION eval_one_off_cases
670           (p_sub_evt_grp_tbl   pay_interpreter_pkg.t_detailed_output_tab_rec
671           ,p_assignment_id     NUMBER
672           ,p_comment_text      VARCHAR2
673           ,p_effective_date    DATE)
674 RETURN DATE IS
675   --
676   l_effective_date  DATE := p_effective_date;
677   l_extns_date      DATE;
678   --
679 BEGIN
680   --
681   -- 3716747
682   -- If a person's latest hire date is changed to a future date,
683   -- e.g. from 01-jan-2004 to 15-Jan-2004, the effective date of the transaction
684   -- return by PEM is 15-Jan-2004. It's likely that the person's data in
685   -- base collection table start from the old hire date (01-jan-2004). If the
686   -- event created due to change in latest hire date is created on 15-jan-2004
687   -- the data in base table will not be correct and this will result is errors
688   -- on DBI pages. Therefore, if the event has been caused due to change in person's
689   -- hire date PRE_PERIODS_OF_SERVICE.DATE_START then event date should be set the least
690   -- of the old-new hire dates i.e. 01-jan-2004 in this case. This will ensure that old
691   -- data for the assignment is delete by the collection processes.
692   -- 3952026, extended the case to change in effective date of other non datetrack tables
693   -- per_appraisals and per_periods_of_service
694   -- 3170971, extending the case to per_all_assignments_f, In case of cancel hire of an
695   -- applicant, the previously end dated applicant asg record is end dated to end of
696   -- time from current date and the asg record is deleted. However PEM will detect only
697   -- the update of effective_end_date column
698   --
699   IF (g_prd_of_srvc_table_id = p_sub_evt_grp_tbl.dated_table_id
700       AND p_sub_evt_grp_tbl.column_name = 'DATE_START')
701      OR ( g_appraisal_table_id = p_sub_evt_grp_tbl.dated_table_id
702       AND p_sub_evt_grp_tbl.column_name = 'APPRAISAL_DATE' )
703      OR ( g_perf_review_table_id = p_sub_evt_grp_tbl.dated_table_id
704       AND p_sub_evt_grp_tbl.column_name = 'REVIEW_DATE' )
705      OR ( g_asg_table_id = p_sub_evt_grp_tbl.dated_table_id
706       AND p_sub_evt_grp_tbl.column_name = 'EFFECTIVE_END_DATE' )
707   THEN
708     --
709     dbg('change detected in column '||p_sub_evt_grp_tbl.column_name ||' of table_id '||g_prd_of_srvc_table_id);
710     dbg('p_sub_evt_grp_tbl.change_values = '||p_sub_evt_grp_tbl.change_values);
711     --
712     l_effective_date := get_least_date(
713            p_change_values  => p_sub_evt_grp_tbl.change_values,
714            p_effective_date => p_sub_evt_grp_tbl.effective_date);
715     --
716   --
717   -- Extension Start Date
718   -- 4469175 When the projected end date of the record is changed the event should
719   -- be created on the minimum of all projected end dates + 1 stored in the
720   -- primary asg records of the person. If the new date is not less than the
721   -- date in the system, a new event should be created for all other asg for the
722   -- person
723   --
724   ELSIF   ( g_asg_table_id = p_sub_evt_grp_tbl.dated_table_id AND
725       p_comment_text <> 'Supervisor' AND
726       p_sub_evt_grp_tbl.column_name = 'PROJECTED_ASSIGNMENT_END' )
727   THEN
728     --
729     dbg('In period of extension change calculation');
730     --
731     l_effective_date := get_extnsn_strt_dt(
732            p_assignment_id  => p_assignment_id,
733            p_effective_date => p_sub_evt_grp_tbl.effective_date);
734     --
735   --
736   -- 4469175
737   -- Change of primary assignment and extension calculation
738   -- In case the primary assignment for a record is changed the event date should
739   -- set as least of
740   -- A. Effective change date
741   -- B. The extension date for the person if it has been reset due to the change in
742   --    primary assignment
743   --
744   ELSIF  ( g_asg_table_id = p_sub_evt_grp_tbl.dated_table_id AND
745      p_comment_text <> 'Supervisor' AND
746      p_sub_evt_grp_tbl.column_name = 'PRIMARY_FLAG' )
747   THEN
748     --
749     dbg('In change of primary assignment calculation');
750     --
751     l_extns_date := get_extnsn_strt_dt(
752            p_assignment_id  => p_assignment_id,
753            p_effective_date => p_sub_evt_grp_tbl.effective_date);
754     --
755     l_effective_date := least(l_extns_date,p_sub_evt_grp_tbl.effective_date);
756     --
757   ELSIF g_person_type_table_id = p_sub_evt_grp_tbl.dated_table_id THEN
758     --
759     -- 3829100 If event is due to change to PER_PERSON_TYPE_USAGE_F, the event
760     -- affect DBI only when the change is made to PTU record with EMP, CWK
761     -- person type. The queues should be populated for such events
762     --
763     dbg('inside ptu check');
764     IF valid_for_dbi_ptu_rec(p_sub_evt_grp_tbl.surrogate_key,
765            p_sub_evt_grp_tbl.effective_date)
766     THEN
767       --
768       -- in case the the change is to EFFECTIVE_END_DATE column then
769       -- the effective_date should be set to least of the prev and current dates
770       --
771       IF p_sub_evt_grp_tbl.column_name = 'EFFECTIVE_END_DATE' THEN
772         --
773         l_effective_date := get_least_date(
774 	      p_change_values  => p_sub_evt_grp_tbl.change_values,
775               p_effective_date => p_sub_evt_grp_tbl.effective_date);
776         --
777       END IF;
778       --
779     ELSE
780       --
781       l_effective_date := null;
782       --
783     END IF;
784     --
785   ELSIF p_comment_text = 'Supervisor'
786     AND g_prd_of_srvc_table_id = p_sub_evt_grp_tbl.dated_table_id
787     AND p_sub_evt_grp_tbl.column_name in ('ACTUAL_TERMINATION_DATE','FINAL_PROCESS_DATE' )
788   THEN
789     --
790     -- 3906029, In case of termination events for the supervisor hierarchy
791     -- the min date should not be PRE_PERIODS_OF_SERVICE.DATE_START. It should
792     -- be termination_date + 1. This will prevent the hierarchy from recollecting
793     -- the hierarchy from start date for the person. However, in case of rehire
794     -- the effective date should be PRE_PERIODS_OF_SERVICE.DATE_START
795     --
796     l_effective_date := get_changed_termination_date(
797            p_change_values  => p_sub_evt_grp_tbl.change_values,
798            p_effective_date => p_sub_evt_grp_tbl.effective_date);
799     dbg('termination date = '||l_effective_date);
800     --
801   END IF;
802   --
803   dbg('effective date = '||l_effective_date);
804   --
805   RETURN l_effective_date;
806   --
807 END eval_one_off_cases;
808 --
809 -- ----------------------------------------------------------------------------
810 -- empty_evnts_cptr_refresh_log
811 -- Empty events Capture Refresh Log.
812 -- ============================================================================
813 -- This procedure truncates the BIS log information, for the events capture
814 -- process. This is useful for testing purposes, so that we can re-run tests
815 -- over given date ranges.
816 --
817 -- The logic in this procedure DOES NOT form part of the normal incremental
818 -- events capture process.
819 --
820 PROCEDURE empty_evnts_cptr_refresh_log
821 IS
822   --
823 BEGIN
824   --
825   hri_bpl_conc_log.delete_process_log(c_object_name);
826   --
827 END empty_evnts_cptr_refresh_log;
828 --
829 -- ----------------------------------------------------------------------------
830 -- truncate_table
831 -- The following procedure truncates the passed in table.
832 -- ============================================================================
833 --
834 PROCEDURE truncate_table(p_table_name VARCHAR2)
835 IS
836   --
837   l_sql_stmt   VARCHAR2(200);
838   l_dummy1     VARCHAR2(1);
839   l_dummy2     VARCHAR2(1);
840   l_schema     VARCHAR2(50);
841   --
842 BEGIN
843   --
844   IF NOT fnd_installation.get_app_info('HRI',l_dummy1, l_dummy2, l_schema)
845   THEN
846     --
847     RAISE schema_name_not_set;
848     --
849   END IF;
850   --
851   l_sql_stmt := 'TRUNCATE TABLE ' || l_schema || '.' || p_table_name;
852   --
853   dbg(l_sql_stmt);
854   --
855   EXECUTE IMMEDIATE(l_sql_stmt);
856   --
857   COMMIT;
858   --
859   dbg('Truncated table: '||p_table_name);
860   --
861 EXCEPTION
862   --
863   WHEN OTHERS
864   THEN
865     --
866     dbg('An error occurred while truncating table '||p_table_name);
867     --
868     -- Bug 4105868: Collection Diagnostic Call
869     --
870     hri_bpl_conc_log.log_process_info
871             (p_package_name  => 'HRI_OPL_EVENT_CAPTURE'
872             ,p_msg_type      => 'ERROR'
873             ,p_note          => SQLERRM
874             ,p_msg_group     => 'EVT_CPTR'
875             ,p_msg_sub_group => 'TRUNCATE_TABLE'
876             ,p_sql_err_code  => SQLCODE);
877     --
878     RAISE;
879     --
880   --
881 END truncate_table;
882 --
883 -- ----------------------------------------------------------------------------
884 -- purge_queue
885 -- The following procedure purges the passed in queue table.
886 -- ============================================================================
887 --
888 PROCEDURE purge_queue(p_queue_table_name VARCHAR2)
889 IS
890 BEGIN
891   --
892   truncate_table(p_queue_table_name);
893   --
894 END purge_queue;
895 --
896 -- ----------------------------------------------------------------------------
897 -- Full Refresh
898 -- ============================================================================
899 -- This procedure does very little, other than to set the date that the events
900 -- capture process, needs to run from, subsequent to the full refresh.
901 -- The process also purges the event queues,as the data will no longer be
902 -- required after a full refresh.
903 --
904 PROCEDURE full_refresh (p_refresh_to_date IN DATE DEFAULT NULL)
905 IS
906   --
907   -- Date to set fo full refresh end date.
908   --
909   l_refresh_to_date DATE;
910   --
911 BEGIN
912   --
913   -- Record that the full refresh process has started.
914   --
915   hri_bpl_conc_log.record_process_start(c_object_name);
916   --
917   -- Set the date that the full refresh is refreshed to. Normally this will be
918   -- trunc SYSDATE, but for testing purposes, we may sometimes wish to set an
919   -- earlier date.
920   --
921   IF p_refresh_to_date IS NULL
922   THEN
923     --
924     dbg('Setting refresh date to TRUNC(SYSDATE).');
925     --
926     l_refresh_to_date := SYSDATE;
927     --
928   --
929   -- This logic path will only ever be used for testing. It will allow
930   -- full refresh to be run up to a specified date.
931   --
932   ELSE
933     --
934     dbg('Setting refresh date to p_refresh_to_date.');
935     --
936     l_refresh_to_date := p_refresh_to_date;
937     --
938     -- Purge the dbi collection log, so that we do not have any more recent
939     -- processes in the log.
940     --
941     empty_evnts_cptr_refresh_log;
942     --
943   END IF;
944   --
945   dbg('l_refresh_to_date: '||TO_CHAR(l_refresh_to_date));
946   --
947   -- Empty the Event Queues
948   --
949   -- Truncate archive table
950   truncate_table('HRI_ARCHIVE_EVENTS');
951   -- Purge supervisor hierarchy queue
952   purge_queue('HRI_EQ_SPRVSR_HRCHY_CHGS');
953   -- Purge supervisor history queue
954   purge_queue('HRI_EQ_SPRVSR_HSTRY_CHGS');
955   -- Purge assignment events queue
956   purge_queue('HRI_EQ_ASGN_EVNTS');
957   -- Purge absence events queue
958   purge_queue('HRI_EQ_UTL_ABSNC_DIM');
959   --
960   -- Record the full refresh process has ended. This is the main purpose of
961   -- full refresh, as these dates will then be used to drive the dates that
962   -- the events capture process is then run for.
963   --
964   --
965   commit;
966   --
967   hri_bpl_conc_log.log_process_end
968           (p_status         => TRUE
969           ,p_period_from    => g_dbi_collection_start_date
970           ,p_period_to      => l_refresh_to_date);
971   --
972   commit;
973   --
974 END full_refresh;
975 --
976 -- ----------------------------------------------------------------------------
977 -- get_business_group_id
978 -- Gets the Business group ID for a given assignment_id
979 -- ============================================================================
980 --
981 FUNCTION get_business_group_id(p_assignment_id IN VARCHAR2)
982 RETURN NUMBER IS
983   --
984   CURSOR c_business_group(p_assignment_id IN VARCHAR2) IS
985     SELECT          business_group_id
986     FROM            per_all_assignments_f
987     WHERE           assignment_id = p_assignment_id;
988   --
989   l_business_group_id NUMBER;
990   --
991 BEGIN
992   --
993   -- Get the event group id
994   --
995   OPEN c_business_group(p_assignment_id);
996   FETCH c_business_group INTO l_business_group_id;
997   IF c_business_group%NOTFOUND
998   THEN
999     --
1000     -- 3710454 There are certain cases when the business_group_id will not
1001     -- be available eg. when the assignment is deleted. In such a case
1002     -- exception should not be raised but the interpreter should be called without
1003     -- with out the business_group parameter
1004     --
1005     dbg('Business Group for assignment "'||p_assignment_id||'" not found.');
1006     --
1007   END IF;
1008   --
1009   CLOSE c_business_group;
1010   --
1011   RETURN l_business_group_id;
1012   --
1013 END get_business_group_id;
1014 --
1015 -- ----------------------------------------------------------------------------
1016 -- get_event_group_id
1017 -- Gets the event group ID based on its name.
1018 -- ============================================================================
1019 --
1020 FUNCTION get_event_group_id(p_event_group_name IN VARCHAR2)
1021 RETURN NUMBER IS
1022   --
1023   CURSOR get_evt(p_grp IN VARCHAR2) IS
1024     SELECT          event_group_id
1025     FROM            pay_event_groups
1026     WHERE           event_group_name = p_grp;
1027   --
1028   l_event_group_id NUMBER;
1029   --
1030 BEGIN
1031   --
1032   dbg('Getting Event Group Id for '||p_event_group_name||' event group.');
1033   --
1034   -- Get the event group id
1035   --
1036   OPEN get_evt(p_event_group_name);
1037   FETCH get_evt INTO l_event_group_id;
1038   IF get_evt%NOTFOUND
1039   THEN
1040     --
1041     -- Trace some debug info and raise the error
1042     --
1043     dbg('Event group "'||p_event_group_name||'" not found.');
1044     --
1045     CLOSE get_evt;
1046     RAISE event_group_not_found;
1047     --
1048   END IF;
1049   --
1050   CLOSE get_evt;
1051   --
1052   dbg('Getting Event Group Id is '||l_event_group_id||'.');
1053   --
1054   RETURN l_event_group_id;
1055   --
1056 END get_event_group_id;
1057 --
1058 -- ----------------------------------------------------------------------------
1059 -- 5.1.1 (interpret_all_asgnmnt_changes)
1060 -- Get All Assignment Changes For The Master Event Group
1061 -- ============================================================================
1062 -- This procedure calls PEM interpreter package to populate a PLSQL table of
1063 -- all of the events that have occurred for assignments, where the event exists
1064 -- in the master event group. The master event group is an event group that
1065 -- contains all of the events contained in all of the sub event groups.
1066 -- The sub event groups contain only those events that relate to a given
1067 -- collection e.g. the supervisor hierarchy collection.
1068 --
1069 -- The concept of master event groups and sub event groups does not actually
1070 -- exist in PEM, so we need to make sure when we seed the sub event groups or
1071 -- change them, that the master event groups are also maintained.
1072 --
1073 PROCEDURE interpret_all_asgnmnt_changes
1074   (
1075    p_assignment_id IN NUMBER
1076   ,p_start_date IN DATE
1077   ,p_master_events_table
1078     IN OUT nocopy pay_interpreter_pkg.t_detailed_output_table_type
1079   )
1080 IS
1081   --
1082   -- The following 3 PLSQL tables are required as return placeholders for
1083   -- the procedure pay_interpreter_pkg.entry_affected. The results from
1084   -- these tables is CURRENTLY IGNORED.
1085   --
1086   l_proration_dates     pay_interpreter_pkg.t_proration_dates_table_type;
1087   l_proration_changes   pay_interpreter_pkg.t_proration_type_table_type;
1088   l_pro_type_tab        pay_interpreter_pkg.t_proration_type_table_type;
1089   --
1090   -- The business group id of the assignent
1091   --
1092   l_business_group_id    NUMBER;
1093   --
1094 BEGIN
1095   --
1096   dbg('Executing interpret_all_asgnmnt_changes ....');
1097   --
1098   -- Get the business group id for the assignment (p_assignment_id)
1099   -- this is not strictly necessary, but improves the performance
1100   -- of pay_interpreter_pkg.entry_affected
1101   --
1102   l_business_group_id := get_business_group_id(p_assignment_id);
1103   --
1104   -- Call the Payroll Events Model (PEM) interpreter to identify all
1105   -- of the events that have occurred for the assignment since p_start_date,
1106   -- in the master event group.
1107   --
1108   dbg('c_ee_id: '||c_ee_id);
1109   dbg('p_assignment_id: '||p_assignment_id);
1110   dbg('g_master_event_group_id: '||g_master_event_group_id);
1111   dbg('p_start_date: '||p_start_date);
1112   dbg('g_end_of_time: '||g_end_of_time);
1113   dbg('l_business_group_id: '||l_business_group_id);
1114   --
1115   IF l_business_group_id is not null THEN
1116     --
1117     pay_interpreter_pkg.entry_affected(
1118       p_element_entry_id      => c_ee_id
1119      ,p_assignment_action_id  => NULL
1120      ,p_assignment_id         => p_assignment_id
1121      ,p_mode                  => NULL -- pickup events of all types including
1122                                       -- 'REPORTS' and 'DATE_PROCESSED'
1123      ,p_process               => NULL
1124      ,p_event_group_id        => g_master_event_group_id
1125      ,p_process_mode          => 'ENTRY_CREATION_DATE'-- means I am
1126                                                       -- interested in
1127                                                       -- events created
1128      ,p_start_date            => p_start_date          -- between here
1129      ,p_end_date              => g_end_of_time            -- and here
1130      ,p_unique_sort           => 'N' -- tells the interpreter not to do a
1131                                      -- unique sort, and this improves
1132                                      -- performance.
1133      ,p_business_group_id     => l_business_group_id
1134      ,t_detailed_output       => p_master_events_table  --OUTPUT OF RESULTS
1135      ,t_proration_dates       => l_proration_dates      --IGNORED
1136      ,t_proration_change_type => l_proration_changes    --IGNORED
1137      ,t_proration_type        => l_pro_type_tab);       --IGNORED
1138     --
1139   ELSE
1140     --
1141     -- 3710454 As business_group_id is not found for the assignment, call the
1142     -- interpreter version which does not take the business group parameters.
1143     -- Note: This version is inefficient, but we don't want to miss any events
1144     -- which has happened to an assignment
1145     --
1146     pay_interpreter_pkg.entry_affected(
1147       p_element_entry_id      => c_ee_id
1148      ,p_assignment_action_id  => NULL
1149      ,p_assignment_id         => p_assignment_id
1150      ,p_mode                  => NULL
1151      ,p_process               => NULL
1152      ,p_event_group_id        => g_master_event_group_id
1153      ,p_process_mode          => 'ENTRY_CREATION_DATE'
1154      ,p_start_date            => p_start_date           -- Events from
1155      ,p_end_date              => g_end_of_time          -- till here
1156      ,t_detailed_output       => p_master_events_table  -- OUTPUT OF RESULTS
1157      ,t_proration_dates       => l_proration_dates      -- IGNORED
1158      ,t_proration_change_type => l_proration_changes    -- IGNORED
1159      ,t_proration_type        => l_pro_type_tab);       -- IGNORED
1160     --
1161   END IF;
1162   --
1163   dbg('Rows Returned: '||TO_CHAR(p_master_events_table.COUNT));
1164   --
1165   -- Loop through rows returned by the interpreter for dubug
1166   -- purposes only.
1167   --
1168   -- ONLY if debugging is on output log information
1169   --
1170   IF g_debug_flag = 'Y' THEN
1171     --
1172     FOR i in 1..p_master_events_table.COUNT
1173     LOOP
1174       --
1175       dbg(' dated_table_id: '||TO_CHAR(p_master_events_table(i).dated_table_id)
1176         ||', datetracked_event: '||p_master_events_table(i).datetracked_event
1177         ||', update_type: '||p_master_events_table(i).update_type
1178         ||', surrogate_key: '||TO_CHAR(p_master_events_table(i).surrogate_key)
1179         ||', column_name: '||TO_CHAR(p_master_events_table(i).column_name)
1180         ||', Effective_date: '||p_master_events_table(i).effective_date
1181         ||', old_value: '||p_master_events_table(i).old_value
1182         ||', new_value: '||p_master_events_table(i).new_value
1183         ||', change_values: '||p_master_events_table(i).change_values
1184         ||', proration_type: '||p_master_events_table(i).proration_type
1185         ||', change_mode: '||p_master_events_table(i).change_mode
1186         ||', element_entry_id: '||p_master_events_table(i).element_entry_id
1187         ||', next_ee: '||p_master_events_table(i).next_ee
1188        );
1189       --
1190     END LOOP;
1191     --
1192   END IF; -- end of debug condition
1193   --
1194 END interpret_all_asgnmnt_changes;
1195 --
1196 -- ----------------------------------------------------------------------------
1197 -- Update_archive_record
1198 -- Log details for the identified event
1199 -- ============================================================================
1200 -- Updates hri_archive_events with details of the action taken for
1201 -- the earliest event found for an assignent event.
1202 --
1203 PROCEDURE Update_archive_record
1204   (p_assignment_id         IN NUMBER
1205   ,p_change_date           IN DATE     -- The effective change date
1206   ,p_event_queue_table     IN VARCHAR2 -- The table name of the event queue we
1207                                        -- have identified the event for.
1208   ,p_action_taken          IN VARCHAR2 -- The action taken with the event we
1209                                        -- have identified.
1210   ,p_capture_from_date     IN DATE     -- The date that the event queue was
1211                                        -- was using as a start date when the
1212                                        -- event was found.
1213   )
1214 IS
1215   --
1216 BEGIN
1217   --
1218   INSERT INTO hri_archive_events
1219   (
1220    assignment_id
1221   ,event_queue_table
1222   ,action_taken
1223   ,erlst_evnt_effective_date
1224   ,capture_from_date
1225   )
1226   VALUES
1227   (
1228    p_assignment_id
1229   ,p_event_queue_table
1230   ,p_action_taken
1231   ,p_change_date
1232   ,p_capture_from_date
1233   );
1234   --
1235 END Update_archive_record;
1236 --
1237 -- ----------------------------------------------------------------------------
1238 -- 5.1.2.2 (Update_Sprvsr_Hstry_Evnt_Q)
1239 -- Update the Supervisor Hierarchy Event Queue
1240 -- ============================================================================
1241 -- This procedure will for the given assignment_id and change date, update
1242 -- the event queue by either:
1243 --
1244 -- + Insert a new record in the event queue (if no record for that assignment
1245 --   exists for the assignment).
1246 -- + Update the existing record in the event queue for the assignment, if it
1247 --   exists, and has a later date than the new event you have found.
1248 -- + Do nothing to the event queue as there is already an early change record
1249 --   for the assignment.
1250 --
1251 -- The procedure will also insert arecord of the event in hri_archive_events
1252 -- for audit purposes to record the event capture and what was done to the
1253 -- event queue as a result of the event capture.
1254 --
1255 PROCEDURE Update_Sprvsr_Hstry_Evnt_Q
1256   (p_assignment_id IN NUMBER
1257   ,p_change_date   IN DATE -- The effective change date
1258   ,p_start_date    IN DATE -- The date the events were captured from
1259   )
1260 IS
1261   --
1262   -- Select the erlst_evnt_processed_date from the event queue
1263   -- for the assignment_id if it exists, so that we can decide
1264   -- whether we need to:
1265   --
1266   -- + Insert if there is no record for the assignment in the queue.
1267   -- + Update the queue if p_change_date is earlier than
1268   --   erlst_evnt_processed_date.
1269   -- + Do nothing.
1270   --
1271   CURSOR c_get_queued_event(cp_assignment_id IN NUMBER) IS
1272     SELECT erlst_evnt_effective_date
1273     FROM   hri_eq_sprvsr_hstry_chgs
1274     WHERE  assignment_id = cp_assignment_id;
1275   --
1276   l_erlst_evnt_effective_date DATE; -- Stores the earliest event data for
1277                                     -- the assignment currently stored
1278                                     -- in the event queue.
1279   --
1280   l_action_taken VARCHAR2(30); -- used to store what we do with the passed
1281                                -- in event. This is used when inserting
1282                                -- into hri_archive_events to show what action
1283                                -- we took with the captured event.
1284   --
1285 BEGIN
1286   --
1287   dbg('Updating the Supervisor History Events Queue for '||p_assignment_id||'.');
1288   --
1289   -- Exit if HRI:Populate Supervisor Status History Events Queue is not enabled
1290   --
1291   IF g_col_sup_hstry_eq = 'N' THEN
1292     --
1293     dbg('Profile HRI:Populate Supervisor Status History Events Queue not enabled, '||
1294         'skip populating supervisor status history events queue');
1295     return;
1296     --
1297   END IF;
1298   --
1299   -- Get the earliest change date currently stored in the event queue
1300   -- (l_erlst_evnt_processed_date), where it exists.
1301   --
1302   OPEN c_get_queued_event(p_assignment_id);
1303   FETCH c_get_queued_event INTO l_erlst_evnt_effective_date;
1304   --
1305   -- If no record exists in the queue for the assignment, then we need to
1306   -- INSERT into the event queue.
1307   --
1308   IF c_get_queued_event%NOTFOUND OR c_get_queued_event%NOTFOUND IS NULL
1309   THEN
1310     --
1311     dbg('No record  for assignment '||p_assignment_id||' exists, so INSERT.');
1312     --
1313     INSERT INTO hri_eq_sprvsr_hstry_chgs
1314     (
1315      assignment_id
1316     ,erlst_evnt_effective_date
1317     )
1318     VALUES
1319     (
1320      p_assignment_id
1321     ,p_change_date
1322     );
1323     --
1324     l_action_taken := 'INSERTED';
1325     --
1326   --
1327   -- If there is already a record in hri_eq_asgn_evnts for the assignment_id
1328   -- but it is for an event that occurred later or at the same time as the
1329   -- new event we have found (p_change_date), then update the queue with the
1330   -- earlier date.
1331   --
1332   ELSIF l_erlst_evnt_effective_date > p_change_date
1333   THEN
1334     --
1335     dbg('Record is earlier than one in queue currently for '||p_assignment_id||', so UPDATE.');
1336     --
1337     UPDATE hri_eq_sprvsr_hstry_chgs
1338     SET erlst_evnt_effective_date = p_change_date
1339     WHERE assignment_id = p_assignment_id;
1340     --
1341     l_action_taken := 'UPDATED';
1342     --
1343   ELSE
1344     --
1345     dbg('Record is later, or the same date as the one in queue currently for '||p_assignment_id||', so do NOTHING.');
1346     --
1347     l_action_taken := 'NONE';
1348     --
1349   END IF;
1350   --
1351   -- Update the hri_archive_events table with details of what we have
1352   -- done for the identified event.
1353   --
1354   IF g_enable_archive_flag = 'Y' THEN
1355     --
1356     Update_archive_record
1357       (
1358        p_assignment_id     => p_assignment_id
1359       ,p_change_date       => p_change_date
1360       ,p_event_queue_table => 'HRI_EQ_SPRVSR_HSTRY_CHGS'
1361       ,p_action_taken      => l_action_taken
1362       ,p_capture_from_date => p_start_date
1363       );
1364     --
1365   END IF;
1366   --
1367 END Update_Sprvsr_Hstry_Evnt_Q;
1368 --
1369 --
1370 -- ----------------------------------------------------------------------------
1371 -- 5.1.2.1 (Update_Sprvsr_Hrchy_Evnt_Q)
1372 -- Update the Supervisor Hierarchy Event Queue
1373 -- ============================================================================
1374 -- This procedure will for the given assignment_id and change date, update
1375 -- the event queue by either:
1376 --
1377 -- + Insert a new record in the event queue (if no record for that assignment
1378 --   exists for the assignment).
1379 -- + Update the existing record in the event queue for the assignment, if it
1380 --   exists, and has a later date than the new event you have found.
1381 -- + Do nothing to the event queue as there is already an early change record
1382 --   for the assignment.
1383 --
1384 -- The procedure will also insert arecord of the event in hri_archive_events
1385 -- for audit purposes to record the event capture and what was done to the
1386 -- event queue as a result of the event capture.
1387 --
1388 PROCEDURE Update_Sprvsr_Hrchy_Evnt_Q
1389   (p_assignment_id IN NUMBER
1390   ,p_change_date   IN DATE -- The effective change date
1391   ,p_start_date    IN DATE -- The date the events were captured from
1392   )
1393 IS
1394   --
1395   -- Select the erlst_evnt_processed_date from the event queue
1396   -- for the assignment_id if it exists, so that we can decide
1397   -- whether we need to:
1398   --
1399   -- + Insert if there is no record for the assignment in the queue.
1400   -- + Update the queue if p_change_date is earlier than
1401   --   erlst_evnt_processed_date.
1402   -- + Do nothing.
1403   --
1404   CURSOR c_get_queued_event(cp_assignment_id IN NUMBER) IS
1405     SELECT erlst_evnt_effective_date
1406     FROM   hri_eq_sprvsr_hrchy_chgs
1407     WHERE  assignment_id = cp_assignment_id;
1408   --
1409   l_erlst_evnt_effective_date DATE; -- Stores the earliest event data for
1410                                     -- the assignment currently stored
1411                                     -- in the event queue.
1412   --
1413   l_action_taken VARCHAR2(30); -- used to store what we do with the passed
1414                                -- in event. This is used when inserting
1415                                -- into hri_archive_events to show what action
1416                                -- we took with the captured event.
1417   --
1418 BEGIN
1419   --
1420   dbg('Updating the Supervisor Hierarchy Events Queue for '||p_assignment_id||'.');
1421   --
1422   -- Exit if HRI:Populate Supervisor Hierarchy Events Queue is not enabled
1423   --
1424   IF g_col_sup_hrchy_eq = 'N' THEN
1425     --
1426     dbg('Profile HRI:Populate Supervisor Hierarchy Events Queue not enabled, '||
1427         'skip populating supervisor hierarchy events queue');
1428     return;
1429     --
1430   END IF;
1431   --
1432   -- Get the earliest change date currently stored in the event queue
1433   -- (l_erlst_evnt_processed_date), where it exists.
1434   --
1435   OPEN c_get_queued_event(p_assignment_id);
1436   FETCH c_get_queued_event INTO l_erlst_evnt_effective_date;
1437   --
1438   -- If no record exists in the queue for the assignment, then we need to
1439   -- INSERT into the event queue.
1440   --
1441   IF c_get_queued_event%NOTFOUND OR c_get_queued_event%NOTFOUND IS NULL
1442   THEN
1443     --
1444     dbg('No record  for assignment '||p_assignment_id||' exists, so INSERT.');
1445     --
1446     INSERT INTO hri_eq_sprvsr_hrchy_chgs
1447     (
1448      assignment_id
1449     ,erlst_evnt_effective_date
1450     )
1451     VALUES
1452     (
1453      p_assignment_id
1454     ,p_change_date
1455     );
1456     --
1457     l_action_taken := 'INSERTED';
1458     --
1459   --
1460   -- If there is already a record in hri_eq_asgn_evnts for the assignment_id
1461   -- but it is for an event that occurred later or at the same time as the
1462   -- new event we have found (p_change_date), then update the queue with the
1463   -- earlier date.
1464   --
1465   ELSIF l_erlst_evnt_effective_date > p_change_date
1466   THEN
1467     --
1468     dbg('Record is earlier than one in queue currently for '
1469         ||p_assignment_id||', so UPDATE.');
1470     --
1471     UPDATE hri_eq_sprvsr_hrchy_chgs
1472     SET erlst_evnt_effective_date = p_change_date
1473     WHERE assignment_id = p_assignment_id;
1474     --
1475     l_action_taken := 'UPDATED';
1476     --
1477   ELSE
1478     --
1479     dbg('Record is later, or the same date as the one in queue currently for '
1480         ||p_assignment_id||', so do NOTHING.');
1481     --
1482     l_action_taken := 'NONE';
1483     --
1484   END IF;
1485   --
1486   -- Update the hri_archive_events table with details of what we have
1487   -- done for the identified event.
1488   --
1489   IF g_enable_archive_flag = 'Y' THEN
1490     --
1491     Update_archive_record
1492       (
1493        p_assignment_id     => p_assignment_id
1494       ,p_change_date       => p_change_date
1495       ,p_event_queue_table => 'HRI_EQ_SPRVSR_HRCHY_CHGS'
1496       ,p_action_taken      => l_action_taken
1497       ,p_capture_from_date => p_start_date
1498       );
1499     --
1500   END IF;
1501   --
1502 END Update_Sprvsr_Hrchy_Evnt_Q;
1503 --
1504 -- ----------------------------------------------------------------------------
1505 -- Find_sub_event_group_events
1506 -- Find the earliest event in the master event group PLSQL table for a given
1507 -- sub event group id.
1508 -- ============================================================================
1509 --
1510 -- This procedure calls pay_interpreter_pkg.get_subset_given_new_evg to
1511 -- process the alreadu identified events in the master event group, to see
1512 -- if any of those events are in the sub event group.
1513 --
1514 -- If any events are found in the sub event group, then the earliest event date
1515 -- found is returned via p_event_date to the calling process.
1516 --
1517 -- The package pay_interpreter_pkg.get_subset_given_new_evg returns a PLSQL
1518 -- table similar to the one passed in, but only containing those rows that
1519 -- are relevant to these event queues. The earliest of the records found in
1520 -- the returned PLSQL table, is then used to update the event queues.
1521 --
1522 --
1523 PROCEDURE Find_sub_event_group_events
1524   (
1525    p_assignment_id IN NUMBER    -- The assignment id that we are currently
1526                                 -- processing.
1527   ,p_start_date IN DATE         -- Used for updating the event archive only.
1528                                 -- Does not effect process flow in this
1529                                 -- procedure.
1530   ,p_sub_event_grp_id IN NUMBER -- The event group id of the sub event group
1531                                 -- that we are trying to find events for.
1532   ,p_comment_text VARCHAR2      -- Text used by debug comments to indicate
1533                                 -- which queue's sub eveng group is being
1534                                 -- processed.
1535   ,p_master_events_table        -- The Master Event Group PLSQL table.
1536     IN OUT nocopy pay_interpreter_pkg.t_detailed_output_table_type
1537   ,p_event_date OUT nocopy DATE -- Event date of the earliest sub event found
1538                                 -- in the passed in event group and
1539                                 -- master events table
1540   ,p_sub_evt_grp_tbl OUT nocopy pay_interpreter_pkg.t_detailed_output_table_type
1541                                  -- This array is only relevant as an
1542                                  -- output value when p_event_capture_mode
1543                                  -- is 'S'.
1544                                  --
1545   ,p_event_capture_mode IN VARCHAR2 -- Indicates whether the process should
1546                                  -- E) return the earliest date for a
1547                                  --    relevant change.
1548                                  -- OR
1549                                  -- R) Return simply the fact that a
1550                                  --    relevant change has been found
1551                                  -- OR
1552                                  -- S) Return the sub event group array
1553                                  --    for further processing.
1554   )
1555 IS
1556   --
1557   -- We only care about the earliest change for an assignment. l_min_date is
1558   -- used to store the earliest effective_date date found in the PLSQL table
1559   -- l_sub_evt_grp_tbl returned from the call to
1560   -- pay_interpreter_pkg.get_subset_given_new_evg
1561   --
1562   --
1563   l_min_date             DATE;
1564   l_effective_date       DATE;
1565   l_extns_date           DATE;
1566   --
1567 BEGIN
1568   --
1569   dbg('Executing Find_sub_event_group_events for '||p_comment_text
1570       ||' in mode '|| p_event_capture_mode ||'....');
1571   --
1572   -- If the master event group PLSQL table is empty then there is no
1573   -- point continuing, so exit procedure.
1574   --
1575   IF p_master_events_table.COUNT = 0
1576   THEN
1577     --
1578     dbg('0 records in master table for '||p_comment_text||
1579         ', exiting Find_sub_event_group_events');
1580     --
1581     p_event_date := NULL;
1582     --
1583     RETURN;
1584     --
1585   END IF;
1586   --
1587   -- Set the minimum change date for the assignment to end of time.
1588   --
1589   l_min_date := g_end_of_time;
1590   --
1591   -- Find all the events in the master event group for the assignment that
1592   -- relate to the sub event group for changes relevant to the assignment
1593   -- events fact.
1594   --
1595   dbg('Calling pay_interpreter_pkg.get_subset_given_new_evg ...');
1596   --
1597   pay_interpreter_pkg.get_subset_given_new_evg
1598     (p_filter_event_group_id => p_sub_event_grp_id
1599     ,p_complete_detail_tab   => p_master_events_table
1600     ,p_subset_detail_tab     => p_sub_evt_grp_tbl
1601     );
1602   --
1603   dbg('Sub Event Rows Returned: '||p_sub_evt_grp_tbl.COUNT);
1604   --
1605   -- The followin IF statement is used for debugging only.
1606   --
1607   IF (p_sub_evt_grp_tbl.COUNT <> p_master_events_table.COUNT)
1608      AND
1609      (g_debug_flag = 'Y')
1610   THEN
1611     --
1612     dbg(
1613         'Row number discrepency found for assignment: '
1614         ||TO_CHAR(p_assignment_id)||','
1615         ||TO_CHAR(p_master_events_table.COUNT)||','
1616         ||TO_CHAR(p_sub_evt_grp_tbl.COUNT)
1617        );
1618     --
1619   END IF;
1620   --
1621   -- Only need to check find the earliest change if rows have been found
1622   -- that relate to the sub event group.
1623   --
1624   IF p_sub_evt_grp_tbl.COUNT > 0
1625   THEN
1626     --
1627     dbg('Found some records in the '||p_comment_text||' sub event group');
1628     --
1629   ELSE
1630     --
1631     dbg('No relevant records found that affect '||p_comment_text||'.');
1632     --
1633     -- No relevant events found, so return NULL date, this will be used by the
1634     -- calling process, to decide not to do anything further.
1635     --
1636     p_event_date := NULL;
1637     --
1638     RETURN;
1639     --
1640   END IF; -- If l_sub_evt_grp_tbl.COUNT > 0
1641   --
1642   -- If we are in mode 'R' simply return the fact that an
1643   -- event has been found within the specified period.
1644   --
1645   IF p_event_capture_mode = 'R'
1646   THEN
1647     --
1648     -- If any events have occurred for the sub event group within
1649     -- the period this mode will simply return 'end of time'
1650     --
1651     dbg('An event has been found within the period ...');
1652     dbg('As called in mode ''R'' return p_event_date as ''end of time''.');
1653     --
1654     p_event_date := g_end_of_time;
1655     --
1656     RETURN;
1657     --
1658   END IF;
1659   --
1660   -- Default mode 'S' will return the earliest relevent sub event group
1661   -- event date for the assignment within the period, and p_sub_evt_grp_tbl
1662   -- which can be ignored.
1663   --
1664   IF p_event_capture_mode = 'S'
1665   THEN
1666     --
1667     -- If any events have occurred for the sub event group within
1668     -- the period this mode will simply return 'end of time' and the
1669     -- array p_sub_evt_grp_tbl.
1670     --
1671     dbg('An event has been found within the period ...');
1672     dbg('As called in mode ''S'' return p_event_date as ''end of time'''||
1673         ' and return the sub event group array ''p_sub_evt_grp_tbl'''||
1674         ' for further processing.');
1675     --
1676     p_event_date := g_end_of_time;
1677     --
1678     RETURN;
1679     --
1680   END IF; -- Default get earliest date of change mode 'S'
1681   --
1682   -- Default mode 'E' will return the earliest relevent sub event group
1683   -- event date for the assignment within the period.
1684   --
1685   IF p_event_capture_mode = 'E'
1686   THEN
1687     --
1688     -- Default get earliest date of change mode 'E'
1689     --
1690     dbg('Find_sub_event_group_events has been called in mode ''E''.');
1691     --
1692     FOR i in 1..p_sub_evt_grp_tbl.COUNT
1693     LOOP
1694       --
1695       -- Call the function which evaluates the event date for special cases
1696       -- such as Termination date evaluation, extension date calculations etc.
1697       -- It returns the adjusted event date or the effective change date
1698       --
1699       l_effective_date := eval_one_off_cases
1700                             (p_sub_evt_grp_tbl   => p_sub_evt_grp_tbl(i)
1701                             ,p_assignment_id     => p_assignment_id
1702                             ,p_comment_text      => p_comment_text
1703                             ,p_effective_date    => p_sub_evt_grp_tbl(i).effective_date);
1704       --
1705       -- If the change date of the current record is less than l_min_date
1706       -- change l_min_date to equal that date. At the end of the loop
1707       -- l_min_date will be set to the earliest change date for the assignment
1708       -- since p_start_date.
1709       --
1710       IF l_effective_date < l_min_date
1711       THEN
1712         --
1713         l_min_date := l_effective_date;
1714         --
1715         dbg('Earliest date found so far: '||TO_CHAR(l_min_date));
1716         --
1717       END IF;
1718       --
1719       -- Following IF statement is for debug purposes only.
1720       --
1721       IF g_debug_flag = 'Y'
1722       THEN
1723         --
1724         dbg('Datetracked_event: '||p_sub_evt_grp_tbl(i).datetracked_event
1725           ||', Change_mode: '||p_sub_evt_grp_tbl(i).change_mode
1726           ||', Effective_date: '||p_sub_evt_grp_tbl(i).effective_date
1727           ||', dated_table_id: '||TO_CHAR(p_sub_evt_grp_tbl(i).dated_table_id)
1728           ||', surrogate_key: '||TO_CHAR(p_sub_evt_grp_tbl(i).surrogate_key)
1729           ||', column_name: '||TO_CHAR(p_sub_evt_grp_tbl(i).column_name)
1730           ||', old_value: '||p_sub_evt_grp_tbl(i).old_value
1731           ||', new_value: '||p_sub_evt_grp_tbl(i).new_value
1732           ||', change_values: '||p_sub_evt_grp_tbl(i).change_values
1733           );
1734         --
1735       END IF; -- g_debug_flag = 'Y'
1736       --
1737     END LOOP;
1738     --
1739     -- Set p_event_date to the earliest event date found. This will be used
1740     -- by the calling procedure to update the relevant event queue.
1741     --
1742     -- 3906029, For supervisor hierarchy events the min date returned by the
1743     -- wrapper, cannot be used directly. In case the event occurs before the
1744     -- minimum date for which the hierarchy is populated, the collection program
1745     -- will collect data which can corrupt the hierarchy with duplicate records
1746     -- for subordinates. So the min date should returned should not be
1747     -- less than the Refresh From Date for the last full refresh run of supervisor
1748     -- hierarchy
1749     --
1750     IF p_comment_text = 'Supervisor' THEN
1751       --
1752       dbg('As this is a supervisor event, we need to make sure event date '||
1753           'returned (p_event_date) is no less than minimum date for which '||
1754           'the supervisor hierarchy has been populated');
1755       --
1756       p_event_date := greatest(l_min_date,g_min_suph_date);
1757       --
1758     ELSIF l_min_date = g_end_of_time THEN
1759       --
1760       -- In case the min event date is eot then there is no need to create an event
1761       -- the l_min_date is initialized to EOT, and there is no point in capturing an event
1762       -- which is happening so far in time.
1763       --
1764       dbg('l_min_date IS EOT so set p_event_date to NULL');
1765       --
1766       p_event_date := null;
1767       --
1768     ELSE
1769       --
1770       dbg('Just return the earliest date found');
1771       --
1772       p_event_date := l_min_date;
1773       --
1774     END IF;
1775     --
1776     dbg('Returning p_event_date as '||TO_CHAR(p_event_date)||'.');
1777     --
1778     RETURN;
1779     --
1780   END IF; -- Default get earliest date of change mode 'E'
1781   --
1782 END Find_sub_event_group_events;
1783 --
1784 -- Overloaded version of procedure to be called for event groups where we
1785 -- are interested in the earliest change for an assignment, as opposed
1786 -- to just being interested in the whether an event has occurred at all.
1787 --
1788 PROCEDURE Find_sub_event_group_events
1789   (
1790    p_assignment_id IN NUMBER    -- The assignment id that we are currently
1791                                 -- processing.
1792   ,p_start_date IN DATE         -- Used for updating the event archive only.
1793                                 -- Does not effect process flow in this
1794                                 -- procedure.
1795   ,p_sub_event_grp_id IN NUMBER -- The event group id of the sub event group
1796                                 -- that we are trying to find events for.
1797   ,p_comment_text VARCHAR2      -- Text used by debug comments to indicate
1798                                 -- which queue's sub eveng group is being
1799                                 -- processed.
1800   ,p_master_events_table        -- The Master Event Group PLSQL table.
1801     IN OUT nocopy pay_interpreter_pkg.t_detailed_output_table_type
1802   ,p_event_date OUT nocopy DATE -- Event date of the earliest sub event found
1803                                 -- in the passed in event group and
1804                                 -- master events table
1805   )
1806 IS
1807   --
1808   -- The following PLSQL table will hold the events found from the master
1809   -- event group that relate to sub event group for the passed in sub event
1810   -- group id (p_sub_event_grp_id). It's return value is ignored
1811   --
1812   l_sub_evt_grp_tbl pay_interpreter_pkg.t_detailed_output_table_type;
1813   --
1814 BEGIN
1815   --
1816   Find_sub_event_group_events
1817   (
1818    p_assignment_id => p_assignment_id
1819   ,p_start_date => p_start_date
1820   ,p_sub_event_grp_id => p_sub_event_grp_id
1821   ,p_comment_text => p_comment_text
1822   ,p_master_events_table => p_master_events_table
1823   ,p_event_date => p_event_date
1824   ,p_sub_evt_grp_tbl => l_sub_evt_grp_tbl -- result ignored when called from here
1825   ,p_event_capture_mode => 'E' -- Indicates we want to know earliest event
1826   );
1827   --
1828 END;
1829 --
1830 -- ----------------------------------------------------------------------------
1831 -- 5.1.2 (Process_supervisor_events)
1832 -- Get Earliest Supervisor Event For Assignment
1833 -- ============================================================================
1834 -- This procedure calls the procedure Find_sub_event_group_events, passing
1835 -- in the master event group PLSQL table (containing all the interpreted
1836 -- events that have occurred since p_start_date for the assignment), to
1837 -- identify all of the events that have occurred that are relevent to
1838 -- the supervisor hierarchy, and supervisor status history event queues.
1839 --
1840 PROCEDURE Process_supervisor_events
1841   (p_assignment_id IN NUMBER
1842   ,p_start_date IN DATE
1843   ,p_master_events_table
1844     IN OUT nocopy pay_interpreter_pkg.t_detailed_output_table_type)
1845 IS
1846   --
1847   -- l_min_date is used to store the earliest effective_date date found
1848   -- by the procedure Find_sub_event_group_events for the sub event group
1849   --
1850   l_min_date DATE;
1851   --
1852 BEGIN
1853   --
1854   dbg('Executing Process_supervisor_events ....');
1855   --
1856   -- 3658545 exit if the supervisor related queues are not to be populated
1857   --
1858   IF g_col_sup_hrchy_eq = 'N' AND
1859      g_col_sup_hstry_eq = 'N'
1860   THEN
1861     --
1862     dbg('Not populating supervisor related queues');
1863     RETURN;
1864     --
1865   END IF;
1866   --
1867   Find_sub_event_group_events
1868     (
1869      p_assignment_id => p_assignment_id
1870     ,p_start_date => p_start_date
1871     ,p_sub_event_grp_id => g_sprvsr_change_event_grp_id
1872     ,p_comment_text => 'Supervisor'
1873     ,p_master_events_table => p_master_events_table
1874     ,p_event_date => l_min_date
1875     );
1876   --
1877   -- If l_min_date is NOT NULL this means that Find_sub_event_group_events
1878   -- has found an event for the sub event group, and assignment id on that
1879   -- date. We therefore need to see if it is necessary to update the relevant
1880   -- event queues with this information.
1881   --
1882   IF l_min_date IS NOT NULL
1883   THEN
1884     --
1885     Update_Sprvsr_Hrchy_Evnt_Q
1886       (
1887        p_assignment_id => p_assignment_id
1888       ,p_change_date   => l_min_date
1889       ,p_start_date    => p_start_date
1890       );
1891     --
1892     Update_Sprvsr_Hstry_Evnt_Q
1893       (
1894        p_assignment_id => p_assignment_id
1895       ,p_change_date   => l_min_date
1896       ,p_start_date    => p_start_date
1897       );
1898     --
1899   END IF;
1900   --
1901 END Process_supervisor_events;
1902 --
1903 -- ----------------------------------------------------------------------------
1904 -- 5.1.3.1 (Update_Asgn_Evnt_Fct_Evnt_Q)
1905 -- Update the Assignment Event Fact Event Queue
1906 -- ============================================================================
1907 -- This procedure will for the given assignment_id and change date, update
1908 -- the event queue by either:
1909 --
1910 -- + Insert a new record in the event queue (if no record for that assignment
1911 --   exists for the assignment).
1912 -- + Update the existing record in the event queue for the assignment, if it
1913 --   exists, and has a later date than the new event you have found.
1914 -- + Do nothing to the event queue as there is already an early change record
1915 --   for the assignment.
1916 --
1917 -- The procedure will also insert arecord of the event in hri_archive_events
1918 -- for audit purposes to record the event capture and what was done to the
1919 -- event queue as a result of the event capture.
1920 --
1921 PROCEDURE Update_Asgn_Evnt_Fct_Evnt_Q
1922   (p_assignment_id IN NUMBER
1923   ,p_change_date   IN DATE -- The effective change date
1924   ,p_start_date    IN DATE -- The date the events were captured from
1925   )
1926 IS
1927   --
1928   -- Select the erlst_evnt_processed_date from the event queue
1929   -- for the assignment_id if it exists, so that we can decide
1930   -- whether we need to:
1931   --
1932   -- + Insert if there is no record for the assignment in the queue.
1933   -- + Update the queue if p_change_date is earlier than
1934   --   erlst_evnt_processed_date.
1935   -- + Do nothing.
1936   --
1937   CURSOR c_get_queued_event(cp_assignment_id IN NUMBER) IS
1938     SELECT erlst_evnt_effective_date
1939     FROM   hri_eq_asgn_evnts
1940     WHERE  assignment_id = cp_assignment_id;
1941   --
1942   l_erlst_evnt_effective_date DATE; -- Stores the earliest event data for
1943                                     -- the assignment currently stored
1944                                     -- in the wvwnt queue.
1945   --
1946   l_action_taken VARCHAR2(30); -- used to store what we do with the passed
1947                                -- in event. This is used when inserting
1948                                -- into hri_archive_events to show what action
1949                                -- we took with the captured event.
1950   --
1951 BEGIN
1952   --
1953   dbg('Updating the Assignment Events Queue for '||p_assignment_id||'.');
1954   --
1955   -- Get the earliest change date currently stored in the event queue
1956   -- (l_erlst_evnt_processed_date), where it exists.
1957   --
1958   OPEN c_get_queued_event(p_assignment_id);
1959   FETCH c_get_queued_event INTO l_erlst_evnt_effective_date;
1960   --
1961   -- If no record exists in the queue for the assignment, then we need to
1962   -- INSERT into the event queue.
1963   --
1964   IF c_get_queued_event%NOTFOUND OR c_get_queued_event%NOTFOUND IS NULL
1965   THEN
1966     --
1967     dbg('No record  for assignment '||p_assignment_id||' exists, so INSERT.');
1968     --
1969     INSERT INTO hri_eq_asgn_evnts
1970     (
1971      assignment_id
1972     ,erlst_evnt_effective_date
1973     )
1974     VALUES
1975     (
1976      p_assignment_id
1977     ,p_change_date
1978     );
1979     --
1980     l_action_taken := 'INSERTED';
1981     --
1982   --
1983   -- If there is already a record in hri_eq_asgn_evnts for the assignment_id
1984   -- but it is for an event that occurred later or at the same time as the
1985   -- new event we have found (p_change_date), then update the queue with the
1986   -- earlier date.
1987   --
1988   ELSIF l_erlst_evnt_effective_date > p_change_date
1989   THEN
1990     --
1991     dbg('Record is earlier than one in queue currently for '||p_assignment_id||', so UPDATE.');
1992     --
1993     UPDATE hri_eq_asgn_evnts
1994     SET erlst_evnt_effective_date = p_change_date
1995     WHERE assignment_id = p_assignment_id;
1996     --
1997     l_action_taken := 'UPDATED';
1998     --
1999   ELSE
2000     --
2001     dbg('Record is later, or the same date as the one in queue currently for '||p_assignment_id||', so do NOTHING.');
2002     --
2003     l_action_taken := 'NONE';
2004     --
2005   END IF;
2006   --
2007   -- Update the hri_archive_events table with details of what we have
2008   -- done for the identified event.
2009   --
2010   IF g_enable_archive_flag = 'Y' THEN
2011     --
2012     Update_archive_record
2013       (
2014        p_assignment_id     => p_assignment_id
2015       ,p_change_date       => p_change_date
2016       ,p_event_queue_table => 'HRI_EQ_ASGN_EVNTS'
2017       ,p_action_taken      => l_action_taken
2018       ,p_capture_from_date => p_start_date
2019       );
2020   --
2021   END IF;
2022   --
2023 END Update_Asgn_Evnt_Fct_Evnt_Q;
2024 
2025 
2026 --
2027 -- ----------------------------------------------------------------------------
2028 -- 5.1.3.??? (Update_Absence_Dim_Evnt_Q)
2029 -- Update the Assignment Event Fact Event Queue
2030 -- ============================================================================
2031 -- This procedure will for the given assignment_id and change date, update
2032 -- the event queue by either:
2033 --
2034 -- + Insert a new record in the event queue (if no record for that assignment
2035 --   exists for the assignment).
2036 -- + Do nothing to the event queue as there is already a change record
2037 --   for the assignment.
2038 --
2039 -- The procedure will also insert arecord of the event in hri_archive_events
2040 -- for audit purposes to record the event capture and what was done to the
2041 -- event queue as a result of the event capture.
2042 --
2043 PROCEDURE Update_Absence_Dim_Evnt_Q
2044   (p_assignment_id   IN NUMBER
2045   ,p_start_date      IN DATE     -- The date the events were captured from
2046   ,p_sub_evt_grp_tbl IN  pay_interpreter_pkg.t_detailed_output_table_type
2047                                  -- The events found in the sub event group
2048                                  -- that need to be processed to identify
2049                                  -- which absence_attendance_ids have had
2050                                  -- events.
2051   )
2052 IS
2053   --
2054   -- Identify if an event is already queued for the absence_attendance_id
2055   --
2056   CURSOR c_get_queued_event(cp_absence_attendance_id IN NUMBER) IS
2057     SELECT 'X' h_dummy
2058     FROM   hri_eq_utl_absnc_dim
2059     WHERE  absence_attendance_id = cp_absence_attendance_id;
2060   --
2061   -- Stores the previous absence attendance id being processed.
2062   --
2063   l_prv_absence_attendance_id NUMBER DEFAULT -1;
2064   --
2065   -- Stores a dummy value returned from cursor c_get_queued_event
2066   --
2067   l_dummy VARCHAR2(1);
2068   --
2069   -- l_action_taken used to store the type of event that has occurred
2070   -- to be stored in the archive table.
2071   --
2072   l_action_taken VARCHAR2(10) DEFAULT NULL;
2073   --
2074 BEGIN
2075   --
2076   dbg('In procedure Update_Absence_Dim_Evnt_Q ...');
2077   --
2078   dbg('Updating the Absence Dimension Queue for '||p_assignment_id||'.');
2079   --
2080   -- Loop through sub event group and identify the unique
2081   -- absence_attendance_ids that have had an event.
2082   --
2083   FOR i in 1..p_sub_evt_grp_tbl.COUNT
2084   LOOP
2085     --
2086     -- Holds the surrogate key value for the event that has occurred
2087     -- for absence eevents this will be the absence_attendance_id
2088     --
2089     IF l_prv_absence_attendance_id <>
2090        p_sub_evt_grp_tbl(i).surrogate_key
2091     THEN
2092       --
2093       dbg('Found event for absence_attendance_id '||
2094           p_sub_evt_grp_tbl(i).surrogate_key);
2095       --
2096       -- Check if there is already an event for this absence_attendance_id
2097       -- in the queue.
2098       --
2099       OPEN c_get_queued_event(p_sub_evt_grp_tbl(i).surrogate_key);
2100       FETCH c_get_queued_event INTO l_dummy;
2101 
2102       --
2103       -- If no record in the event queue is found for the absence_attendance_id
2104       -- then insert it into the queue
2105       --
2106       IF c_get_queued_event%NOTFOUND OR c_get_queued_event%NOTFOUND IS NULL
2107       THEN
2108         --
2109         dbg('No record  for assignment '||p_assignment_id||' exists, so INSERT.');
2110         --
2111         INSERT INTO hri_eq_utl_absnc_dim
2112         (
2113          absence_attendance_id
2114         )
2115         VALUES
2116         (
2117          p_sub_evt_grp_tbl(i).surrogate_key
2118         );
2119         --
2120         l_action_taken := 'INSERTED';
2121         --
2122       --
2123       -- IF a record already exists for the absence
2124       --
2125       ELSE
2126         --
2127         dbg('Record already exists.');
2128         --        --
2129         l_action_taken := 'NONE';
2130         --
2131       END IF;
2132       --
2133       -- Close Curosr c_get_queued_event
2134       --
2135       CLOSE c_get_queued_event;
2136       --
2137       -- Update the hri_archive_events table with details of what we have
2138       -- done for the identified event.
2139       --
2140       IF g_enable_archive_flag = 'Y' THEN
2141         --
2142         -- Instead of assignment_id pass in absence_attendance_id
2143         --
2144         Update_archive_record
2145           (
2146            p_assignment_id     => p_sub_evt_grp_tbl(i).surrogate_key
2147           ,p_change_date       => NULL
2148           ,p_event_queue_table => 'HRI_EQ_UTL_ABSNC_DIM '
2149           ,p_action_taken      => l_action_taken
2150           ,p_capture_from_date => p_start_date
2151           );
2152         --
2153       END IF;
2154       --
2155       -- Set the value of the value for l_prv_absence_attendance_id
2156       -- to the current absence_attendance_id so that we can see
2157       -- if it has changed in the next loop.
2158       --
2159       l_prv_absence_attendance_id := p_sub_evt_grp_tbl(i).surrogate_key;
2160       --
2161       -- Following IF statement is for debug purposes only.
2162       --
2163       IF g_debug_flag = 'Y'
2164       THEN
2165         --
2166         dbg('Datetracked_event: '||p_sub_evt_grp_tbl(i).datetracked_event
2167           ||', Change_mode: '||p_sub_evt_grp_tbl(i).change_mode
2168           ||', Effective_date: '||p_sub_evt_grp_tbl(i).effective_date
2169           ||', dated_table_id: '||TO_CHAR(p_sub_evt_grp_tbl(i).dated_table_id)
2170           ||', surrogate_key: '||TO_CHAR(p_sub_evt_grp_tbl(i).surrogate_key)
2171           ||', column_name: '||TO_CHAR(p_sub_evt_grp_tbl(i).column_name)
2172           ||', old_value: '||p_sub_evt_grp_tbl(i).old_value
2173           ||', new_value: '||p_sub_evt_grp_tbl(i).new_value
2174           ||', change_values: '||p_sub_evt_grp_tbl(i).change_values
2175           );
2176         --
2177       END IF; -- g_debug_flag = 'Y'
2178       --
2179     END IF; -- If the absence_attendance_id has changed.
2180     --
2181   END LOOP;
2182   --
2183 END Update_Absence_Dim_Evnt_Q;
2184 --
2185 -- ----------------------------------------------------------------------------
2186 -- 5.1.3 (Process_assgnmnt_evnt_changes)
2187 -- Get Earliest Assignment Events Fact Event For Assignment
2188 -- ============================================================================
2189 -- This procedure calls the procedure Find_sub_event_group_events, passing
2190 -- in the master event group PLSQL table (containing all the interpreted
2191 -- events that have occurred since p_start_date for the assignment), to
2192 -- identify all of the events that have occurred that are relevent to
2193 -- the assignment events fact event queue.
2194 --
2195 PROCEDURE Process_assgnmnt_evnt_changes
2196   (p_assignment_id IN NUMBER
2197   ,p_start_date IN DATE
2198   ,p_master_events_table
2199     IN OUT nocopy pay_interpreter_pkg.t_detailed_output_table_type)
2200 IS
2201   --
2202   -- l_min_date is used to store the earliest effective_date date found
2203   -- by the procedure Find_sub_event_group_events for the sub event group
2204   --
2205   l_min_date DATE;
2206   --
2207 BEGIN
2208   --
2209   dbg('Executing Process_assgnmnt_evnt_changes ....');
2210   --
2211   -- 3658545 Populate assignment events queue only if g_col_asg_events_eq = 'Y'
2212   --
2213   IF g_col_asg_events_eq = 'N' THEN
2214     --
2215     dbg('Profile HRI:Populate Assignment Events Queue not enabled, skip populating '||
2216         'assignment events queue');
2217     return;
2218     --
2219   END IF;
2220   --
2221   Find_sub_event_group_events
2222     (
2223      p_assignment_id => p_assignment_id
2224     ,p_start_date => p_start_date
2225     ,p_sub_event_grp_id => g_assgnmnt_evnt_event_grp_id
2226     ,p_comment_text => 'Assignment Events'
2227     ,p_master_events_table => p_master_events_table
2228     ,p_event_date => l_min_date
2229     );
2230   --
2231   -- If l_min_date is NOT NULL this means that Find_sub_event_group_events
2232   -- has found an event for the sub event group, and assignment id on that
2233   -- date. We therefore need to see if it is necessary to update the relevant
2234   -- event queues with this information.
2235   --
2236   IF l_min_date IS NOT NULL
2237   THEN
2238     --
2239     -- Insert a record in the event queue for the earliest change for the
2240     -- assignment for the sub event group.
2241     --
2242     Update_Asgn_Evnt_Fct_Evnt_Q
2243       (
2244        p_assignment_id => p_assignment_id
2245       ,p_change_date   => l_min_date
2246       ,p_start_date    => p_start_date
2247       );
2248     --
2249   END IF;
2250   --
2251 END Process_assgnmnt_evnt_changes;
2252 --
2253 -- ----------------------------------------------------------------------------
2254 -- 5.1.4 (Process_absence_evnt_changes)
2255 -- Get Absence Events For Assignment
2256 -- ============================================================================
2257 -- This procedure calls the procedure Find_sub_event_group_events, passing
2258 -- in the master event group PLSQL table (containing all the interpreted
2259 -- events that have occurred since p_start_date for the assignment), to
2260 -- identify any events that have occurred that are relevent to
2261 -- the absence dimension event queue.
2262 --
2263 PROCEDURE Process_absence_dim_changes
2264   (p_assignment_id IN NUMBER
2265   ,p_start_date IN DATE
2266   ,p_master_events_table
2267     IN OUT nocopy pay_interpreter_pkg.t_detailed_output_table_type)
2268 IS
2269   --
2270   -- l_min_date is used to store the earliest effective_date date found
2271   -- by the procedure Find_sub_event_group_events for the sub event group
2272   --
2273   l_min_date DATE;
2274   --
2275   -- The following PLSQL table will hold the sub events returned by
2276   -- Find_sub_event_group_events.
2277   --
2278   l_sub_evt_grp_tbl pay_interpreter_pkg.t_detailed_output_table_type;
2279   --
2280 BEGIN
2281   --
2282   dbg('Executing Process_absence_evnt_changes ....');
2283   --
2284   -- 3658545 Populate assignment events queue only if g_col_asg_events_eq = 'Y'
2285   --
2286   IF g_col_absence_events_eq = 'N' THEN
2287     --
2288     dbg('Profile HRI:Absence Dimension Queue not enabled, skip populating '||
2289         'absence events queue');
2290     return;
2291     --
2292   END IF;
2293   --
2294   Find_sub_event_group_events
2295     (
2296      p_assignment_id => p_assignment_id
2297     ,p_start_date => p_start_date
2298     ,p_sub_event_grp_id => g_absence_dim_event_grp_id
2299     ,p_comment_text => 'Absences'
2300     ,p_master_events_table => p_master_events_table
2301     ,p_event_date => l_min_date
2302     ,p_sub_evt_grp_tbl => l_sub_evt_grp_tbl
2303     ,p_event_capture_mode => 'S' -- Tells process just tell if there has been
2304                                  -- an event within the period. D not care
2305                                  -- when this was, as absences are not date
2306                                  -- tracked.
2307     );
2308   --
2309   -- If l_min_date is NOT NULL this means that Find_sub_event_group_events
2310   -- has found an event for the sub event group, and assignment id on that
2311   -- date. We therefore need to see if it is necessary to update the relevant
2312   -- event queues with this information.
2313   --
2314   IF l_min_date IS NOT NULL
2315   THEN
2316     --
2317     dbg('Absence Events have been found ....');
2318     --
2319     -- Insert a record in the event queue for the earliest change for the
2320     -- assignment for the sub event group.
2321     --
2322     dbg('Calling Update_Absence_Dim_Evnt_Q ....');
2323     --
2324     Update_Absence_Dim_Evnt_Q
2325       (
2326        p_assignment_id => p_assignment_id
2327       ,p_start_date    => p_start_date
2328       ,p_sub_evt_grp_tbl => l_sub_evt_grp_tbl
2329       );
2330     --
2331   ELSE
2332     --
2333     dbg('Absence Events have NOT been found ....');
2334     --
2335   END IF;
2336   --
2337 END Process_absence_dim_changes;
2338 --
2339 -- ----------------------------------------------------------------------------
2340 -- Capture_Events
2341 -- Main Entry point for capturing events for a given assignment
2342 -- ============================================================================
2343 -- This procedure is the main contoling processing of a given
2344 -- assignment. It is called by process_range, the entry point for handling a
2345 -- single assignment called by the child multithreading process.
2346 --
2347 PROCEDURE capture_events
2348   (p_assignment_id NUMBER
2349   ,p_start_date DATE)
2350 IS
2351   --
2352   l_master_events_table pay_interpreter_pkg.t_detailed_output_table_type;
2353   --
2354 BEGIN
2355   --
2356   interpret_all_asgnmnt_changes(p_assignment_id
2357                                ,p_start_date
2358                                ,l_master_events_table);
2359   --
2360   Process_supervisor_events(p_assignment_id
2361                            ,p_start_date
2362                            ,l_master_events_table);
2363   --
2364   Process_assgnmnt_evnt_changes(p_assignment_id
2365                                 ,p_start_date
2366                                 ,l_master_events_table);
2367   --
2368   Process_absence_dim_changes(p_assignment_id
2369                               ,p_start_date
2370                               ,l_master_events_table);
2371   --
2372 END;
2373 --
2374 -- ----------------------------------------------------------------------------
2375 -- run_for_bg
2376 -- Test procedure to run for all assignments consecutively
2377 -- ============================================================================
2378 --
2379 PROCEDURE run_for_bg(
2380    p_business_group_id  IN NUMBER
2381   ,p_collect_from       IN DATE
2382   )
2383 IS
2384   --
2385   CURSOR asg_csr IS
2386   SELECT DISTINCT assignment_id
2387   FROM per_all_assignments_f
2388   WHERE assignment_type = 'E'
2389   AND business_group_id = NVL(p_business_group_id, business_group_id)
2390   AND (effective_start_date >= p_collect_from
2391     OR effective_end_date >= p_collect_from);
2392   --
2393 BEGIN
2394   --
2395   FOR asg_rec IN asg_csr LOOP
2396     --
2397     capture_events(
2398       p_assignment_id  => asg_rec.assignment_id
2399      ,p_start_date => SYSDATE) ;
2400     --
2401   END LOOP;
2402   --
2403   COMMIT;
2404   --
2405 END run_for_bg;
2406 --
2407 -- ----------------------------------------------------------------------------
2408 -- run_for_asg
2409 -- Debugging procedure to run for a single assignment
2410 -- ============================================================================
2411 --
2412 PROCEDURE run_for_asg(
2413                       p_assignment_id     IN NUMBER
2414                      ,p_capture_from_date IN DATE
2415                      )
2416 IS
2417   --
2418 BEGIN
2419   --
2420   g_master_event_group_id      := get_event_group_id('HRI_ASG_MASTER_GROUP');
2421   g_sprvsr_change_event_grp_id := get_event_group_id('HRI_SUPERVISOR_EVENTS');
2422   g_assgnmnt_evnt_event_grp_id := get_event_group_id('HRI_ASG_EVNTS_FCT');
2423   g_absence_dim_event_grp_id   := get_event_group_id('HRI_ABSENCE_EVENTS');
2424   --
2425   g_prd_of_srvc_table_id    := get_dated_table_id('PER_PERIODS_OF_SERVICE');
2426   g_appraisal_table_id      := get_dated_table_id('PER_APPRAISALS');
2427   g_perf_review_table_id    := get_dated_table_id('PER_PERFORMANCE_REVIEWS');
2428   g_asg_table_id            := get_dated_table_id('PER_ALL_ASSIGNMENTS_F');
2429   g_person_type_table_id    := get_dated_table_id('PER_PERSON_TYPE_USAGES_F');
2430   --
2431   g_absence_attendance_table_id := get_dated_table_id('PER_ABSENCE_ATTENDANCES');
2432   --
2433   capture_events
2434     (
2435      p_assignment_id  => p_assignment_id
2436     ,p_start_date     => p_capture_from_date
2437     );
2438   --
2439   -- Commit is okay here as we are not executing the PYUGEN portion of this
2440   -- package.
2441   --
2442   COMMIT;
2443   --
2444 END run_for_asg;
2445 --
2446 -- Decides whether to full refresh
2447 --
2448 FUNCTION get_full_refresh_value RETURN VARCHAR2
2449   IS
2450   --
2451   -- Indicators showing whether particular tables should be fully or
2452   -- incrementally refreshed.
2453   --
2454   l_suph_full_refresh     VARCHAR2(30);
2455   l_asgn_full_refresh     VARCHAR2(30);
2456   l_spst_full_refresh     VARCHAR2(30);
2457   l_absc_full_refresh     VARCHAR2(30);
2458   --
2459 BEGIN
2460   --
2461   -- Get full refresh value for each of dependent tables
2462   --
2463   dbg('Getting full refresh value for each of dependent tables ...');
2464   --
2465   l_suph_full_refresh := hri_oltp_conc_param.get_parameter_value
2466                           (p_parameter_name     => 'FULL_REFRESH',
2467                            p_process_table_name => 'HRI_CS_SUPH');
2468   l_asgn_full_refresh := hri_oltp_conc_param.get_parameter_value
2469                           (p_parameter_name     => 'FULL_REFRESH',
2470                            p_process_table_name => 'HRI_MB_ASGN_EVENTS_CT');
2471   l_spst_full_refresh := hri_oltp_conc_param.get_parameter_value
2472                           (p_parameter_name     => 'FULL_REFRESH',
2473                            p_process_table_name => 'HRI_CL_WKR_SUP_STATUS_CT');
2474   l_absc_full_refresh := hri_oltp_conc_param.get_parameter_value
2475                           (p_parameter_name     => 'FULL_REFRESH',
2476                            p_process_table_name => 'HRI_CS_ABSENCE_CT');
2477   --
2478   -- Only do the following if you are in debug mode for information purposes
2479   --
2480   IF g_debug_flag = 'Y'
2481   THEN
2482     --
2483     msg('l_suph_full_refresh: '||l_suph_full_refresh);
2484     msg('l_asgn_full_refresh: '||l_asgn_full_refresh);
2485     msg('l_spst_full_refresh: '||l_spst_full_refresh);
2486     msg('l_absc_full_refresh: '||l_absc_full_refresh);
2487     --
2488   END IF;
2489   --
2490   -- If any of these processes is incremental then
2491   -- event capture must be incremental
2492   --
2493   IF (l_suph_full_refresh = 'N' OR
2494       l_asgn_full_refresh = 'N' OR
2495       l_spst_full_refresh = 'N' OR
2496       l_absc_full_refresh = 'N')
2497   THEN
2498     --
2499     dbg('Return ''N'' to indicate incremental refresh should take place.');
2500     --
2501     RETURN 'N';
2502     --
2503   ELSE
2504     --
2505     dbg('Return ''Y'' to indicate full refresh should take place.');
2506     --
2507     RETURN 'Y';
2508     --
2509   END IF;
2510   --
2511 END get_full_refresh_value;
2512 --
2513 --
2514 -- -----------------------------------------------------------------------------
2515 --
2516 -- -----------------------------------------------------------------------------
2517 -- -----------------------------------------------------------------------------
2518 -- -----------------------------------------------------------------------------
2519 --                         Multithreading Calls                               --
2520 -- -----------------------------------------------------------------------------
2521 -- The Multithreading Utility Provides the Framework for processing collection
2522 -- using multiple threads. The sequence of operation performed by the utility are
2523 --   a) Invoke the PRE_PROCESS procedure to initialize the global variables and
2524 --      return a SQL based on which the processing ranges will be created.
2525 --      In case of Foundation HR environment or when the process is being run in
2526 --      full refresh mode the process will not return any SQL. Therefore the
2527 --      mulithtreading utility will not invoke the PROCESS_RANGE and POST_PROCESS
2528 --      process.
2529 --   b) Invoke the PROCESS_RANGE procedure to process the assignments in the range
2530 --      This part is done by multiple threads
2531 --   c) Invoke the POST_PROCESS procedure to perform the post processing tasks
2532 -- -----------------------------------------------------------------------------
2533 -- -----------------------------------------------------------------------------
2534 --
2535 --
2536 -- ----------------------------------------------------------------------------
2537 -- SET_PARAMETERS
2538 -- sets up parameters required for the events capture processes
2539 -- Sets up global list of parameters, this is the way that parameters need
2540 -- to be set up for collecting incremental events by HRI multithreading utility
2541 -- ----------------------------------------------------------------------------
2542 --
2543 PROCEDURE set_parameters( p_mthd_action_id  IN NUMBER,
2544                           p_called_from     IN VARCHAR2 default null)
2545 IS
2546   --
2547   l_bis_start_date   DATE;
2548   l_bis_end_date     DATE; -- Dummy variable return value ignored
2549   l_period_from      DATE; -- Dummy variable return value ignored
2550   l_period_to        DATE; -- Dummy variable return value ignored
2551   l_message          fnd_new_messages.message_text%TYPE;
2552   --
2553 BEGIN
2554   --
2555   dbg('Setting parameters ...');
2556   --
2557   -- If parameters haven't already been set, then set them
2558   --
2559   IF p_called_from = 'PRE_PROCESS'
2560   THEN
2561     --
2562     dbg('Parameters haven''t been set yet, so set them ...');
2563     --
2564     -- Populate the multithread action arrays
2565     --
2566     g_mthd_action_array   := hri_opl_multi_thread.get_mthd_action_array(p_mthd_action_id);
2567     --
2568     -- Decide whether to full refresh
2569     --
2570     g_full_refresh := get_full_refresh_value;
2571     dbg('Full refresh:   ' || g_full_refresh);
2572     --
2573     -- Get the profile value which determines whether Archiving has been turned on
2574     --
2575     g_enable_archive_flag := NVL(fnd_profile.value('HRI_SET_EVENTS_ARCHIVE'),'N');
2576     --
2577     -- 3658545 The Events Collection process should populate the events queues
2578     -- based on the following profile
2579     --
2580     -- a) HRI:Populate Assignment Events Queue
2581     -- b) HRI:Populate Supervisor Hierarchy Events Queue
2582     -- c) HRI:Populate Supervisor Status History Events Queue
2583     --
2584     -- The process will only populate the queues for which the profile has been enabled.
2585     -- However, as the Supervisor Status History collection is dependent on assignment events
2586     -- fact table, even if HRI:Populate Assignment Events Queue profile has not been enabled
2587     -- the Assignment Events Queue will be populated.
2588     --
2589     --
2590     -- Get the profile value to determine which events queue is to be populated
2591     --
2592     g_col_asg_events_eq   := NVL(fnd_profile.value('HRI_COL_ASG_EVENTS_EQ'),'Y');
2593     g_col_sup_hrchy_eq    := NVL(fnd_profile.value('HRI_COL_SUP_HRCHY_EQ'),'Y');
2594     g_col_sup_hstry_eq    := NVL(fnd_profile.value('HRI_COL_SUP_STATUS_EQ'),'Y');
2595     g_col_absence_events_eq := NVL(fnd_profile.value('HRI_COL_ABSNCE_DIM_EQ'),'Y');
2596     --
2597     IF g_col_asg_events_eq = 'N' AND
2598        g_col_sup_hstry_eq = 'N'
2599     THEN
2600       --
2601       -- msg('Profile HRI:Populate Assignment Events Queue is not enabled.');
2602       -- msg('  Assignment Events queue will not be populated');
2603       --
2604       -- Bug 4105868: Collection Diagnostics
2605       --
2606       fnd_message.set_name('HRI', 'HRI_407162_PRF_ASGEQ_IMPCT');
2607       fnd_message.set_token('PROFILE_NAME', 'HRI:Populate Assignment Events Queue');
2608       --
2609       l_message := fnd_message.get;
2610       --
2611       hri_bpl_conc_log.log_process_info
2612               (p_package_name  => 'HRI_OPL_EVENT_CAPTURE'
2613               ,p_msg_type      => 'WARNING'
2614               ,p_note          => l_message
2615               ,p_msg_group     => 'EVT_CPTR'
2616 	      ,p_msg_sub_group => 'SET_PARAMETERS'
2617               ,p_sql_err_code  => SQLCODE);
2618       --
2619       msg(l_message);
2620       --
2621     END IF;
2622     --
2623     IF g_col_sup_hrchy_eq = 'N' THEN
2624       --
2625       -- msg('Profile HRI:Populate Supervisor Hierarchy Events Queue is not enabled.');
2626       -- msg('  Supervisor Hierarch Events queue will not be populated');
2627       --
2628       -- Bug 4105868: Collection Diagnostics
2629       --
2630       fnd_message.set_name('HRI', 'HRI_407163_PRF_SUPH_EQ_IMPCT');
2631       fnd_message.set_token('PROFILE_NAME', 'HRI:Populate Supervisor Hierarchy Events Queue');
2632       --
2633       l_message := fnd_message.get;
2634       --
2635       hri_bpl_conc_log.log_process_info
2636               (p_package_name  => 'HRI_OPL_EVENT_CAPTURE'
2637               ,p_msg_type      => 'WARNING'
2638               ,p_note          => l_message
2639               ,p_msg_group     => 'EVT_CPTR'
2640               ,p_msg_sub_group => 'SET_PARAMETERS'
2641               ,p_sql_err_code  => SQLCODE);
2642       --
2643       msg(l_message);
2644       --
2645     END IF;
2646     --
2647     dbg('Start collection diagnostics ...');
2648     --
2649     IF g_col_sup_hstry_eq = 'N' THEN
2650       --
2651       -- msg('Profile HRI:Populate Supervisor Status History Events Queue is not enabled.');
2652       -- msg('  Supervisor Status History Events queue will not be populated');
2653       --
2654       -- Bug 4105868: Collection Diagnostics
2655       --
2656       fnd_message.set_name('HRI', 'HRI_407164_PRF_SUPST_EQ_IMPCT');
2657       fnd_message.set_token('PROFILE_NAME', 'HRI:Populate Supervisor Status History Events Queue');
2658       --
2659       l_message := fnd_message.get;
2660       --
2661       hri_bpl_conc_log.log_process_info
2662               (p_package_name  => 'HRI_OPL_EVENT_CAPTURE'
2663               ,p_msg_type      => 'WARNING'
2664               ,p_note          => l_message
2665               ,p_msg_group     => 'EVT_CPTR'
2666               ,p_msg_sub_group => 'SET_PARAMETERS'
2667               ,p_sql_err_code  => SQLCODE);
2668       --
2669       msg(l_message);
2670       --
2671     ELSIF g_col_sup_hstry_eq  = 'Y' AND
2672           g_col_asg_events_eq = 'N'
2673     THEN
2674       --
2675       -- msg('Profile HRI:Populate Supervisor Status History Events Queue is enabled.');
2676       -- msg('  Assignment Events queue will also be populated');
2677       --
2678       -- Bug 4105868: Collection Diagnostics
2679       --
2680       fnd_message.set_name('HRI', 'HRI_407293_PRF_SUPST_ENBLD');
2681       --
2682       l_message := fnd_message.get;
2683       --
2684       hri_bpl_conc_log.log_process_info
2685               (p_package_name  => 'HRI_OPL_EVENT_CAPTURE'
2686               ,p_msg_type      => 'WARNING'
2687               ,p_note          => l_message
2688               ,p_msg_group     => 'EVT_CPTR'
2689               ,p_msg_sub_group => 'SET_PARAMETERS'
2690               ,p_sql_err_code  => SQLCODE);
2691       --
2692       msg(l_message);
2693       --
2694     END IF;
2695     --
2696     IF g_col_absence_events_eq = 'N' THEN
2697       --
2698       -- msg('Profile HRI:Populate Absence Dimension Queue is not enabled.');
2699       -- msg('  Absence Events queue will not be populated');
2700       --
2701       fnd_message.set_name('HRI', 'HRI_407200_PRF_ABS_EQ_IMPCT');
2702       fnd_message.set_token('PROFILE_NAME', 'HRI:Populate Absence Dimension Queue');
2703       --
2704       l_message := fnd_message.get;
2705       --
2706       hri_bpl_conc_log.log_process_info
2707               (p_package_name  => 'HRI_OPL_EVENT_CAPTURE'
2708               ,p_msg_type      => 'WARNING'
2709               ,p_note          => l_message
2710               ,p_msg_group     => 'EVT_CPTR'
2711               ,p_msg_sub_group => 'SET_PARAMETERS'
2712               ,p_sql_err_code  => SQLCODE);
2713       --
2714       msg(l_message);
2715       --
2716     END IF;
2717     --
2718     dbg('Finished collection diagnostics ...');
2719     --
2720     IF g_col_sup_hstry_eq = 'Y' THEN
2721       --
2722       g_col_asg_events_eq := 'Y';
2723       --
2724     END IF;
2725     --
2726     -- If only Supervisor Hierachy events needs to be populated then set the master group
2727     -- as HRI_SUPERVISOR_EVENTS
2728     --
2729     dbg('Start setting up event groups ...');
2730     --
2731     IF g_col_sup_hrchy_eq  = 'Y' AND
2732        g_col_asg_events_eq = 'N' AND
2733        g_col_sup_hstry_eq  = 'N' AND
2734        g_col_absence_events_eq = 'N'
2735     THEN
2736       --
2737       dbg('Only supervisor events being collected ...');
2738       --
2739       g_master_event_group_id  := get_event_group_id('HRI_SUPERVISOR_EVENTS');
2740       --
2741       g_sprvsr_change_event_grp_id := get_event_group_id('HRI_SUPERVISOR_EVENTS');
2742       --
2743     ELSIF g_col_asg_events_eq = 'Y' AND
2744        g_col_sup_hrchy_eq  = 'N' AND
2745        g_col_sup_hstry_eq  = 'N' AND
2746        g_col_absence_events_eq = 'N'
2747     THEN
2748       --
2749       dbg('Only assignment events being collected ...');
2750       --
2751       g_master_event_group_id      := get_event_group_id('HRI_ASG_EVNTS_FCT');
2752       --
2753       g_assgnmnt_evnt_event_grp_id := get_event_group_id('HRI_ASG_EVNTS_FCT');
2754       --
2755     ELSIF g_col_absence_events_eq = 'Y' AND
2756        g_col_asg_events_eq = 'N' AND
2757        g_col_sup_hrchy_eq  = 'N' AND
2758        g_col_sup_hstry_eq  = 'N'
2759     THEN
2760       --
2761       dbg('Only absence events being collected ...');
2762       --
2763       g_master_event_group_id    := get_event_group_id('HRI_ABSENCE_EVENTS');
2764       --
2765       g_absence_dim_event_grp_id := get_event_group_id('HRI_ABSENCE_EVENTS');
2766       --
2767     ELSE
2768       --
2769       dbg('Do normal event group setup ...');
2770       --
2771       g_master_event_group_id      := get_event_group_id('HRI_ASG_MASTER_GROUP');
2772       --
2773       g_sprvsr_change_event_grp_id := get_event_group_id('HRI_SUPERVISOR_EVENTS');
2774       --
2775       g_assgnmnt_evnt_event_grp_id := get_event_group_id('HRI_ASG_EVNTS_FCT');
2776       --
2777       g_absence_dim_event_grp_id   := get_event_group_id('HRI_ABSENCE_EVENTS');
2778       --
2779       dbg('Finished doing normal event group setup ...');
2780       --
2781     END IF;
2782     --
2783     dbg('Finished setting up event groups ...');
2784     --
2785     -- Get the dates of the last refresh of this program
2786     --
2787     dbg('Get the dates of the last refresh of this program ...');
2788     --
2789     bis_collection_utilities.get_last_refresh_dates(
2790             c_object_name,
2791             l_bis_start_date,
2792             l_bis_end_date,
2793             l_period_from,
2794             l_period_to);
2795     --
2796     -- If the Events capture process has never been run before then the
2797     -- dates returned by bis_collection_utilities will be NULL, so we
2798     -- need to switch to full refresh mode.
2799     --
2800     dbg('Capture From Date: '||to_char(l_bis_start_date,'MM/DD/YYYY HH24:MI:SS')||'.');
2801     --
2802     IF l_bis_start_date  IS NULL
2803        OR
2804        l_period_to IS NULL
2805     THEN
2806       --
2807       -- Set indicator to show that full refresh has not been run,
2808       -- and so we need fail cleanly. This will be cause the HRI
2809       -- Multithreading process to end cleanly.
2810       --
2811       dbg('Setting indocators to show ull refresh has not been run.');
2812       --
2813       g_full_refresh_not_run := TRUE;
2814       g_full_refresh := 'Y';
2815       --
2816     ELSE
2817       --
2818       -- The start of this refresh should be the time at which the last one
2819       -- started running so that any changes made during the last run are
2820       -- picked up by this one. The end should be now
2821       --
2822       -- 3696594 changed the capture from date to be start_date of the
2823       -- last process
2824       --
2825       dbg('Setting g_capture_from_date to start date of last run.');
2826       --
2827       g_capture_from_date := l_bis_start_date;
2828       --
2829     END IF;
2830     --
2831     -- Get the dated table id of the non data tracked tables, this is used for
2832     -- determining the change to effective dates of non datetracked tables
2833     --
2834     dbg(' Get the dated table id of the non data tracked tables ...');
2835     --
2836     g_prd_of_srvc_table_id    := get_dated_table_id('PER_PERIODS_OF_SERVICE');
2837     g_appraisal_table_id      := get_dated_table_id('PER_APPRAISALS');
2838     g_perf_review_table_id    := get_dated_table_id('PER_PERFORMANCE_REVIEWS');
2839     g_asg_table_id            := get_dated_table_id('PER_ALL_ASSIGNMENTS_F');
2840     g_person_type_table_id    := get_dated_table_id('PER_PERSON_TYPE_USAGES_F');
2841     --
2842     -- 3906029 The event date to be populated in the supervisor hierarchy
2843     -- events queue should not be lesser than the last full refresh date
2844     -- or the minimum date in the hierarchy
2845     --
2846     g_min_suph_date := get_min_suph_date;
2847     --
2848     dbg('Store the parameter values for use by slave processes...');
2849     --
2850     UPDATE hri_adm_mthd_actions
2851     SET    full_refresh_flag = g_full_refresh,
2852            collect_from_date =  g_capture_from_date,
2853            attribute1  =  g_master_event_group_id,
2854            attribute2  =  g_assgnmnt_evnt_event_grp_id,
2855            attribute3  =  g_sprvsr_change_event_grp_id,
2856            attribute4  =  g_col_asg_events_eq,
2857            attribute5  =  g_col_sup_hrchy_eq,
2858            attribute6  =  g_col_sup_hstry_eq,
2859            attribute7  =  g_enable_archive_flag,
2860            attribute8  =  g_min_suph_date,
2861            attribute9  =  g_prd_of_srvc_table_id,
2862            attribute10 =  g_appraisal_table_id,
2863            attribute11 =  g_perf_review_table_id,
2864            attribute12 =  g_asg_table_id,
2865            attribute13 =  g_person_type_table_id          -- Dated table id of PER_PERSON_TYPE_USAGES_F
2866     WHERE  mthd_action_id = p_mthd_action_id;
2867     --
2868     dbg('Completed storing the parameter values for use by the slave processes ...');
2869     --
2870     COMMIT;
2871   --
2872   -- Parameters have already been set so don't need to be set again.
2873   --
2874   ELSIF (g_capture_from_date IS NULL) THEN
2875     --
2876     dbg('Set parameters has been called from a slave process. Retrieve '||
2877         'the parameter values.');
2878     --
2879     -- Populate the multithread action arrays
2880     --
2881     g_mthd_action_array := hri_opl_multi_thread.get_mthd_action_array(p_mthd_action_id);
2882     g_full_refresh      := 'N';
2883     --
2884     -- Populate the global variables
2885     --
2886     g_capture_from_date           := g_mthd_action_array.collect_from_date;
2887     g_master_event_group_id       := g_mthd_action_array.attribute1;
2888     g_assgnmnt_evnt_event_grp_id  := g_mthd_action_array.attribute2;
2889     g_sprvsr_change_event_grp_id  := g_mthd_action_array.attribute3;
2890     g_col_asg_events_eq           := g_mthd_action_array.attribute4;
2891     g_col_sup_hrchy_eq            := g_mthd_action_array.attribute5;
2892     g_col_sup_hstry_eq            := g_mthd_action_array.attribute6;
2893     g_enable_archive_flag         := g_mthd_action_array.attribute7;
2894     g_min_suph_date               := g_mthd_action_array.attribute8;
2895     --
2896     -- ID of table on which HRI PEM triggers can be created
2897     --
2898     g_prd_of_srvc_table_id        := g_mthd_action_array.attribute9;
2899     g_appraisal_table_id          := g_mthd_action_array.attribute10;
2900     g_perf_review_table_id        := g_mthd_action_array.attribute11;
2901     g_asg_table_id                := g_mthd_action_array.attribute12;
2902     g_person_type_table_id        := g_mthd_action_array.attribute13;
2903     --
2904     dbg('Finished retrieving parameter values.');
2905     --
2906   END IF;
2907   --
2908 END set_parameters;
2909 --
2910 -- ----------------------------------------------------------------------------
2911 -- PRE_PROCESS
2912 -- This procedure includes all the logic required for performing the pre_process
2913 -- task of HRI multithreading utility.
2914 -- ----------------------------------------------------------------------------
2915 --
2916 PROCEDURE PRE_PROCESS(
2917 --
2918   p_mthd_action_id              IN             NUMBER,
2919   p_sqlstr                                 OUT NOCOPY VARCHAR2) IS
2920   --
2921   l_dummy1           VARCHAR2(2000);
2922   l_dummy2           VARCHAR2(2000);
2923   l_schema           VARCHAR2(400);
2924 --
2925 BEGIN
2926   --
2927   -- Set up the parameters
2928   --
2929   set_parameters( p_mthd_action_id  => p_mthd_action_id,
2930                   p_called_from     => 'PRE_PROCESS');
2931   --
2932   -- In case the process is running in a Foundation HR environment run
2933   -- the post_process to update the bis_refresh_log table and return without
2934   -- returning any SQL. The mulithreading utility will then not invoke the
2935   -- PROCESS_RANGES and POST_PROCESS calls
2936   --
2937   IF g_mthd_action_array.foundation_hr_flag = 'Y' THEN
2938     --
2939     -- This process is not supported in Shared HR mode, update the
2940     -- bis refresh log table and return. The multithreading utility
2941     -- does not do any processing if no SQL is returned
2942     --
2943     dbg('Foundation HR environment found');
2944     post_process (p_mthd_action_id => p_mthd_action_id);
2945     --
2946   ELSIF g_full_refresh = 'Y'
2947         OR g_full_refresh_not_run
2948   THEN
2949     --
2950     dbg('calling full refresh');
2951     --
2952     -- In case the process is running in full refresh mode, directly call the
2953     -- full_refresh procedure and return without returning any SQL. The mulithreading
2954     -- utility will then not invoke the PROCESS_RANGES and POST_PROCESS calls
2955     --
2956     full_refresh (p_refresh_to_date => NULL);
2957     --
2958   ELSIF (g_col_asg_events_eq = 'N' AND
2959          g_col_sup_hrchy_eq  = 'N' AND
2960          g_col_sup_hstry_eq  = 'N' AND
2961          g_col_absence_events_eq = 'N')
2962   THEN
2963     --
2964     -- The events queue profile have been set, so events are not to be collected.
2965     -- The multithreading utility does not do any processing if no SQL is returned
2966     --
2967     dbg('All the events queues profiles have been set to ''N''');
2968     post_process(p_mthd_action_id => p_mthd_action_id);
2969     --
2970   ELSE
2971     --
2972     -- The SELECT statement built up underneath populates the out parameter sqlstr
2973     -- which is used by the utility to generate the range of assignments to be
2974     -- processed.
2975     --
2976     -- This is the normal execution path when the process is run correctly
2977     -- after a full refresh.
2978     --
2979     -- Generate a SQL statement that SELECTs all of the DISTINCT assignments
2980     -- that have had events in the pay_process_events table, since the last
2981     -- incremental refresh.
2982     --
2983     -- 3703498 Added restriction so that only assignments with changes that are
2984     -- being tracked in the event group are processed
2985     --
2986     p_sqlstr :=
2987       'SELECT /*+ parallel(ppe , default, default) */ DISTINCT
2988              ppe.assignment_id object_id
2989        FROM  pay_process_events ppe
2990        WHERE ppe.creation_date
2991          BETWEEN to_date('''
2992            || to_char(g_capture_from_date, 'DD-MON-YYYY HH24:MI:SS')
2993                        || ''',''DD-MON-YYYY HH24:MI:SS'')
2994          AND     to_date('''
2995            || to_char(g_end_of_time, 'DD-MON-YYYY HH24:MI:SS')
2996                        || ''',''DD-MON-YYYY HH24:MI:SS'')
2997          AND    EXISTS (SELECT distinct event_update_id
2998                     FROM   pay_datetracked_events pde,
2999                            pay_event_updates      peu
3000                     WHERE  pde.event_group_id  = '||g_master_event_group_id||'
3001                     AND    pde.dated_table_id  = peu.dated_table_id
3002                     AND    ppe.event_update_id = peu.event_update_id )
3003        ORDER BY ppe.assignment_id';
3004     --
3005   END IF;
3006   --
3007   dbg(p_sqlstr);
3008   --
3009   -- 4357755
3010   -- The central refresh procedure should be initialized so that entries
3011   -- about the process are correctly inserted into the bis refresh log table
3012   -- This information is used to determine the start time of the next process.
3013   --
3014   hri_bpl_conc_log.record_process_start(c_object_name);
3015   --
3016   dbg('Exiting pre_process');
3017   --
3018 END PRE_PROCESS;
3019 --
3020 -- ----------------------------------------------------------------------------
3021 -- PROCESS_RANGE
3022 -- This procedure is dynamically the HRI multithreading utility child threads
3023 -- for processing the assignment ranges. The procedure manages the mulithreading
3024 -- ranges and invokes the overloaded process_range procedure to process the
3025 -- ranges.
3026 -- ----------------------------------------------------------------------------
3027 --
3028 PROCEDURE process_range(
3029    errbuf                          OUT NOCOPY VARCHAR2
3030   ,retcode                         OUT NOCOPY NUMBER
3031   ,p_mthd_action_id            IN             NUMBER
3032   ,p_mthd_range_id             IN             NUMBER
3033   ,p_start_object_id           IN             NUMBER
3034   ,p_end_object_id             IN             NUMBER)
3035 IS
3036   --
3037   l_error_step        NUMBER;
3038   l_mthd_range_id     NUMBER;
3039   l_start_object_id   NUMBER;
3040   l_end_object_id     NUMBER;
3041   --
3042 BEGIN
3043   --
3044   dbg('Inside process_range');
3045   --
3046   set_parameters(p_mthd_action_id);
3047   --
3048   dbg('processing range='||p_mthd_range_id);
3049   --
3050   process_range(p_start_object_id    => p_start_object_id
3051                 ,p_end_object_id     => p_end_object_id);
3052   --
3053   errbuf  := 'SUCCESS';
3054   retcode := 0;
3055   --
3056   dbg('Exiting process_range');
3057   --
3058 EXCEPTION
3059   when others then
3060     dbg('Error at step '||l_error_step );
3061     msg(sqlerrm);
3062     --
3063     errbuf := SQLERRM;
3064     retcode := SQLCODE;
3065     --
3066     raise;
3067    --
3068 END process_range;
3069 --
3070 -- ----------------------------------------------------------------------------
3071 -- PROCESS_RANGE
3072 -- This is an overloaded procedure which is invoked by PROCESS_RANGE above.
3073 -- For each of the assignment in the range, this procedure invokes the
3074 -- capture_events process to populate the events queues
3075 -- ----------------------------------------------------------------------------
3076 --
3077 PROCEDURE process_range(p_start_object_id   IN NUMBER
3078                        ,p_end_object_id     IN NUMBER )
3079 IS
3080   --
3081   -- Cursor to get the assignment_id for assignment action for full refresh
3082   --
3083   CURSOR c_asg_to_process IS
3084   SELECT DISTINCT ppe.assignment_id
3085   FROM   pay_process_events ppe
3086   WHERE  assignment_id between p_start_object_id and p_end_object_id
3087   AND    ppe.creation_date BETWEEN g_capture_from_date and g_end_of_time
3088   AND    EXISTS (SELECT distinct event_update_id
3089                  FROM   pay_datetracked_events pde,
3090                         pay_event_updates      peu
3091                  WHERE  pde.event_group_id  =  g_master_event_group_id
3092                  AND    pde.dated_table_id  =  peu.dated_table_id
3093                  AND    ppe.event_update_id =  peu.event_update_id );
3094   --
3095   -- Holds assignment from the cursor
3096   --
3097   l_assignment_id     NUMBER;
3098   l_change_date       DATE;
3099   l_error_step        NUMBER;
3100   --
3101 BEGIN
3102   --
3103   --
3104   --
3105   FOR l_asg_to_process in c_asg_to_process LOOP
3106     --
3107     -- For each of the
3108     --
3109     capture_events
3110        (p_assignment_id   => l_asg_to_process.assignment_id,
3111         p_start_date      => g_capture_from_date);
3112     --
3113   END LOOP;
3114   --
3115 END process_range;
3116 --
3117 -- ----------------------------------------------------------------------------
3118 -- POST_PROCESS
3119 -- This procedure is dynamically invoked by the HRI Multithreading utility.
3120 -- It finishes the processing by updating the BIS_REFRESH_LOG table
3121 -- ----------------------------------------------------------------------------
3122 --
3123 PROCEDURE post_process (p_mthd_action_id NUMBER) IS
3124   --
3125   l_dummy1           VARCHAR2(2000);
3126   l_dummy2           VARCHAR2(2000);
3127   l_schema           VARCHAR2(400);
3128   --
3129 --
3130 BEGIN
3131   --
3132   dbg('Inside post_process');
3133   --
3134   set_parameters(p_mthd_action_id);
3135   --
3136   -- 4765258
3137   -- Update the supervisor history events queue with the supervisors
3138   -- to process
3139   --
3140   -- Also check snapshot facts for new snapshot dates
3141   -- and populate EQs accordingly
3142   --
3143   IF (g_full_refresh = 'N') THEN
3144     hri_opl_sup_status_hst.find_changed_supervisors;
3145     check_for_new_snapshot_dates;
3146   END IF;
3147   --
3148   -- 4357755
3149   -- Insert the details of the run in the bis refresh log table. This info is
3150   -- read used to set the start date of next run
3151   --
3152   hri_bpl_conc_log.log_process_end
3153     (
3154      p_status         => TRUE
3155     ,p_period_from    => g_capture_from_date
3156     ,p_period_to      => SYSDATE
3157     );
3158   --
3159   dbg('Exiting post_process ....');
3160   --
3161   commit;
3162   --
3163 END post_process;
3164 --
3165 END HRI_OPL_EVENT_CAPTURE;