DBA Data[Home] [Help]

PACKAGE BODY: APPS.HXC_RPT_TC_AUDIT_TRAIL

Source


1 PACKAGE BODY HXC_RPT_TC_AUDIT_TRAIL AS
2 /* $Header: hxcrptaudittrail.pkb 120.10.12010000.7 2010/02/16 16:56:01 asrajago ship $ */
3 
4 g_debug BOOLEAN := hr_utility.debug_enabled;
5 
6 newline           VARCHAR2(1) :=
7 '
8 ';
9 
10 
11 
12 
13 -- AFTERPFORM
14 -- Calls the main action block and passes on the global parameters.
15 
16 FUNCTION afterpform
17 RETURN BOOLEAN
18 AS
19 
20 errbuf    VARCHAR2(100);
21 retcode   VARCHAR2(100);
22 
23 BEGIN
24 
25 
26     -- Public Procedure afterpform
27     -- Calls execute_audit_trail_reporting passing the global parameters
28     -- Is called from the HXCRPTAUD.xml, data definition file.
29 
30     execute_audit_trail_reporting  (errbuf          => errbuf,
31                                     retcode         => retcode,
32                                     p_date_from     => p_from_date ,
33                                     p_date_to       => p_to_date ,
34                                     p_data_regen    => p_dat_regen ,
35                                     p_record_save   => p_record_save,
36                                     p_org_id        => p_org_id ,
37                                     p_locn_id       => p_locn_id ,
38                                     p_payroll_id    => p_payroll_id ,
39                                     p_supervisor_id => p_supervisor_id ,
40                                     p_person_id     => p_person_id  );
41 
42     RETURN TRUE;
43 END;
44 
45 
46 -- AFTERREPORT
47 -- Clears HXC_RPT_TC_AUDIT after the reporting is done.
48 
49 FUNCTION afterreport
50 RETURN BOOLEAN
51 AS
52 
53 BEGIN
54 
55     -- Public Procedure afterreport
56     -- Truncates table HXC_RPT_TC_AUDIT after reporting is done.
57     -- Is called from HXCRPTAUD.xml file.
58 
59     --DELETE FROM hxc_rpt_tc_audit;
60     COMMIT;
61 
62     RETURN TRUE;
63 END;
64 
65 FUNCTION beforereport
66 RETURN BOOLEAN
67 AS
68 
69 BEGIN
70     RETURN TRUE;
71 END;
72 
73 
74 -- TRANSLATE_PARAMETERS
75 -- Translates all the ids that are provided as parameters to the names for
76 -- display in the report.
77 
78 PROCEDURE translate_parameters
79 AS
80 
81 BEGIN
82 
83     -- Public Procedure translate_parameters
84     -- Browse thru all the parameters, to check if they are NULL.
85     -- If anything is not null, get the relevant names from corresponding
86     --     tables.
87     -- Convert the from,to,sysdate, data_regen and record_save flags
88     -- anyway, because you need them always.
89 
90 
91 
92     IF g_debug
93     THEN
94        hr_utility.trace('translate_parameters');
95     END IF;
96 
97     lp_from_date := to_char(fnd_date.canonical_to_date(p_from_date),'dd-MON-yyyy');
98     lp_to_date := to_char(fnd_date.canonical_to_date(p_to_date),'dd-MON-yyyy');
99 
100     IF p_record_save = 'Y'
101     THEN
102        lp_record_save := 'Yes';
103     ELSE
104        lp_record_save := 'No';
105     END IF;
106 
107     IF P_DAT_REGEN = 'Y'
108     THEN
109        lp_dat_regen := 'Yes';
110     ELSE
111        lp_dat_regen := 'No';
112     END IF;
113 
114 
115     IF (p_org_id IS NOT NULL)
116     THEN
117        SELECT name
118          INTO lp_org
119          FROM hr_all_organization_units_tl
120         WHERE organization_id = p_org_id
121           AND language = USERENV('LANG');
122 
123     END IF;
124 
125     IF (p_locn_id IS NOT NULL)
126     THEN
127        SELECT location_code
128          INTO lp_location
129          FROM hr_locations_all_tl
130         WHERE location_id = p_locn_id
131           AND language = USERENV('LANG');
132 
133     END IF;
134 
135     IF (p_payroll_id IS NOT NULL)
136     THEN
137        SELECT payroll_name
138          INTO lp_payroll
139          FROM pay_all_payrolls_f
140         WHERE payroll_id = p_payroll_id
141           AND fnd_date.canonical_TO_DATE(p_from_date) BETWEEN effective_start_date
142                                                           AND effective_END_date;
143 
144     END IF;
145 
146     IF (p_supervisor_id IS NOT NULL)
147     THEN
148        SELECT full_name
149          INTO lp_supervisor
150          FROM per_all_people_f
151         WHERE person_id = p_supervisor_id
152           AND SYSDATE BETWEEN effective_start_date
153                           AND effective_END_date;
154 
155     END IF;
156 
157     IF (p_person_id IS NOT NULL)
158     THEN
159        SELECT full_name
160          INTO lp_person
161          FROM per_all_people_f
162         WHERE person_id = p_person_id
163           AND SYSDATE BETWEEN effective_start_date
164                           AND effective_END_date;
165 
166     END IF;
167 
168     lp_sysdate := TO_CHAR(SYSDATE,'dd-Mon-yyyy HH:MI:SS ');
169 
170 
171     SELECT fnd.user_name||' ['||ppf.full_name||']'
172       INTO lp_user
173       FROM per_all_people_f ppf,
174            fnd_user fnd
175      WHERE ppf.person_id = fnd.employee_id
176        AND SYSDATE BETWEEN ppf.effective_start_date
177                        AND ppf.effective_end_date
178        AND fnd.user_id = FND_GLOBAL.USER_ID;
179 
180 
181 
182     IF g_debug
183     THEN
184        hr_utility.trace('Translated parameters normally ');
185        hr_utility.trace('lp_from_date   : '||lp_from_date);
186        hr_utility.trace('lp_to_date     : '||lp_to_date);
187        hr_utility.trace('lp_dat_regen   : '||lp_dat_regen);
188        hr_utility.trace('lp_record_save : '||lp_record_save);
189        hr_utility.trace('lp_org         : '||lp_org);
190        hr_utility.trace('lp_location    : '||lp_location);
191        hr_utility.trace('lp_payroll     : '||lp_payroll);
192        hr_utility.trace('lp_supervisor  : '||lp_supervisor);
193        hr_utility.trace('lp_person      : '||lp_person);
194        hr_utility.trace('lp_user        : '||lp_user);
195     END IF;
196 
197 END translate_parameters;
198 
199 
200 
201 -- EXECUTE_AUDIT_TRAIL_REPORTING
202 -- Main action block for Timecard Audit Trail Reporting, processes
203 -- the detail records accordingly, and loads data into HXC_RPT_TC_AUDIT.
204 
205 PROCEDURE execute_audit_trail_reporting  (errbuf          OUT NOCOPY VARCHAR2,
206                                           retcode         OUT NOCOPY NUMBER,
207                                           p_date_from     IN VARCHAR2 ,
208                                           p_date_to       IN VARCHAR2 ,
209                                           p_data_regen    IN VARCHAR2 ,
210                                           p_record_save   IN VARCHAR2 ,
211                                           p_org_id        IN NUMBER DEFAULT NULL,
212                                           p_locn_id       IN NUMBER DEFAULT NULL,
213                                           p_payroll_id    IN NUMBER DEFAULT NULL,
214                                           p_supervisor_id IN NUMBER DEFAULT NULL,
215                                           p_person_id     IN NUMBER DEFAULT NULL )
216 AS
217 
218   l_call_status  BOOLEAN ;
219   l_interval     NUMBER := 30;
220   l_phase        VARCHAR2(30);
221   l_status       VARCHAR2(30);
222   l_dev_phase    VARCHAR2(30);
223   l_dev_status   VARCHAR2(30);
224   l_message      VARCHAR2(30);
225   l_sqlcode      NUMBER;
226   l_sqlmsg       VARCHAR2(100);
227 
228 
229   l_data_load_request_id NUMBER;
230   l_resource_id      NUMBER;
231   l_start_time       DATE;
232   l_stop_time        DATE;
233   l_resource_count   NUMBER := 0;
234 
235   CURSOR get_timecards ( p_request_id  NUMBER)
236       IS SELECT resource_id,
237                 tc_start_time,
238                 tc_stop_time
239            FROM hxc_rpt_tc_hist_log log
240           WHERE request_id = p_request_id  ;
241 
242 l_trans_id_tab       FLOATTABLE;
243 l_trans_date_tab     DATETABLE;
244 l_trans_max_date_tab DATETABLE;
245 l_trans_user_tab     VARCHARTABLE;
246 l_trans_name_tab     VARCHARTABLE;
247 l_comments_tab       VARCHARTABLE;
248 l_bb_id_tab          NUMTABLE;
249 l_bb_ovn_tab         NUMTABLE;
250 l_max_bb_id_tab      NUMTABLE;
251 l_trans_status_tab   VARCHARTABLE;
252 
253 
254 l_del_bb_id_tab    NUMTABLE;
255 l_del_bb_ovn_tab   NUMTABLE;
256 l_del_date_tab     DATETABLE;
257 l_del_id_tab       FLOATTABLE;
258 
259 
260 
261 
262 
263 --   EXECUTE AUDIT TRAIL REPORTING -- FUNCTIONAL FLOW
264 --   ================================================
265 --
266 --   This prog is used to created the Change history for each timecard, whose
267 --   information is retrieved from HXC_TIME_ATTRIBUTES, HXC_TIME_BUILDING_BLOCKS
268 --   and HXC_TRANSACTIONS.
269 --
270 --   The processing is done per timecard -- meaning the table HXC_RPT_TC_DETAILS_ALL
271 --   table is grouped by resource_id, start_time and stop_time for each iteration
272 --   of processing.
273 --
274 --   Timecard Level Actions
275 --   ======================
276 --
277 --   Submissions
278 --   -----------
279 --
280 --   In ideal case, each submission would mean a different transaction_id with atleast
281 --   one detail building block id in SUBMITTED status.  For Self Service, Transaction
282 --   is created only when there is a Submission, not for timecard Save, but Timekeeper
283 --   creates a Deposit Transaction for timecard Save as well. So the most basic submission
284 --   has to be captured by looking for distinct DEPOSIT transactions, with Time building
285 --   blocks which are not in WORKING status. In Self service, there is no way you are going
286 --   to submit a timecard with ERROR status, but Timekeeper can do so. Meaning, we are
287 --   showing ERROR status as such too.
288 --
289 --   For the record_save option, a different query would run and pick up the WORKING
290 --   status guys as well.
291 --
292 --   Approvals
293 --   ---------
294 --
295 --   Timecard approvals normally are captured by the APPLICATION_PERIOD scope records
296 --   from hxc_time_building_blocks. A join with our Details_all table and hxc_time_building
297 --   blocks will give you this information. Once you get all the approvals, these has to be placed
298 --   so that the reporting table will get this info in proper place. For this, the submissions
299 --   captured above are browsed thru and a most appropriate submission is found out.
300 --   The transaciton_id of this submission is taken in as the transaction id of the approval
301 --   action and while the report groups the data on transaction_id, we get in the proper order.
302 --   The most appropriate approval is a transaction_id whose action date is equal to
303 --   ( only for Approval on submit style ) or less than the action date for the approval,
304 --   and who has a successive transaction_id with action date greater than the
305 --   approval date.
306 --
307 --   eg.    Approval date               Transaction_dates
308 --          08:05:11                     07:50:33
309 --                                       07:59:15
310 --                                       08:03:52
311 --                                       08:13:34
312 --                                       09:45:23
313 --
314 --      Here the given approval will take the transaction id of 08:03:52.
315 --
316 --
317 --
318 --   Deletions
319 --   ---------
320 --
321 --   Deletions can be of two kinds.
322 --
323 --     1)  Deletion from Recent Timecards page.
324 --     2)  Overwriting with a Template. -- This is deletion and resubmission.
325 --
326 --    The first case is straight forward.  When a timecard is deleted this way
327 --    its all time_building_blocks are end dated, and a new set will be
328 --    created with the created date equal to date_to. We track this down by
329 --    looking at transactions where the creation_date is equal to date_to
330 --    and day_date_to ( date_to of the parent day building block ) is
331 --    end dated.  Actually for the first case day_date_to is equal to the
332 --    creation_date and date_to of the detail record, and this is the only
333 --    thing you need to check. This also means that a negative condition should
334 --    be added to evade this whilst recording submissions.
335 --
336 --    The second case is slightly more complex. Here the details are end dated
337 --    but a new set wont be created.  The worst part is that there might be a
338 --    one or two seconds delay on the date_to timing for the existing set of
339 --    time_building_blocks -- Meaning, the existing OVN of Timecard.Day and
340 --    Detail scopes will have different date_to values. This is exactly the
341 --    reason why we cant equate date_to of the detail record to the day scope
342 --    record and pick up the deleted timecards even in the above case.
343 --
344 --    To escape this, we pick up all records having date_to = creation_date.
345 --    This will pick up records with Timecard Delete as we would expect,
346 --    Overwriting, again expected and those for which a row delete happened
347 --    in the time entry page.  Those for which the row delete happened in the time
348 --    entry page would not have a new timebuilding block id for the submitted timecard.
349 --    Where as a template overwritten timecard will have a new set of time building
350 --    block ids.
351 --
352 --    In either case, the entries would be tracked down as Submissions earlier --
353 --    because though you are deleting timecard as a whole ( while overwriting )
354 --    or deleting a line from the timecard ( while deleting from the time entry
355 --    screen ), the rest of the timecard is submitted.  So loop thru the submissions
356 --    and pick up the transaction of the deletion we are processing.
357 --    For this, check if the max timecard id and min timecard id for the transaction
358 --    are same to the deleted timecards timecard id.
359 --
360 --    TC bb id    OVN   date_to
361 --    1            1    end of time
362 --
363 --    When deleted from the Recent timecards page.
364 --
365 --    TC bb id    OVN    date_to
366 --    1            1     sysdate
367 --
368 --    When deleting a row from the Time entry page.
369 --
370 --    TC bb id    OVN    date_to
371 --    1            1     sysdate
372 --    1            2     end of time
373 --
374 --    When overwriting with a template
375 --
376 --    Tc bb id    OVN    date_to
377 --    1            1     sysdate
378 --    2            1     end of time.
379 --
380 --
381 --    Now the first case will be anyway captured from the query, and there neednt
382 --    be any check on this, because the transaction that is holding it will not
383 --    be picked up in submissions.
384 --
385 --    For the second case, we dont want this as a timecard delete, so compare the
386 --    transactions max tc bb id and min tc bb id. Both will be the same, so dont
387 --    use this record.
388 --
389 --    For the third case the comparison would fail and we have to consider this as
390 --    a deletion.
391 --
392 --      As of now, we are not considering a separate query for Deletions with Record save
393 --      option toggling.  This is because, as of now, in 12.1.1, a deleting an entry
394 --      and saving the timecard yields a Submitted status time entry as well.  This would
395 --      take care of Deletion with Working status being recorded.
396 --
397 --
398 --
399 --    Detail Changes
400 --    --------------
401 --
402 --    The logic followed here is put inline for more clarity.
403 --
404 --
405 --
406 --
407 --    ACTION_TYPE column
408 --    ==================
409 --
410 --    HXC_RPT_TC_AUDIT has this column called Action_type which is used particularly
411 --    in ordering the entries while querying for the report.
412 --
413 --
414 --    Timecard Level Actions
415 --    -----------------------
416 --
417 --    TS                      ---    Timecard Submission
418 --    TSD                     ---    Timecard Deletion
419 --    TSA                     ---    Timecard Approval
420 --
421 --
422 --    These are named so to ease out ordering.  A Deletion or an Approval cannot
423 --    happen without a Submission, hence TS ( alphabetically, the first of the three).
424 --    Once submitted, the next action that might come would be Deletion or Approval.
425 --    But in no way can a Deletion be followed by Approval. It has to be
426 --    either Sub->Appr->Deletion or Sub->Deletion, meaning Deletion will always
427 --    come to the end in the transaction. Hence TSD for Deletion and TSA for approval
428 --    because approval falls b/w the other two, if at all it falls.
429 --
430 --
431 --
432 --    Detail Level Actions
433 --    ---------------------
434 --
435 --    EN                      ---     New Entry/Late Entry
436 --    EB                      ---     Before Edit
437 --    EC                      ---     After Edit
438 --    ED                      ---     Deleted
439 --
440 --
441 --
442 --    No complex logic here. Only Before/After Edit can come together, for the same
443 --    date-detail.  Hence EB and EC respectively, because Before Edit should appear
444 --    first.
445 --
446 --
447 
448 
449 
450 
451 
452 
453   -- RECORD_SUBMISSIONS
454   -- Queries against HXC_RPT_TC_DETAILS_ALL and captures all the timecard
455   -- submissions.
456 
457   PROCEDURE record_submissions( p_resource_id  IN NUMBER,
458                                 p_start_time   IN DATE,
459                                 p_stop_time    IN DATE,
460                                 p_record_save  IN VARCHAR2)
461   AS
462 
463 
464 
465 
466      -- The following two queries have been given conditions for a range
467      -- for a date check.  Creation_date and day_date_to logically could be
468      -- the same value, but for big timecards you would see a one or 2 secs delay.
469      -- Meaning, we check for this condition in a range, rather than an inequality.
470      --
471 
472   CURSOR get_transactions ( p_resource_id NUMBER,
473                             p_start_time  DATE,
474                             p_stop_time   DATE )
475       IS SELECT transaction_id,
476                 MAX(creation_date),
477                 MIN(creation_date),
478                 MIN(created_by_user),
479                 MIN(tc_comments),
480                 MIN(tc_bb_id),
481                 MIN(tc_bb_ovn),
482                 MAX(tc_bb_id),
483                 MIN(resource_name),
484                 MIN(status)
485            FROM hxc_rpt_tc_details_all
486           WHERE resource_id   = p_resource_id
487             AND tc_start_time = p_start_time
488             AND tc_stop_time  = p_stop_time
489             AND creation_date NOT BETWEEN (day_date_to - (2/(24*60*60)))
490                                       AND (day_date_to + (2/(24*60*60)))
491             AND transaction_id IS NOT NULL
492             AND transaction_detail_id IS NOT NULL
493             AND status <> 'WORKING'
494           GROUP BY transaction_id
495           ORDER BY MIN(creation_date) ;
496 
497   CURSOR get_all_transactions ( p_resource_id NUMBER,
498                             p_start_time  DATE,
499                             p_stop_time   DATE )
500       IS SELECT transaction_id,
501                 MAX(creation_date),
502                 MIN(creation_date),
503                 MIN(created_by_user),
504                 MIN(tc_comments),
505                 MIN(tc_bb_id),
506                 MIN(tc_bb_ovn),
507                 MAX(tc_bb_id),
508                 MIN(resource_name),
509                 MIN(decode(transaction_detail_id,NULL,'WORKING',status))
510            FROM hxc_rpt_tc_details_all
511           WHERE resource_id   = p_resource_id
512             AND tc_start_time = p_start_time
513             AND tc_stop_time  = p_stop_time
514             AND creation_date NOT BETWEEN (day_date_to - (2/(24*60*60)))
515                                       AND (day_date_to + (2/(24*60*60)))
516             AND transaction_id IS NOT NULL
517           GROUP BY transaction_id
518           ORDER BY MIN(creation_date) ;
519 
520 
521   BEGIN
522 
523       -- Private Procedure record_submissions
524       -- Query from HXC_RPT_TC_DETAILS_ALL, grouping by transaction
525       --       id for this timecard, and pick up all the distinct
526       --       transaction ids, and relevant info like the users, dates
527       --       timecard_id, ovn, etc.
528       -- Insert into HXC_RPT_TC_AUDIT, the picked up information.
529 
530       IF g_debug
531       THEN
532          hr_utility.trace('record_submissions for '||p_resource_id
533                         ||' from '||p_start_time
534                         ||' to '||p_stop_time);
535       END IF;
536 
537       IF p_record_save = 'Y'
538       THEN
539           OPEN get_all_transactions(p_resource_id,
540       	                        p_start_time,
541       	                        p_stop_time );
542 
543       	  FETCH get_all_transactions BULK COLLECT INTO l_trans_id_tab,
544       	                                           l_trans_max_date_tab,
545       	                                           l_trans_date_tab,
546       	                                           l_trans_user_tab,
547       	                                           l_comments_tab,
548       	                                           l_bb_id_tab,
549       	                                           l_bb_ovn_tab,
550       	                                           l_max_bb_id_tab,
551       	                                           l_trans_name_tab,
552       	                                           l_trans_status_tab ;
553       	  CLOSE get_all_transactions;
554       ELSE
555           OPEN get_transactions(p_resource_id,
556       	                        p_start_time,
557       	                        p_stop_time );
558 
559       	  FETCH get_transactions BULK COLLECT INTO l_trans_id_tab,
560       	                                           l_trans_max_date_tab,
561       	                                           l_trans_date_tab,
562       	                                           l_trans_user_tab,
563       	                                           l_comments_tab,
564       	                                           l_bb_id_tab,
565       	                                           l_bb_ovn_tab,
566       	                                           l_max_bb_id_tab,
567       	                                           l_trans_name_tab,
568       	                                           l_trans_status_tab ;
569       	  CLOSE get_transactions;
570       END IF;
571 
572       IF g_debug
573       THEN
574          hr_utility.trace('Fetched from get_transactions ');
575          hr_utility.trace('Total number of submissions : '||l_trans_id_tab.COUNT);
576       END IF;
577 
578 
579       IF l_trans_id_tab.COUNT > 0
580       THEN
581          FORALL i IN l_trans_id_tab.FIRST..l_trans_id_tab.LAST
582               INSERT INTO hxc_rpt_tc_audit
583                          ( resource_id,
584                            tc_start_time,
585                            tc_stop_time,
586                            resource_name,
587                            action,
588                            action_date,
589                            action_by,
590                            comments,
591                            transaction_id,
592                            tc_bb_id,
593                            tc_bb_ovn,
594                            action_type )
595                    VALUES ( p_resource_id,
596                             p_start_time,
597                             p_stop_time,
598                             l_trans_name_tab(i),
599                             INITCAP(DECODE(l_trans_status_tab(i),'WORKING','Saved',l_trans_status_tab(i))),
600                             l_trans_max_date_tab(i),
601                             l_trans_user_tab(i),
602                             l_comments_tab(i),
603                             l_trans_id_tab(i),
604                             l_bb_id_tab(i),
605                             l_bb_ovn_tab(i),
606                             'TS' );
607       END IF;
608 
609       IF g_debug
610       THEN
611          hr_utility.trace('record_submissions completed alright ');
612       END IF;
613 
614 
615   END record_submissions ;
616 
617 
618 
619   -- RECORD_APPROVALS
620   -- Queries against HXC_TIME_BUIDLING_BLOCKS to capture the
621   -- Approval details for this timecard.
622 
623   PROCEDURE record_approvals ( p_resource_id   IN NUMBER,
624                                p_start_time    IN DATE,
625                                p_stop_time     IN DATE )
626   AS
627 
628 
629   CURSOR get_approvals ( p_resource_id NUMBER,
630                          p_start_time  DATE,
631                          p_stop_time   DATE )
632       IS SELECT 0 transaction_id,
633                 0 tc_bb_id,
634                 hxc.creation_date,
635                 fnd.user_name ,
636                 NVL(fnd.employee_id,-1),
637                 INITCAP(approval_status),
638                 DECODE(comment_text,
639                        'LIGHT_APPROVAL','Approval On Submit',
640                        'AUTO_APPROVE',  'Auto Approved',
641                        comment_text),
642                 ' '
643            FROM hxc_time_building_blocks hxc,
644                 fnd_user fnd
645           WHERE scope = 'APPLICATION_PERIOD'
646             AND resource_id        = p_resource_id
647             AND p_start_time BETWEEN start_time
648                                  AND stop_time
649             AND TRUNC(p_stop_time) BETWEEN start_time
650                                        AND stop_time
651             AND approval_status IN ('APPROVED','REJECTED')
652             AND fnd.user_id = hxc.created_by
653             AND NVL(hxc.comment_text,' ') <> 'TIMED_OUT'
654             AND NVL(hxc.comment_text,' ') <> 'BLANK_NOTIFICATION'
655          ORDER BY hxc.creation_date ;
656 
657 
658 
659   CURSOR get_approvers ( p_person_id   NUMBER,
660                          p_appr_date   DATE )
661       IS SELECT full_name
662            FROM per_all_people_f
663           WHERE person_id   = p_person_id
664             AND p_appr_date BETWEEN effective_start_date
665                                 AND effective_end_date ;
666 
667 
668 
669   l_appr_trans_tab    NUMTABLE;
670   l_appr_bb_tab       NUMTABLE;
671   l_appr_date_tab     DATETABLE;
672   l_appr_user_tab     VARCHARTABLE;
673   l_appr_status_tab   VARCHARTABLE;
674   l_appr_comments_tab VARCHARTABLE;
675   l_appr_resource_tab VARCHARTABLE;
676   l_appr_person_tab   NUMTABLE;
677   l_approver_name     VARCHAR2(400);
678 
679   BEGIN
680 
681       -- Private Procedure record_approvals
682       -- Queries against HXC_TIME_BUILDING_BLOCKS and FND_USER
683       --      for all the APPLICATION_PERIOD records for this timecard.
684       --      The application periods are joined with BETWEEN & AND
685       --      conditions to pull up those timecards whose Approval period
686       --      spans across multiple timecard periods.
687       -- To find out the user's name fetch the full name from PER_ALL_PEOPLE_F.
688       -- To find out the transaction/submission that matches these approvals,
689       --      loops thru the transaction date pl/sql table already created, to find
690       --      a matching transaction.
691       -- Once all the transactions are picked up, inserts the records into HXC_RPT_TC_AUDIT.
692 
693       IF g_debug
694       THEN
695          hr_utility.trace('record_approvals for '||p_resource_id
696                         ||' from '||p_start_time
697                         ||' to '||p_stop_time);
698       END IF;
699 
700       OPEN get_approvals (p_resource_id,
701                           p_start_time,
702                           p_stop_time ) ;
703 
704       FETCH get_approvals BULK COLLECT INTO l_appr_trans_tab,
705                                             l_appr_bb_tab,
706                                             l_appr_date_tab,
707                                             l_appr_user_tab,
708                                             l_appr_person_tab,
709                                             l_appr_status_tab,
710                                             l_appr_comments_tab,
711                                             l_appr_resource_tab ;
712 
713        CLOSE get_approvals;
714 
715        IF g_debug
716        THEN
717           hr_utility.trace('Fetched from get_approvals ');
718           hr_utility.trace('Total number of approvals : '||l_appr_trans_tab.COUNT);
719        END IF;
720 
721 
722        IF l_appr_trans_tab.COUNT > 0
723        THEN
724           FOR i IN l_appr_trans_tab.FIRST..l_appr_trans_tab.LAST
725           LOOP
726 
727              -- Initialize the approver's name to blank.
728              l_approver_name := ' ';
729 
730              -- Do this only if there exists a valid person. -1 here would mean
731              -- a null for employee_id in FND_USER, so the person who approved
732              -- is a dummy person like SYSADMIN.
733 
734              IF l_appr_person_tab(i) <> -1
735              THEN
736                 OPEN get_approvers( l_appr_person_tab(i),
737                                     l_appr_date_tab(i) );
738                 FETCH get_approvers INTO l_approver_name;
739                 CLOSE get_approvers;
740              END IF;
741 
742              l_appr_user_tab(i) := l_appr_user_tab(i)||newline
743                                          ||'['||l_approver_name||']';
744 
745              -- Bug 9137834
746              -- Added the following IF condition to take care of
747              -- BLANK auto approved timecards.
748              IF l_trans_id_tab.COUNT > 0
749              THEN
750 
751                 FOR j IN l_trans_id_tab.FIRST..l_trans_id_tab.LAST-1
752              	LOOP
753 
754              	   IF ( (l_trans_date_tab(j) <= l_appr_date_tab(i))
755              	      AND (l_trans_date_tab(j+1) > l_appr_date_tab(i)))
756              	   THEN
757              	      l_appr_trans_tab(i) := l_trans_id_tab(j);
758              	      l_appr_bb_tab(i)    := l_bb_id_tab(j);
759              	      l_appr_resource_tab(i) := l_trans_name_tab(j);
760              	      EXIT;
761              	   END IF;
762              	END LOOP;
763 
764              	IF l_appr_trans_tab(i) = 0
765              	THEN
766              	    l_appr_trans_tab(i) := l_trans_id_tab(l_trans_id_tab.LAST);
767              	    l_appr_bb_tab(i) := l_bb_id_tab(l_bb_id_tab.LAST);
768              	    l_appr_resource_tab(i) := l_trans_name_tab(l_bb_id_tab.LAST);
769              	END IF;
770 
771              END IF;
772 
773            END LOOP;
774 
775           FORALL i IN l_appr_trans_tab.FIRST..l_appr_trans_tab.LAST
776                  INSERT INTO hxc_rpt_tc_audit
777                          ( resource_id,
778                            tc_start_time,
779                            tc_stop_time,
780                            resource_name,
781                            action,
782                            action_date,
783                            action_by,
784                            comments,
785                            transaction_id,
786                            tc_bb_id,
787                            action_type )
788                     VALUES ( p_resource_id,
789                              p_start_time,
790                              p_stop_time,
791                              l_appr_resource_tab(i),
792                              l_appr_status_tab(i),
793                              l_appr_date_tab(i),
794                              l_appr_user_tab(i),
795                              l_appr_comments_tab(i),
796                              l_appr_trans_tab(i),
797                              l_appr_bb_tab(i),
798                              'TSA' );
799 
800        l_appr_trans_tab.DELETE;
801        l_appr_bb_tab.DELETE;
802        l_appr_date_tab.DELETE;
803        l_appr_user_tab.DELETE;
804        l_appr_resource_tab.DELETE;
805        l_appr_status_tab.DELETE;
806        l_appr_comments_tab.DELETE;
807 
808 
809       END IF;
810 
811       IF g_debug
812       THEN
813          hr_utility.trace('record_approvals completed alright ');
814       END IF;
815 
816 
817 
818   END record_approvals ;
819 
820 
821 
822 
823   -- RECORD_DELETIONS
824   -- Queries against HXC_RPT_TC_DETAILS_ALL to find out all the timecard
825   -- deletions, and records these into HXC_RPT_TC_AUDIT.
826 
827   PROCEDURE record_deletions  ( p_resource_id  IN NUMBER,
828                                 p_start_time   IN DATE,
829                                 p_stop_time    IN DATE )
830   AS
831 
832   CURSOR get_deletions ( p_resource_id NUMBER,
833                             p_start_time  DATE,
834                             p_stop_time   DATE )
835       IS SELECT transaction_id,
836                 MIN(creation_date),
837                 MIN(created_by_user),
838                 MIN(tc_comments),
839                 MIN(tc_bb_id),
840                 MIN(tc_bb_ovn),
841                 MIN(resource_name)
842            FROM hxc_rpt_tc_details_all det
843           WHERE resource_id   = p_resource_id
844             AND tc_start_time = p_start_time
845             AND tc_stop_time  = p_stop_time
846             AND day_date_to   <> hr_general.end_of_time
847             AND creation_date  = date_to
848             AND transaction_id IS NOT NULL
849             AND status <> 'WORKING'
850             AND NOT EXISTS ( SELECT 1
851                                FROM hxc_timecard_summary hxc
852                               WHERE timecard_id = det.tc_bb_id
853                                 AND hxc.resource_id  = det.resource_id
854                                 AND hxc.start_time   = det.tc_start_time
855                             )
856           GROUP BY transaction_id
857           ORDER BY MIN(creation_date) ;
858 
859 
860 
861 
862   l_del_comments_tab VARCHARTABLE;
863   l_del_user_tab     VARCHARTABLE;
864   l_del_name_tab     VARCHARTABLE;
865 
866 
867 
868   BEGIN
869 
870 
871       -- Private Procedure record_deletions
872       -- Queries against HXC_RPT_TC_DETAILS_ALL table for all records
873       --      that have creation_date = deleted date for the day record
874       --      These indicate a timecard delete.
875       -- Insert these including the transaction_ids into HXC_RPT_TC_AUDIT.
876 
877       IF g_debug
878       THEN
879          hr_utility.trace('record_deletions for '||p_resource_id
880                         ||' from '||p_start_time
881                         ||' to '||p_stop_time);
882       END IF;
883 
884 
885       OPEN get_deletions   (p_resource_id,
886                             p_start_time,
887                             p_stop_time );
888       FETCH get_deletions BULK COLLECT INTO l_del_id_tab,
889                                             l_del_date_tab,
890                                             l_del_user_tab,
891                                             l_del_comments_tab,
892                                             l_del_bb_id_tab,
893                                             l_del_bb_ovn_tab,
894                                             l_del_name_tab ;
895       CLOSE get_deletions;
896 
897       IF g_debug
898       THEN
899          hr_utility.trace('Fetched from get_deletions ');
900          hr_utility.trace('Total number of deletions : '||l_del_id_tab.COUNT);
901       END IF;
902 
903 
904       IF l_del_id_tab.COUNT > 0
905       THEN
906          FOR i IN l_del_id_tab.FIRST..l_del_id_tab.LAST
907          LOOP
908             FOR j IN l_trans_id_tab.FIRST..l_trans_id_tab.LAST
909             LOOP
910                IF l_trans_id_tab(j) = l_del_id_tab(i)
911                THEN
912 
913                   IF l_max_bb_id_tab(j) = l_del_bb_id_tab(i)
914                   THEN
915                     l_del_id_tab(i) := 0;
916                     EXIT;
917                   END IF;   -- l_max_bb_id_tab(j) = l_bb_id_tab(j)
918 
919                   IF l_trans_id_tab.EXISTS(j-1)
920                   THEN
921                       l_del_id_tab(i) := l_trans_id_tab(j-1) ;
922                   ELSE
923                      l_del_id_tab(i) := l_del_id_tab(i) - 1;
924                   END IF; -- l_trans_id_tab.EXISTS(j-1)
925                   EXIT;   -- l_trans_id_tab.FIRST..l_trans_id_tab.LAST
926                END IF;    -- l_trans_id_tab(j) = l_del_id_tab(i)
927             END LOOP;     -- l_trans_id_tab.FIRST..l_trans_id_tab.LAST
928          END LOOP;        -- l_del_id_tab.FIRST..l_del_id_tab.LAST
929 
930 
931 
932          FOR i IN l_del_id_tab.FIRST..l_del_id_tab.LAST
933          LOOP
934             IF l_del_id_tab(i) <> 0
935             THEN
936               INSERT INTO hxc_rpt_tc_audit
937                          ( resource_id,
938                            tc_start_time,
939                            tc_stop_time,
940                            resource_name,
941                            action,
942                            action_date,
943                            action_by,
944                            comments,
945                            transaction_id,
946                            tc_bb_id,
947                            tc_bb_ovn,
948                            action_type )
949                    VALUES ( p_resource_id,
950                             p_start_time,
951                             p_stop_time,
952                             l_del_name_tab(i),
953                             'Deleted Timecard',
954                             l_del_date_tab(i),
955                             l_del_user_tab(i),
956                             l_del_comments_tab(i),
957                             l_del_id_tab(i),
958                             l_del_bb_id_tab(i),
959                             l_del_bb_ovn_tab(i),
960                             'TSD' );
961               END IF; -- l_del_id_tab(i) <> 0
962          END LOOP;
963 
964       	 l_del_comments_tab.DELETE;
965       	 l_del_user_tab.DELETE;
966       	 l_del_name_tab.DELETE;
967 
968       END IF;
969 
970       IF g_debug
971       THEN
972          hr_utility.trace('record_deletions completed alright ');
973       END IF;
974 
975 
976   END record_deletions ;
977 
978 
979 
980 
981   -- RECORD_DETAILS
982   -- Queries against HXC_RPT_TC_DETAILS_ALL and records the detail records
983   -- in the required format.
984 
985 
986   PROCEDURE record_details ( p_resource_id  IN NUMBER,
987                              p_start_time   IN DATE,
988                              p_stop_time    IN DATE,
989                              p_record_save  IN VARCHAR2 )
990   AS
991 
992     l_audit_cnt  NUMBER := 0;
993     temp1        VARCHAR2(500);
994     temp2        VARCHAR2(500);
995 
996     l_tc_details       TIMEDETAILSTABLE;
997     l_audit_details    AUDITTABLE ;
998 
999     l_delete_done      BOOLEAN;
1000 
1001 
1002    -- The following two queries have been given conditions for a range
1003    -- for a date check.  Creation_date and day_date_to logically could be
1004    -- the same value, but for big timecards you would see a one or 2 secs delay.
1005    -- Meaning, we check for this condition in a range, rather than an inequality.
1006    --
1007    CURSOR get_details ( p_resource_id NUMBER,
1008                        p_start_time  DATE,
1009                        p_stop_time   DATE )
1010       IS SELECT  *
1011            FROM hxc_rpt_tc_details_all
1012           WHERE resource_id           = p_resource_id
1013             AND tc_start_time 	      = p_start_time
1014             AND tc_stop_time  	      = p_stop_time
1015             AND creation_date         NOT BETWEEN (day_date_to - (2/(24*60*60)))
1016                                       AND (day_date_to + (2/(24*60*60)))
1017             AND transaction_id        IS NOT NULL
1018             AND transaction_detail_id IS NOT NULL
1019             AND status <> 'WORKING'
1020           ORDER BY detail_bb_id,
1021                    detail_bb_ovn ;
1022 
1023 
1024    CURSOR get_all_details ( p_resource_id NUMBER,
1025                             p_start_time  DATE,
1026                             p_stop_time   DATE )
1027       IS SELECT  *
1028            FROM hxc_rpt_tc_details_all
1029           WHERE resource_id   = p_resource_id
1030             AND tc_start_time = p_start_time
1031             AND tc_stop_time  = p_stop_time
1032             AND creation_date         NOT BETWEEN (day_date_to - (2/(24*60*60)))
1033                                       AND (day_date_to + (2/(24*60*60)))
1034             AND transaction_id IS NOT NULL
1035           ORDER BY detail_bb_id,
1036                    detail_bb_ovn ;
1037 
1038 
1039     -- COPY_TIMECARD_TO_AUDIT
1040     -- Copies the timecard record from HXC_RPT_TC_DETAILS_ALL to an
1041     -- audit record format, like the record structure in HXC_RPT_TC_AUDIT.
1042 
1043     PROCEDURE copy_timecard_to_audit (p_tc_record    IN            hxc_rpt_tc_details_all%ROWTYPE,
1044                                       p_audit_record IN OUT NOCOPY hxc_rpt_tc_audit%ROWTYPE)
1045     AS
1046     BEGIN
1047 
1048           -- Private Procedure copy_timecard_to_audit
1049           -- Copies timecard style record from HXC_RPT_TC_DETAILS_ALL
1050           --    to audit type after putting in necessary formatting, like
1051           --    concatenating all attributes, with a Line Feed as separator.
1052 
1053           p_audit_record.detail_bb_id  := p_tc_record.detail_bb_id;
1054           p_audit_record.detail_bb_ovn := p_tc_record.detail_bb_ovn;
1055           p_audit_record.time_entry_date := p_tc_record.day_start_time;
1056           p_audit_record.attribute_info :=
1057                  p_tc_record.attribute1||newline||p_tc_record.attribute2||newline||
1058                  p_tc_record.attribute3||newline||p_tc_record.attribute4||newline||
1059 		 p_tc_record.attribute5||newline||p_tc_record.attribute6||newline||
1060 		 p_tc_record.attribute7||newline||p_tc_record.attribute8||newline||
1061 		 p_tc_record.attribute9||newline||p_tc_record.attribute10||newline||
1062   		 p_tc_record.attribute11||newline||p_tc_record.attribute12||newline||
1063 		 p_tc_record.attribute13||newline||p_tc_record.attribute14||newline||
1064 		 p_tc_record.attribute15||newline||p_tc_record.attribute16||newline||
1065 		 p_tc_record.attribute17||newline||p_tc_record.attribute18||newline||
1066 		 p_tc_record.attribute19||newline||p_tc_record.attribute20||newline||
1067 		 p_tc_record.attribute21||newline||p_tc_record.attribute22||newline||
1068 		 p_tc_record.attribute23||newline||p_tc_record.attribute24||newline||
1069 		 p_tc_record.attribute25||newline||p_tc_record.attribute26||newline||
1070 		 p_tc_record.attribute27||newline||p_tc_record.attribute28||newline||
1071 		 p_tc_record.attribute29||newline||p_tc_record.attribute30;
1072 
1073           p_audit_record.attribute_info := LTRIM(RTRIM(p_audit_record.attribute_info,newline),newline) ;
1074           p_audit_record.hours := p_tc_record.hours_measure;
1075           p_audit_record.action_date := p_tc_record.creation_date;
1076           p_audit_record.action_by := p_tc_record.created_by_user;
1077           p_audit_record.comments := p_tc_record.detail_comments;
1078           p_audit_record.transaction_id := p_tc_record.transaction_id;
1079           p_audit_record.resource_id := p_tc_record.resource_id;
1080           p_audit_record.resource_name := p_tc_record.resource_name;
1081           p_audit_record.tc_start_time := p_tc_record.tc_start_time;
1082           p_audit_record.tc_stop_time  := p_tc_record.tc_stop_time;
1083           p_audit_record.cla_reason    :=
1084                        LTRIM(RTRIM(p_tc_record.cla_reason||'-'||
1085                          p_tc_record.cla_comments,'-'),'-');
1086 
1087           -- Code below added to include start stop times in the report.
1088           -- TO_CHAR(date,'HHMISSAM') will print the time in the following
1089           -- format.
1090           --   115959PM
1091           --  If the start, stop times are not given, the default time
1092           -- of <date> 11:59:59 PM would be the column value.
1093           --  Just check this up. If its not the default time, record it
1094           -- as start stop time.
1095 
1096 
1097           IF TO_CHAR(p_tc_record.day_stop_time,'HHMISSAM') <> '115959PM'
1098           THEN
1099               p_audit_record.start_stop_time := to_char(p_tc_record.day_start_time,'HH:MI AM')||newline||
1100                              to_char(p_tc_record.day_stop_time,'HH:MI AM');
1101           END IF;
1102 
1103 
1104 
1105       END copy_timecard_to_audit ;
1106 
1107       -- TIME_DETAILS
1108       -- For a given timecard record, from HXC_RPT_TC_DETAILS_ALL, returns a
1109       -- concatenated string of attributes, hours and comments.
1110 
1111       FUNCTION time_details( p_tc_record  IN hxc_rpt_tc_details_all%ROWTYPE )
1112       RETURN VARCHAR2
1113       AS
1114        time_detail VARCHAR2(4000);
1115 
1116       BEGIN -- time_details
1117 
1118            -- Private function time_details
1119            -- Concatenates the attributes, hours and detail comments and returns these as a
1120            --    string.
1121            time_detail := p_tc_record.attribute1||p_tc_record.attribute2||p_tc_record.attribute3||
1122 			  p_tc_record.attribute4||p_tc_record.attribute5||p_tc_record.attribute6||
1123 			  p_tc_record.attribute7||p_tc_record.attribute8||p_tc_record.attribute9||
1124 			  p_tc_record.attribute10||p_tc_record.attribute11||p_tc_record.attribute12||
1125 			  p_tc_record.attribute13||p_tc_record.attribute14||p_tc_record.attribute15||
1126 			  p_tc_record.attribute16||p_tc_record.attribute17||p_tc_record.attribute18||
1127 			  p_tc_record.attribute19||p_tc_record.attribute20||p_tc_record.attribute21||
1128 			  p_tc_record.attribute22||p_tc_record.attribute23||p_tc_record.attribute24||
1129 			  p_tc_record.attribute25||p_tc_record.attribute26||p_tc_record.attribute27||
1130 			  p_tc_record.attribute28||p_tc_record.attribute29||p_tc_record.attribute30||
1131                           to_char(p_tc_record.day_start_time,'dd/mm/yy/hh24/mi/ss')||
1132                           to_char(p_tc_record.day_stop_time,'dd/mm/yy/hh24/mi/ss')||
1133 			  p_tc_record.hours_measure||p_tc_record.detail_comments;
1134            RETURN time_detail;
1135       END time_details;
1136 
1137 
1138       -- INSERT_DETAILS
1139       -- Inserts all the audit records into HXC_RPT_TC_AUDIT.
1140 
1141       PROCEDURE insert_details
1142       AS
1143 
1144       BEGIN
1145 
1146           -- Private Procedure insert_details
1147           -- Inserts the details collected into audit record pl/sql table, into
1148           --     HXC_RPT_TC_AUDIT.
1149 
1150           IF g_debug
1151           THEN
1152              hr_utility.trace('Inserting details into hxc_rpt_tc_audit ');
1153 
1154              -- Commenting the below code, which logs all the detail info to be
1155              -- recorded into HXC_RPT_TC_AUDIT.  Not too much hit to performance,
1156              -- but uncomment and run only if you see that there is an issue in the way
1157              -- the details are getting framed.  Else, this would just add on hundreds
1158              -- of lines to your log files, nothing more.
1159 
1160              -- FOR i IN l_audit_details.FIRST..l_audit_details.LAST
1161              -- LOOP
1162              --    hr_utility.trace('Record No.'||i);
1163              --    hr_utility.trace('time_entry_date : '||l_audit_details(i).time_entry_date);
1164              -- 	hr_utility.trace('attribute_info : '||l_audit_details(i).attribute_info);
1165              -- 	hr_utility.trace('hours : '||l_audit_details(i).hours);
1166              -- 	hr_utility.trace('action : '||l_audit_details(i).action);
1167              -- 	hr_utility.trace('action_date : '||l_audit_details(i).action_date);
1168              -- 	hr_utility.trace('action_by : '||l_audit_details(i).action_by);
1169              -- 	hr_utility.trace('comments : '||l_audit_details(i).comments);
1170              -- 	hr_utility.trace('reasons : '||l_audit_details(i).reasons);
1171              -- 	hr_utility.trace('transaction_id : '||l_audit_details(i).transaction_id);
1172              -- 	hr_utility.trace('detail_bb_id : '||l_audit_details(i).detail_bb_id);
1173              -- 	hr_utility.trace('detail_bb_ovn : '||l_audit_details(i).detail_bb_ovn);
1174              -- 	hr_utility.trace('tc_bb_id : '||l_audit_details(i).tc_bb_id);
1175              -- 	hr_utility.trace('tc_bb_ovn : '||l_audit_details(i).tc_bb_ovn);
1176              -- 	hr_utility.trace('action_type : '||l_audit_details(i).action_type);
1177              -- 	hr_utility.trace('resource_id : '||l_audit_details(i).resource_id);
1178              -- 	hr_utility.trace('tc_start_time : '||l_audit_details(i).tc_start_time);
1179              -- 	hr_utility.trace('tc_stop_time : '||l_audit_details(i).tc_stop_time);
1180              -- 	hr_utility.trace('action_by_person : '||l_audit_details(i).action_by_person);
1181              -- 	hr_utility.trace('cla_reason : '||l_audit_details(i).cla_reason);
1182              -- 	hr_utility.trace('resource_name : '||l_audit_details(i).resource_name);
1183              -- END LOOP;
1184 
1185           END IF;
1186 
1187           FORALL i IN l_audit_details.FIRST..l_audit_details.LAST
1188                INSERT INTO hxc_rpt_tc_audit
1189                     VALUES l_audit_details(i);
1190          COMMIT;
1191       END insert_details ;
1192 
1193 
1194   BEGIN -- record_details
1195 
1196 
1197       -- Private Procedure record_details
1198       -- Pick up all the detail records from HXC_RPT_TC_DETAILS_ALL for this timecard into
1199       --    pl/sql table of HXC_RPT_TC_DETAILS_ALL rowtype, ordered by detail bb id. If
1200       --    p_record_save is set to Y, need to pick up WORKING status records also. In that
1201       --    case work with get_all_details cursor, else with get_details.
1202       -- Loop thru these picked up details.
1203       --    *  If the OVN is 1, then it is a New Entry, if its not a Late Entry.
1204       --       If CLA reason is NULL, then it is a New Entry, else its a Late Entry.
1205       --       If CLA reason is not NULL, but the entry was made well in time, its
1206       --       a Late Entry, just a New Entry.
1207       --    *  If OVN is not 1, then check if there is another element of the same
1208       --       bb id before this element. -- If yes, then its a changed entry,
1209       --       if the date_to column is not end of time, make sure this is an edited entry
1210       --       so record as After Edit after comparing the attributes of this element and
1211       --       the previous element.
1212       --       If there is no element prior to this with the same bb id, then its again a New
1213       --       Entry.
1214       --    *  Check the next entry in the table, if it is of the same bb id, then this is
1215       --       changed in the next transaction, so insert a record with Before Edit entry
1216       --       after fetching the proper transaction id and after checking if the attributes
1217       --       have changed.
1218       --    *  If the next entry with the same bb id is having an end date, then you know it is
1219       --       deleted in the next submission.  So create an entry saying Deleted.
1220       -- Once you have looped thru all the records, insert the details collected into HXC_RPT_
1221       -- TC_AUDIT.
1222 
1223       -- Inline comments are put in for more clarity.
1224 
1225       l_audit_details := audittable();
1226 
1227       IF p_record_save = 'Y'
1228       THEN
1229          OPEN get_all_details(p_resource_id,
1230                               p_start_time,
1231                               p_stop_time );
1232 
1233          FETCH get_all_details BULK
1234                             COLLECT INTO l_tc_details ;
1235 
1236          CLOSE get_all_details;
1237       ELSE
1238          OPEN get_details(p_resource_id,
1239                           p_start_time,
1240                           p_stop_time );
1241 
1242          FETCH get_details BULK
1243                         COLLECT INTO l_tc_details ;
1244 
1245          CLOSE get_details;
1246       END IF;
1247 
1248       IF g_debug
1249       THEN
1250          hr_utility.trace('Fetched details ');
1251          hr_utility.trace('Total Number of details fetched : '||l_tc_details.COUNT);
1252       END IF;
1253 
1254 
1255       IF l_tc_details.COUNT > 0
1256       THEN
1257 
1258 
1259       FOR i IN l_tc_details.FIRST..l_tc_details.LAST
1260       LOOP
1261           -- First of all, make sure if this entry is included in a Deletion
1262           -- ( A deletion can be a deletion from Recent timecards page or
1263           --   an Overwrite with template.  An Overwritten timecard entries
1264           --   neednt be shown again, and need to be trimmed off.  So check if
1265           --   this time entry belongs to a timecard previously recorded as
1266           --   Deleted )
1267           l_delete_done := FALSE;
1268           IF (     l_del_bb_id_tab.COUNT > 0
1269                AND l_tc_details(i).date_to <> hr_general.end_of_time )
1270           THEN
1271              FOR x IN l_del_bb_id_tab.FIRST..l_del_bb_id_tab.LAST
1272              LOOP
1273                 IF (     l_del_bb_id_tab(x)  = l_tc_details(i).tc_bb_id
1274                      AND l_del_bb_ovn_tab(x) = l_tc_details(i).tc_bb_ovn
1275                      AND l_del_id_tab(x) <> 0
1276                     )
1277                 THEN
1278                    -- Found out its true, so mark the flag.  We would use this flag before
1279                    -- inserting.
1280                    l_delete_done := TRUE;
1281                    EXIT;
1282                 END IF;
1283               END LOOP;
1284            END IF;
1285 
1286           IF (l_tc_details(i).detail_bb_ovn = 1) OR
1287             (    (l_tc_details(i).detail_bb_ovn <> 1)
1288               AND l_tc_details.EXISTS(i-1) = FALSE ) OR
1289             (     l_tc_details.EXISTS(i-1) = TRUE
1290               AND l_tc_details(i-1).detail_bb_id <> l_tc_details(i).detail_bb_id)
1291 
1292           THEN -- new record
1293              l_audit_details.EXTEND;
1294              l_audit_cnt := l_audit_cnt + 1 ;
1295              copy_timecard_to_audit(l_tc_details(i),
1296                                     l_audit_details(l_audit_cnt));
1297              IF ( l_tc_details(i).cla_type = 'LATE'
1298                  AND TRUNC(l_tc_details(i).creation_date) >
1299                            TRUNC(l_tc_details(i).day_start_time) )
1300              THEN
1301                  l_audit_details(l_audit_cnt).action := 'Late Entry';
1302              ELSE
1303                  l_audit_details(l_audit_cnt).action := 'New Entry';
1304              END IF;
1305              l_audit_details(l_audit_cnt).action_type := 'EN' ;
1306           ELSE -- if not new record
1307              IF l_tc_details(i).detail_bb_id = l_tc_details(i-1).detail_bb_id
1308              THEN
1309                  temp1 :=    time_details(l_tc_details(i));
1310                  temp2 :=    time_details(l_tc_details(i-1));
1311                  IF temp1 <> temp2
1312                  THEN
1313                     l_audit_details.EXTEND(1);
1314                     l_audit_cnt := l_audit_cnt + 1 ;
1315 
1316                     copy_timecard_to_audit(l_tc_details(i),
1317                                            l_audit_details(l_audit_cnt) );
1318                     l_audit_details(l_audit_cnt).action := 'After Edit';
1319                     l_audit_details(l_audit_cnt).action_type := 'EC' ;
1320                  END IF; -- IF temp1 <> temp2
1321              END IF; -- IF l_tc_details(i-1).detail_bb_id = l_tc_details(i-1).detail_bb_id
1322           END IF;  -- IF new record
1323 
1324           IF l_tc_details(i).date_to <> hr_general.end_of_time
1325           THEN
1326              IF l_tc_details.EXISTS(i+1)
1327              THEN
1328                 IF l_tc_details(i).detail_bb_id = l_tc_details(i+1).detail_bb_id
1329                 THEN -- Changed Record
1330                    temp1 :=   time_details(l_tc_details(i));
1331                    temp2 :=   time_details(l_tc_details(i+1));
1332                    IF temp1 <> temp2
1333                    THEN -- Not just OVN, a real change
1334                         l_audit_details.EXTEND(1);
1335                         l_audit_cnt := l_audit_cnt + 1 ;
1336                         copy_timecard_to_audit(l_tc_details(i),
1337                                                l_audit_details(l_audit_cnt));
1338                         l_audit_details(l_audit_cnt).comments := l_tc_details(i).detail_comments;
1339                         l_audit_details(l_audit_cnt).transaction_id := l_tc_details(i+1).transaction_id;
1340                         l_audit_details(l_audit_cnt).action_by := l_tc_details(i).last_updated_by_user;
1341                         l_audit_details(l_audit_cnt).action := 'Before Edit';
1342                         l_audit_details(l_audit_cnt).action_type := 'EB' ;
1343                    END IF; -- IF temp1 <> temp2
1344                 ELSE -- its deleted	 (l_tc_details(i).detail_bb_id = l_tc_details(i+1).detail_bb_id
1345                      --               is false )
1346                    FOR j IN l_trans_id_tab.FIRST..l_trans_id_tab.LAST
1347                    LOOP
1348                       IF (l_trans_date_tab(j) >= l_tc_details(i).date_to)
1349                         AND (l_bb_id_tab(j) = l_tc_details(i).tc_bb_id)
1350                       THEN
1351                           l_audit_details.EXTEND(1);
1352                           l_audit_cnt := l_audit_cnt + 1 ;
1353                           copy_timecard_to_audit(l_tc_details(i),
1354                                               l_audit_details(l_audit_cnt));
1355                           l_audit_details(l_audit_cnt).action_date := l_trans_date_tab(j);
1356                           l_audit_details(l_audit_cnt).action_by := l_tc_details(i).last_updated_by_user;
1357                           l_audit_details(l_audit_cnt).action := 'Deleted';
1358                           l_audit_details(l_audit_cnt).action_type := 'ED' ;
1359                           l_audit_details(l_audit_cnt).transaction_id :=
1360                                                   l_trans_id_tab(j);
1361                           EXIT;
1362                        -- Is the entry deleted, but still the next transaction is of
1363                        -- a different timecard id ? In that case, we only need to find
1364                        -- out if this belongs to a Deleted Timecard.  If not, we need
1365                        -- to mark it as a delete for next transaction anyway.
1366                        ELSIF (l_trans_date_tab(j) >= l_tc_details(i).date_to)
1367                          AND NOT l_delete_done
1368                         THEN
1369                           l_audit_details.EXTEND(1);
1370                           l_audit_cnt := l_audit_cnt + 1 ;
1371                           copy_timecard_to_audit(l_tc_details(i),
1372                                               l_audit_details(l_audit_cnt));
1373                           l_audit_details(l_audit_cnt).action_date := l_trans_date_tab(j);
1374                           l_audit_details(l_audit_cnt).action_by := l_tc_details(i).last_updated_by_user;
1375                           l_audit_details(l_audit_cnt).action := 'Deleted';
1376                           l_audit_details(l_audit_cnt).action_type := 'ED' ;
1377                           l_audit_details(l_audit_cnt).transaction_id :=
1378                                                   l_trans_id_tab(j);
1379                           EXIT;
1380                       END IF;  -- IF trans_date_tab = tc_details.date_to
1381                    END LOOP;  -- FOR j IN l_trans_id_tab
1382                 END IF;  -- IF tc_details(i).bb_id = tc_details(i+1).bb_id
1383              ELSE -- l_tc_details.EXISTS
1384                 FOR j IN l_trans_date_tab.FIRST..l_trans_date_tab.LAST
1385                 LOOP
1386                    IF l_trans_date_tab(j) >= l_tc_details(i).date_to
1387                    THEN
1388                       l_audit_details.EXTEND(1);
1389                       l_audit_cnt := l_audit_cnt + 1 ;
1390                       copy_timecard_to_audit(l_tc_details(i),
1391                                      l_audit_details(l_audit_cnt));
1392                       l_audit_details(l_audit_cnt).action := 'Deleted';
1393                       l_audit_details(l_audit_cnt).action_type := 'ED' ;
1394                       l_audit_details(l_audit_cnt).action_date := l_trans_date_tab(j);
1395                       l_audit_details(l_audit_cnt).action_by := l_tc_details(i).last_updated_by_user;
1396 
1397                       l_audit_details(l_audit_cnt).transaction_id := l_trans_id_tab(j);
1398                       EXIT;
1399                    END IF;
1400                 END LOOP;
1401              END IF;  -- l_tc_details.EXISTS
1402           END IF; -- IF l_tc_details(i).date_to <> '31-DEC-4712'
1403     END LOOP; -- FOR i IN l_tc_details.FIRST..l_tc_details.LAST
1404 
1405     insert_details;
1406 
1407     END IF;
1408 
1409     l_trans_id_tab.DELETE;
1410     l_trans_date_tab.DELETE;
1411     l_trans_user_tab.DELETE;
1412     l_comments_tab.DELETE;
1413     l_bb_id_tab.DELETE;
1414     l_bb_ovn_tab.DELETE;
1415     l_max_bb_id_tab.DELETE;
1416     l_trans_status_tab.DELETE;
1417 
1418     l_del_bb_id_tab.DELETE;
1419     l_del_bb_ovn_tab.DELETE;
1420     l_del_date_tab.DELETE;
1421     l_del_id_tab.DELETE;
1422 
1423 
1424     l_tc_details.DELETE;
1425     l_audit_details.DELETE;
1426 
1427 
1428   END record_details ;
1429 
1430 
1431 BEGIN -- execute_audit_trail_reporting
1432 
1433 
1434    -- Public Procedure execute_audit_trail_reporting
1435    -- Take all the parameters and initiate request Load Timecard Snapshot
1436    --      passing all the parameters.
1437    -- While waiting for the request, translate all the parameters for display.
1438    -- Wait for the request to complete.
1439    -- Delete from HXC_RPT_TC_AUDIT, just in case last run crashed.
1440    -- Open get_timecards, passing in this request id, and fetch all the timecards.
1441    -- For each timecard,
1442    --    * Record the submissions.
1443    --    * Record approvals
1444    --    * Record deletions
1445    --    * Record details, and changes.
1446    -- Clear HXC_RPT_TC_AUDIT.
1447 
1448 
1449    IF g_debug
1450    THEN
1451       hr_utility.trace('execute_audit_trail_reporting');
1452       hr_utility.trace('Parameters ');
1453       hr_utility.trace('===========');
1454       hr_utility.trace('p_date_from     '||p_date_from);
1455       hr_utility.trace('p_date_to       '||p_date_to);
1456       hr_utility.trace('p_data_regen    '||p_data_regen);
1457       hr_utility.trace('p_record_save   '||p_record_save);
1458       hr_utility.trace('p_org_id        '||p_org_id);
1459       hr_utility.trace('p_locn_id       '||p_locn_id);
1460       hr_utility.trace('p_payroll_id    '||p_payroll_id);
1461       hr_utility.trace('p_supervisor_id '||p_supervisor_id);
1462       hr_utility.trace('p_person_id     '||p_person_id);
1463    END IF;
1464 
1465 
1466    -- Calling Load timecard snapshot passing the required parameters.
1467 
1468    l_data_load_request_id := FND_REQUEST.SUBMIT_REQUEST ( application => 'HXC',
1469                                                          program      => 'HXCRPTTCSN',
1470                                                          description => NULL,
1471                                                          sub_request => FALSE,
1472                                                          argument1   =>   p_date_from     ,
1473                                                          argument2    =>  p_date_to       ,
1474                                                          argument3    =>  p_data_regen    ,
1475                                                          argument4    =>  p_record_save   ,
1476                                                          argument5    =>  p_org_id        ,
1477                                                          argument6    =>  p_locn_id       ,
1478                                                          argument7    =>  p_payroll_id    ,
1479                                                          argument8    =>  p_supervisor_id ,
1480                                                          argument9    =>  p_person_id     );
1481    COMMIT;
1482 
1483    IF l_data_load_request_id = 0
1484    THEN
1485       hr_utility.trace('There was an error in submitting Load Timecard Snapshot ');
1486       hr_utility.trace('Sql Error : '||SQLCODE);
1487    END IF;
1488 
1489 
1490    -- Translate_parameters is to translate the given parameters to the process
1491    -- for display to the user. While the request waits for Load Timecard Snapshot
1492    -- process, translate these parameters. After it is finished, come back and wait
1493    -- for Load timecard Snapshot.
1494 
1495    translate_parameters;
1496 
1497    IF g_debug
1498    THEN
1499       hr_utility.trace('Request went to wait at '||to_char(sysdate,'dd-MON-yyyy HH:MI:SS'));
1500    END IF;
1501 
1502    l_call_status := FND_CONCURRENT.WAIT_FOR_REQUEST( request_id => l_data_load_request_id,
1503                                                      interval   => l_interval,
1504                                                      max_wait    => 0,
1505                                                      phase      => l_phase,
1506                                                      status     => l_status,
1507                                                      dev_phase  => l_dev_phase,
1508                                                      dev_status => l_dev_status,
1509                                                      message    => l_message );
1510 
1511    IF g_debug
1512    THEN
1513       hr_utility.trace('Request stopped at '||to_char(sysdate,'dd-MON-yyyy HH:MI:SS'));
1514    END IF;
1515 
1516    IF l_call_status = FALSE
1517    THEN
1518       IF g_debug
1519       THEN
1520          hr_utility.trace('There was an error in executing Load Timecard Snapshot ');
1521          hr_utility.trace('Sql Error : '||SQLCODE);
1522       END IF;
1523    END IF;
1524 
1525    -- Just in case the previous run crashed, clear the reporting table before you
1526    -- insert anything.
1527 
1528    DELETE FROM hxc_rpt_tc_audit;
1529 
1530    OPEN get_timecards(l_data_load_request_id);
1531    LOOP
1532       FETCH get_timecards INTO l_resource_id,
1533                                l_start_time,
1534                                l_stop_time ;
1535       EXIT WHEN get_timecards%NOTFOUND;
1536 
1537       IF g_debug
1538       THEN
1539          hr_utility.trace('Fetched from get_timecards ');
1540          hr_utility.trace('Resource id   : '||l_resource_id);
1541          hr_utility.trace('TC start time : '||l_start_time);
1542          hr_utility.trace('TC stop time  : '||l_stop_time);
1543       END IF;
1544 
1545       IF l_resource_count = 100
1546       THEN
1547          COMMIT;
1548          l_resource_count := 1;
1549       ELSE
1550          l_resource_count := l_resource_count + 1;
1551       END IF;
1552 
1553       -- Bug 9137834
1554       -- Added the exception block
1555       BEGIN
1556           record_submissions(l_resource_id,
1557       	                     l_start_time,
1558       	                     l_stop_time,
1559       	                     p_record_save);
1560 
1561 
1562       	  record_approvals (l_resource_id,
1563       	                    l_start_time,
1564       	                    l_stop_time );
1565 
1566 
1567       	  record_deletions(l_resource_id,
1568       	                   l_start_time,
1569       	                   l_stop_time );
1570 
1571       	  record_details(l_resource_id,
1572       	                 l_start_time,
1573       	                 l_stop_time,
1574       	                 p_record_save );
1575        EXCEPTION
1576                WHEN OTHERS THEN
1577                    hr_utility.trace('Error stack ');
1578                    hr_utility.trace(DBMS_UTILITY.FORMAT_ERROR_BACKTRACE);
1579                    hr_utility.trace(' Exception '||SQLERRM||' while processing the following timecard ');
1580                    hr_utility.trace(' Resource_id '||l_resource_id);
1581                    hr_utility.trace(' Start_time  '||l_start_time);
1582                    hr_utility.trace(' Stop_time  '||l_stop_time);
1583 
1584       END;
1585 
1586    END LOOP;
1587    CLOSE get_timecards;
1588    COMMIT;
1589    IF g_debug
1590    THEN
1591       hr_utility.trace('Completed Audit Trail Reporting normally ');
1592       hr_utility.trace('Finished processing at '||TO_CHAR(SYSDATE,'dd-MON-yyyy HH:MI:SS'));
1593    END IF;
1594 
1595 EXCEPTION
1596       WHEN NO_DATA_FOUND THEN
1597          hr_utility.trace('No Data Found from execute_audit_trail_reporting ');
1598 
1599 END execute_audit_trail_reporting;
1600 
1601 
1602 
1603 
1604 END HXC_RPT_TC_AUDIT_TRAIL;
1605