DBA Data[Home] [Help]

PACKAGE BODY: APPS.PQP_SERVICE_HISTORY_CALC_PKG

Source


1 Package Body pqp_service_history_calc_pkg as
2 /* $Header: pqshpcal.pkb 120.0 2005/05/29 02:11:33 appldev noship $ */
3 --
4 -- ----------------------------------------------------------------------------
5 -- |-------------------------< calculate_period >-----------------------------|
6 -- ----------------------------------------------------------------------------
7 PROCEDURE calculate_period (p_start_date in     date
8                            ,p_end_date   in     date
9                            ,p_days          out nocopy number
10                            ) IS
11   --
12   -- Calculate the number of days for given dates
13   --
14   l_proc       VARCHAR2(60) := 'pqp_service_history_calc_pkg.calculate_period';
15   l_start_date DATE         := trunc(p_start_date);
16   l_end_date   DATE         := trunc(p_end_date);
17   l_days       NUMBER(12);
18   --
19 BEGIN
20   hr_utility.set_location('Entering: '||l_proc, 10);
21   --
22   SELECT l_end_date - l_start_date
23   INTO   l_days
24   FROM   dual;
25   --
26   l_days := l_days + 1;
27   p_days := l_days;
28   --
29   hr_utility.set_location('Leaving: '||l_proc, 20);
30 
31 
32 -- Added by tmehra for nocopy changes Feb'03
33 
34 EXCEPTION
35     WHEN OTHERS THEN
36        hr_utility.set_location('Entering excep:'||l_proc, 35);
37        p_days := 0;
38        raise;
39 
40   --
41 END calculate_period;
42 --
43 -- ----------------------------------------------------------------------------
44 -- |---------------------< calculate_current_service >------------------------|
45 -- ----------------------------------------------------------------------------
46 --
47 FUNCTION calculate_current_service (p_calculation_date   in     date
48                                    ,p_assignment_id      in     number
49                                    ,p_continuous_service in     varchar2
50                                    ) RETURN number IS
51   --
52   -- Calculate the current service period for a given assignment
53   --
54   CURSOR c_curr_serv IS
55   SELECT pps.date_start
56   FROM   per_periods_of_service pps
57         ,per_all_assignments_f  asg
58   WHERE  pps.period_of_service_id = asg.period_of_service_id
59     AND  trunc(p_calculation_date) BETWEEN trunc(asg.effective_start_date)
60                                                          AND trunc(asg.effective_end_date)
61     AND  asg.assignment_id  = p_assignment_id
62     AND  not exists (SELECT 1 FROM pqp_service_history_periods shp
63                      WHERE  trunc(pps.date_start) BETWEEN trunc(shp.start_date)
64                                                       AND trunc(shp.end_date)
65                        AND  shp.assignment_id      = p_assignment_id
66                        AND  shp.continuous_service = NVL(p_continuous_service, shp.continuous_service));
67   --
68   l_func       VARCHAR2(60) := 'pqp_service_history_calc_pkg.calculate_current_service';
69   l_days       NUMBER(12) := 0 ;
70   --
71 BEGIN
72   hr_utility.set_location('Entering: '||l_func, 10);
73   --
74   FOR c_curr_serv_rec IN c_curr_serv LOOP
75       --
76       -- Calculate the service period
77       --
78       calculate_period (p_start_date => c_curr_serv_rec.date_start
79                        ,p_end_date   => p_calculation_date
80                        ,p_days       => l_days
81                        );
82       --
83       hr_utility.set_location(l_func, 20);
84   END LOOP;
85   --
86   return l_days;
87   --
88   hr_utility.set_location('Leaving: '||l_func, 30);
89   --
90 END calculate_current_service;
91 --
92 -- ----------------------------------------------------------------------------
93 -- |-----------------------< convert_years_to_days >--------------------------|
94 -- ----------------------------------------------------------------------------
95 --
96 PROCEDURE convert_years_to_days (p_start_date    in     date
97                                 ,p_period_years  in     number
98                                 ,p_days             out nocopy number) IS
99   --
100   l_proc       VARCHAR2(60) := 'pqp_service_history_calc_pkg.convert_years_to_days';
101   l_days       NUMBER(12) := 0 ;
102   l_end_date   DATE;
103   --
104 BEGIN
105   --
106   hr_utility.set_location('Entering: '||l_proc, 10);
107   --
108   SELECT ADD_MONTHS(p_start_date,(p_period_years * 12))
109   INTO l_end_date
110   FROM dual;
111 
112   hr_utility.set_location(l_proc, 20);
113   SELECT l_end_date - p_start_date
114   INTO l_days
115   FROM dual;
116 
117   p_days := l_days;
118 
119   hr_utility.set_location('Leaving: '||l_proc, 30);
120   --
121 END convert_years_to_days;
122 --
123 -- ----------------------------------------------------------------------------
124 -- |-----------------------< check_overlap_curr_serv >------------------------|
125 -- ----------------------------------------------------------------------------
126 --
127 PROCEDURE check_overlap_curr_serv (p_start_date       in     date
128                                   ,p_end_date         in     date
129                                   ,p_period_years     in     number
130                                   ,p_period_days      in     number
131                                   ,p_assignment_id    in     number
132                                   ,p_calculation_date in     date
133                                   ,p_days                out nocopy number) IS
134 
135   --
136   -- Check whether this service history period overlaps
137   -- with the current service period
138   --
139   CURSOR c_overlap_serv2 IS
140   SELECT NULL
141   FROM   per_periods_of_service pps
142         ,per_all_assignments_f  asg
143   WHERE  pps.period_of_service_id = asg.period_of_service_id
144     AND  trunc(pps.date_start) between trunc(p_start_date)
145                                    and trunc(p_end_date)
146     AND  trunc(p_calculation_date) between trunc(asg.effective_start_date)
147                                        and trunc(asg.effective_end_date)
148     AND  asg.assignment_id = p_assignment_id ;
149   --
150   l_proc       VARCHAR2(60) := 'pqp_service_history_calc_pkg.check_overlap_curr_serv';
151   l_days       NUMBER(12) := 0 ;
152   l_exists     VARCHAR2(1);
153   --
154 BEGIN
155   hr_utility.set_location('Entering: '||l_proc, 10);
156   --
157   OPEN c_overlap_serv2;
158   FETCH c_overlap_serv2 INTO l_exists;
159   hr_utility.set_location (l_proc, 20);
160   If c_overlap_serv2%FOUND THEN
161 
162      --
163      -- Reset the end_date to calculation_date
164      -- Calculate the service period
165      --
166      calculate_period (p_start_date => p_start_date
167                       ,p_end_date   => p_calculation_date
168                       ,p_days       => l_days
169                       );
170   Else
171      --
172      -- Pass the end date value
173      -- Calculate the service period
174      --
175      -- Check period years or period days have a value
176      -- PS Bug 2028104 for details
177      --
178 
179      If p_period_years Is Null And
180         p_period_days  Is Null Then
181 
182         calculate_period (p_start_date => p_start_date
183                          ,p_end_date   => p_end_date
184                          ,p_days       => l_days
185                          );
186 
187      Else
188 
189         -- The following conversion of years to days
190         -- is incorrect as 365 days for a year will be incorrect
191         -- for leap years
192         -- See Bug 4318334 for details
193 
194         -- l_days := nvl(p_period_years,0) * 365;
195         l_days := 0;
196         IF NVL(p_period_years, 0) <> 0 THEN
197           hr_utility.set_location(l_proc, 25);
198           convert_years_to_days (p_start_date   => p_start_date
199                                 ,p_period_years => p_period_years
200                                 ,p_days         => l_days
201                                 );
202         END IF; -- End if of period years is not zero...
203         l_days := l_days + nvl(p_period_days,0);
204 
205 
206      End If; -- End of of period check...
207 
208   End If;
209   CLOSE c_overlap_serv2;
210   --
211   p_days := l_days;
212   hr_utility.set_location('Leaving: '||l_proc, 30);
213   --
214 
215 -- Added by tmehra for nocopy changes Feb'03
216 
217 EXCEPTION
218     WHEN OTHERS THEN
219        hr_utility.set_location('Entering excep:'||l_proc, 35);
220        p_days := 0;
221        raise;
222 
223 END check_overlap_curr_serv;
224 --
225 -- ----------------------------------------------------------------------------
226 -- |-----------------------< calculate_service_history >----------------------|
227 -- ----------------------------------------------------------------------------
228 --
229 FUNCTION calculate_service_history (p_assignment_id    in number
230                                    ,p_calculation_date in date
231                                    ) RETURN number IS
232   --
233   -- This function should query back every period of service for the given
234   -- assignment, and add them together, finally adding on the length of the
235   -- current period of service, up to and including p_calculation_date.
236   -- The result should be returned in days.
237   --
238   -- Select years and days as we need not calculate period if they have a value
239   -- PS bug # for details
240   --
241   CURSOR c_serv_hist IS
242   SELECT start_date
243         ,LEAST(trunc(end_date), trunc(p_calculation_date)) end_date
244         ,DECODE(LEAST(trunc(end_date), trunc(p_calculation_date)), trunc(end_date),
245                                       period_years, NULL) period_years
246         ,DECODE(LEAST(trunc(end_date), trunc(p_calculation_date)), trunc(end_date),
247                                       period_days, NULL) period_days
248   FROM   pqp_service_history_periods shp1
249   WHERE  shp1.assignment_id      = p_assignment_id
250     AND  trunc(shp1.start_date) <= trunc(p_calculation_date)
251     AND  not exists (SELECT 1 FROM pqp_service_history_periods shp2
252                      WHERE  shp2.assignment_id              = shp1.assignment_id
253                        AND  shp2.service_history_period_id <> shp1.service_history_period_id
254                        AND  (trunc(shp2.start_date) between trunc(shp1.start_date)
255                                                                  and trunc(shp1.end_date)
256                              or trunc(shp2.end_date) between trunc(shp1.start_date)
257                                                                   and trunc(shp1.end_date)
258                              or trunc(shp1.start_date) between trunc(shp2.start_date)
259                                                                  and trunc(shp2.end_date)
260                              or trunc(shp1.end_date) between trunc(shp2.start_date)
261                                                                   and trunc(shp2.end_date)));
262   --
263   CURSOR c_overlap_serv IS
264   SELECT MIN(shp1.start_date) start_date
265         ,LEAST(trunc(MAX(shp1.end_date)),trunc(p_calculation_date)) end_date
266   FROM   pqp_service_history_periods shp1
267   WHERE  shp1.assignment_id      = p_assignment_id
268     AND  trunc(shp1.start_date) <= trunc(p_calculation_date)
269     AND  exists (SELECT 1 FROM pqp_service_history_periods shp2
270                      WHERE  shp2.assignment_id              = shp1.assignment_id
271                        AND  shp2.service_history_period_id <> shp1.service_history_period_id
272                        AND  (trunc(shp2.start_date) between trunc(shp1.start_date)
273                                                                  and trunc(shp1.end_date)
274                              or trunc(shp2.end_date) between trunc(shp1.start_date)
275                                                                   and trunc(shp1.end_date)
276                              or trunc(shp1.start_date) between trunc(shp2.start_date)
277                                                                  and trunc(shp2.end_date)
278                              or trunc(shp1.end_date) between trunc(shp2.start_date)
279                                                                   and trunc(shp2.end_date)));
280   --
281   l_func     VARCHAR2(60) := 'pqp_service_history_calc_pkg.calculate_service_history';
282   l_days     NUMBER(12);
283   l_tot_days NUMBER(12)   := 0;
284   --
285 BEGIN
286   hr_utility.set_location('Entering: '||l_func, 10);
287   --
288   FOR c_serv_hist_rec in c_serv_hist LOOP
289 
290      If c_serv_hist_rec.start_date IS NOT NULL And
291         c_serv_hist_rec.end_date   IS NOT NULL Then
292         --
293         -- Before calculating check whether this date
294         -- overlaps with current service period
295         --
296         hr_utility.set_location(l_func, 20);
297         check_overlap_curr_serv (p_start_date       => c_serv_hist_rec.start_date
298                                 ,p_end_date         => c_serv_hist_rec.end_date
299                                 ,p_period_years     => c_serv_hist_rec.period_years
300                                 ,p_period_days      => c_serv_hist_rec.period_days
301                                 ,p_assignment_id    => p_assignment_id
302                                 ,p_calculation_date => p_calculation_date
303                                 ,p_days             => l_days
304                                 );
305         --
306         l_tot_days := l_tot_days + l_days;
307         --
308      End If;
309      --
310      hr_utility.set_location(l_func, 30);
311   END LOOP;
312   --
313   FOR c_overlap_rec IN c_overlap_serv LOOP
314       If c_overlap_rec.start_date IS NOT NULL And
315          c_overlap_rec.end_date   IS NOT NULL Then
316          --
317          -- Before calculating check whether this date
318          -- overlaps with current service period
319          --
320          hr_utility.set_location(l_func, 40);
321          check_overlap_curr_serv (p_start_date       => c_overlap_rec.start_date
322                                  ,p_end_date         => c_overlap_rec.end_date
323                                  ,p_period_years     => NULL
324                                  ,p_period_days      => NULL
325                                  ,p_assignment_id    => p_assignment_id
326                                  ,p_calculation_date => p_calculation_date
327                                  ,p_days             => l_days
328                                  );
329          --
330          l_tot_days := l_tot_days + l_days;
331          --
332       End If;
333       --
334       hr_utility.set_location(l_func, 50);
335   END LOOP;
336   --
337   --
338   -- Calculate the current service period
339   --
340   l_days := calculate_current_service (p_calculation_date   => p_calculation_date
341                                       ,p_assignment_id      => p_assignment_id
342                                       ,p_continuous_service => NULL
343                                       );
344   l_tot_days := l_tot_days + l_days;
345   --
346   hr_utility.set_location(l_func, 60);
347   --
348   return l_tot_days;
349   --
350   hr_utility.set_location('Leaving: '||l_func, 70);
351   --
352 END calculate_service_history;
353 --
354 -- Added this new function
355 -- PS Bug 2028104 for details
356 -- ----------------------------------------------------------------------------
357 -- |-----------------------< calculate_all_service_history >----------------------|
358 -- ----------------------------------------------------------------------------
359 --
360 FUNCTION calculate_all_service_history (p_assignment_id    in number
361                                        ) RETURN number IS
362   --
363   -- This function should query back every period of service for the given
364   -- assignment, and add them together, finally adding on the length of the
365   -- current period of service
366   -- The result should be returned in days.
367   --
368 
369   CURSOR c_all_serv_hist IS
370   SELECT start_date
371         ,end_date
372         ,period_years
376   --
373         ,period_days
374   FROM pqp_service_history_periods shp1
375   WHERE  shp1.assignment_id = p_assignment_id;
377   l_func     VARCHAR2(80) := 'pqp_service_history_calc_pkg.calculate_all_service_history';
378   l_days     NUMBER(12);
379   l_tot_days NUMBER(12)   := 0;
380   --
381 BEGIN
382   hr_utility.set_location('Entering: '||l_func, 10);
383   --
384   FOR c_all_serv_hist_rec in c_all_serv_hist LOOP
385 
386       --
387       -- Calculate period if period_years and period_days do not have values
388       --
389       hr_utility.set_location(l_func, 20);
390 
391       If c_all_serv_hist_rec.period_years Is Null And
392          c_all_serv_hist_rec.period_days Is Null Then
393 
394          calculate_period (p_start_date => c_all_serv_hist_rec.start_date
395                           ,p_end_date   => c_all_serv_hist_rec.end_date
396                           ,p_days       => l_days
397                           );
398 
399       Else
400 
401         -- The following conversion of years to days
402         -- is incorrect as 365 days for a year will be incorrect
403         -- for leap years
404         -- See Bug 4318334 for details
405 
406         -- l_days := nvl(c_all_serv_hist_rec.period_years,0) * 365;;
407         l_days := 0;
408         IF NVL(c_all_serv_hist_rec.period_years, 0) <> 0 THEN
409           hr_utility.set_location(l_func, 25);
410           convert_years_to_days (p_start_date   => c_all_serv_hist_rec.start_date
411                                 ,p_period_years => c_all_serv_hist_rec.period_years
412                                 ,p_days         => l_days
413                                 );
414         END IF; -- End if of period years is not zero...
415         l_days := l_days + nvl(c_all_serv_hist_rec.period_days,0);
416 
417       End If; -- End if of period check...
418 
419       --
420       l_tot_days := l_tot_days + l_days;
421       --
422 
423   END LOOP;
424 
425   --
426   hr_utility.set_location(l_func, 30);
427   --
428   return l_tot_days;
429   --
430   hr_utility.set_location('Leaving: '||l_func, 40);
431   --
432 END calculate_all_service_history;
433 --
434 -- ----------------------------------------------------------------------------
435 -- |---------------------< calculate_continuous_service >---------------------|
436 -- ----------------------------------------------------------------------------
437 FUNCTION calculate_continuous_service (p_assignment_id    in number
438                                       ,p_calculation_date in date
439                                       ) RETURN number IS
440   --
441   -- This function should query back every period of service for the given
442   -- assignment, where the continuous service flag has been checked, and add
443   -- them together, finally adding on the length of the current period of
444   -- service, up to and including p_calculation_date.
445   -- The result should be returned in days.
446   --
447   -- Select years and days as we need not calculate period if they have a value
448   -- PS bug # for details
449   --
450 
451   CURSOR c_cont_serv IS
452   SELECT start_date
453         ,LEAST(trunc(end_date), trunc(p_calculation_date)) end_date
454         ,DECODE(LEAST(trunc(end_date), trunc(p_calculation_date)), trunc(end_date),
455                                       period_years, NULL) period_years
456         ,DECODE(LEAST(trunc(end_date), trunc(p_calculation_date)), trunc(end_date),
457                                       period_days, NULL) period_days
458   FROM   pqp_service_history_periods shp1
459   WHERE  shp1.assignment_id      = p_assignment_id
460     AND  trunc(shp1.start_date) <= trunc(p_calculation_date)
461     AND  shp1.continuous_service = 'Y'
462     AND  not exists (SELECT 1 FROM pqp_service_history_periods shp2
463                      WHERE  shp2.assignment_id              = shp1.assignment_id
464                        AND  shp2.continuous_service         = 'Y'
465                        AND  shp2.service_history_period_id <> shp1.service_history_period_id
466                        AND  (trunc(shp2.start_date) between trunc(shp1.start_date)
467                                                                  and trunc(shp1.end_date)
468                              or trunc(shp2.end_date) between trunc(shp1.start_date)
469                                                                   and trunc(shp1.end_date)
470                              or trunc(shp1.start_date) between trunc(shp2.start_date)
471                                                                  and trunc(shp2.end_date)
472                              or trunc(shp1.end_date) between trunc(shp2.start_date)
473                                                                   and trunc(shp2.end_date)));
474   --
475   CURSOR c_cont_overlap_serv IS
476   SELECT MIN(shp1.start_date) start_date
477         ,LEAST(trunc(MAX(shp1.end_date)), trunc(p_calculation_date)) end_date
478   FROM   pqp_service_history_periods shp1
479   WHERE  shp1.assignment_id      = p_assignment_id
480     AND  trunc(shp1.start_date) <= trunc(p_calculation_date)
481     AND  shp1.continuous_service = 'Y'
482     AND  exists (SELECT 1 FROM pqp_service_history_periods shp2
483                      WHERE  shp2.assignment_id              = shp1.assignment_id
484                        AND  shp2.continuous_service         = 'Y'
485                        AND  shp2.service_history_period_id <> shp1.service_history_period_id
489                                                                   and trunc(shp1.end_date)
486                        AND  (trunc(shp2.start_date) between trunc(shp1.start_date)
487                                                                  and trunc(shp1.end_date)
488                              or trunc(shp2.end_date) between trunc(shp1.start_date)
490                              or trunc(shp1.start_date) between trunc(shp2.start_date)
491                                                                  and trunc(shp2.end_date)
492                              or trunc(shp1.end_date) between trunc(shp2.start_date)
493                                                                   and trunc(shp2.end_date)));
494   --
495   l_func     VARCHAR2(60) := 'pqp_service_history_calc_pkg.calculate_continuous_service';
496   l_days     NUMBER(12);
497   l_tot_days NUMBER(12)   := 0;
498   --
499 BEGIN
500   hr_utility.set_location('Entering: '||l_func, 10);
501   --
502   FOR c_cont_serv_rec IN c_cont_serv LOOP
503       If c_cont_serv_rec.start_date IS NOT NULL And
504          c_cont_serv_rec.end_date   IS NOT NULL Then
505          --
506          -- Before calculating check whether this date
507          -- overlaps with current service period
508          --
509          hr_utility.set_location(l_func, 20);
510          check_overlap_curr_serv (p_start_date       => c_cont_serv_rec.start_date
511                                  ,p_end_date         => c_cont_serv_rec.end_date
512                                  ,p_period_years     => c_cont_serv_rec.period_years
513                                  ,p_period_days      => c_cont_serv_rec.period_days
514                                  ,p_assignment_id    => p_assignment_id
515                                  ,p_calculation_date => p_calculation_date
516                                  ,p_days             => l_days
517                                  );
518          --
519          l_tot_days := l_tot_days + l_days;
520          --
521       End If;
522   END LOOP;
523   hr_utility.set_location(l_func, 30);
524   --
525   FOR c_cont_overlap_rec IN c_cont_overlap_serv LOOP
526       If c_cont_overlap_rec.start_date IS NOT NULL And
527          c_cont_overlap_rec.end_date   IS NOT NULL Then
528          --
529          -- Before calculating check whether this date
530          -- overlaps with current service period
531          --
532          hr_utility.set_location(l_func, 40);
533          check_overlap_curr_serv (p_start_date       => c_cont_overlap_rec.start_date
534                                  ,p_end_date         => c_cont_overlap_rec.end_date
535                                  ,p_period_years     => NULL
536                                  ,p_period_days      => NULL
537                                  ,p_assignment_id    => p_assignment_id
538                                  ,p_calculation_date => p_calculation_date
539                                  ,p_days             => l_days
540                                  );
541          --
542          l_tot_days := l_tot_days + l_days;
543          --
544       End If;
545   END LOOP;
546   hr_utility.set_location(l_func, 50);
547   --
548   -- Calculate the current service period
549   --
550   l_days := calculate_current_service (p_calculation_date   => p_calculation_date
551                                       ,p_assignment_id      => p_assignment_id
552                                       ,p_continuous_service => 'Y'
553                                       );
554   l_tot_days := l_tot_days + l_days;
555   --
556   hr_utility.set_location(l_func, 60);
557   --
558   return l_tot_days;
559   --
560   hr_utility.set_location('Leaving: '||l_func, 70);
561   --
562 END calculate_continuous_service;
563 --
564 -- Added this new function
565 -- PS Bug 2028104 for details
566 -- ----------------------------------------------------------------------------
567 -- |-----------------------< calculate_all_continuous_serv >------------------|
568 -- ----------------------------------------------------------------------------
569 --
570 FUNCTION calculate_all_continuous_serv (p_assignment_id    in number
571                                        ) RETURN number IS
572   --
573   -- This function should query back every period of service that is continuous for the given
574   -- assignment, and add them together, finally adding on the length of the
575   -- current period of service
576   -- The result should be returned in days.
577   --
578 
579   CURSOR c_all_cont_serv IS
580   SELECT start_date
581         ,end_date
582         ,period_years
583         ,period_days
584   FROM pqp_service_history_periods shp1
585   WHERE  shp1.assignment_id      = p_assignment_id
586     AND  shp1.continuous_service = 'Y';
587   --
588   l_func     VARCHAR2(80) := 'pqp_service_history_calc_pkg.calculate_all_continuous_serv';
589   l_days     NUMBER(12);
590   l_tot_days NUMBER(12)   := 0;
591   --
592 BEGIN
593   hr_utility.set_location('Entering: '||l_func, 10);
594   --
595   FOR c_all_cont_serv_rec in c_all_cont_serv LOOP
596 
597       --
598       -- Calculate period if period_years and period_days do not have values
599       --
600       hr_utility.set_location(l_func, 20);
601 
602       If c_all_cont_serv_rec.period_years Is Null And
603          c_all_cont_serv_rec.period_days Is Null Then
604 
608                           );
605          calculate_period (p_start_date => c_all_cont_serv_rec.start_date
606                           ,p_end_date   => c_all_cont_serv_rec.end_date
607                           ,p_days       => l_days
609 
610       Else
611 
612         -- The following conversion of years to days
613         -- is incorrect as 365 days for a year will be incorrect
614         -- for leap years
615         -- See Bug 4318334 for details
616 
617         -- l_days := nvl(c_all_cont_serv_rec.period_years,0) * 365;
618         l_days := 0;
619         IF NVL(c_all_cont_serv_rec.period_years, 0) <> 0 THEN
620           hr_utility.set_location(l_func, 25);
621           convert_years_to_days (p_start_date   => c_all_cont_serv_rec.start_date
622                                 ,p_period_years => c_all_cont_serv_rec.period_years
623                                 ,p_days         => l_days
624                                 );
625         END IF; -- End if of period years is not zero...
626         l_days := l_days + nvl(c_all_cont_serv_rec.period_days,0);
627 
628       End If; -- End if of period check...
629 
630       --
631       l_tot_days := l_tot_days + l_days;
632       --
633 
634   END LOOP;
635 
636   --
637   hr_utility.set_location(l_func, 30);
638   --
639   return l_tot_days;
640   --
641   hr_utility.set_location('Leaving: '||l_func, 40);
642   --
643 END calculate_all_continuous_serv;
644 --
645 -- ----------------------------------------------------------------------------
646 -- |-------------------< calculate_service_hist_period >----------------------|
647 -- ----------------------------------------------------------------------------
648 PROCEDURE calculate_service_hist_period (p_start_date in     date
649                                         ,p_end_date   in     date
650                                         ,p_years         out nocopy number
651                                         ,p_days          out nocopy number
652                                         ) IS
653   --
654   -- This procedure should calculate the duration of a particular period of
655   -- service history.
656   -- The result should be returned in years and days.
657   --
658   l_proc           VARCHAR2(60) := 'pqp_service_history_calc_pkg.calculate_service_hist_period';
659   l_start_date     DATE         := trunc(p_start_date);
660   l_new_start_date DATE;
661   -- include the end date so set the date to +1
662   l_end_date       DATE         := trunc(p_end_date) + 1;
663   l_tot_days       NUMBER(12);
664   l_years          NUMBER(12);
665   l_days           NUMBER(12);
666 --
667 BEGIN
668   hr_utility.set_location('Entering: '||l_proc, 10);
669   --
670   SELECT (l_end_date - l_start_date)
671   INTO   l_tot_days
672   FROM   dual;
673   --
674   hr_utility.set_location(l_proc, 30);
675   --
676   -- The following conversion of days to years
677   -- is incorrect as 365 days for a year will be incorrect
678   -- for leap years
679   -- See Bug 4318334 for details
680 
681   -- l_years := trunc(l_tot_days/365);
682   --
683   -- hr_utility.set_location(l_proc, 40);
684   --
685 
686 --   SELECT MOD(l_tot_days,365)
687 --   INTO   l_days
688 --   FROM   dual;
689 --
690 --   l_days  := l_days + 1 ;
691 --   --
692 --   IF l_days = 365 THEN
693 --      l_days  := 0;
694 --      l_years := l_years + 1;
695 --   END IF;
696 
697   -- Get the number of years based on date using MONTHS_BETWEEN function
698   SELECT TRUNC(MONTHS_BETWEEN(l_end_date, l_start_date)/12)
699   INTO l_years
700   FROM dual;
701 
702   -- Get the new start date based on the l_years figure from the start date
703 
704   hr_utility.set_location(l_proc, 40);
705   SELECT ADD_MONTHS(l_start_date, l_years * 12)
706   INTO l_new_start_date
707   FROM dual;
708 
709   -- Get the number of days based on this new start date
710 
711   hr_utility.set_location(l_proc, 50);
712   SELECT l_end_date - l_new_start_date
713   INTO l_days
714   FROM dual;
715 
716 
717   --
718   p_years := l_years;
719   p_days  := l_days;
720   --
721   hr_utility.set_location('Leaving: '||l_proc, 60);
722   --
723 
724 -- Added by tmehra for nocopy changes Feb'03
725 
726 EXCEPTION
727     WHEN OTHERS THEN
728        hr_utility.set_location('Entering excep:'||l_proc, 35);
729        p_years := 0;
730        p_days  := 0;
731        raise;
732 
733 
734 END calculate_service_hist_period;
735 --
736 END pqp_service_history_calc_pkg;