DBA Data[Home] [Help]

PACKAGE BODY: APPS.HRI_OLTP_DISC_WRKFRC

Source


1 PACKAGE BODY hri_oltp_disc_wrkfrc AS
2 /* $Header: hriodwrk.pkb 115.4 2003/08/04 04:58:59 cbridge noship $ */
3 
4 ---------------------------
5 -- Package global variables
6 ---------------------------
7 /* Values for last calc_abv lookup call */
8 g_bmt_code     VARCHAR2(30);
9 g_bmt_meaning  VARCHAR2(80);
10 
11 g_last_bg_id			per_business_groups.business_group_id%type;
12 g_last_formula_id		ff_formulas_f.formula_id%type;
13 g_last_formula_name		ff_formulas_f.formula_name%type;
14 
15 /* Holds value passed to Discoverer when fast formulas do not exist */
16 g_no_valid_formula		number := to_number(null);
17 /* Holds value passed to Discoverer when fast formulas do not exist or are not compiled */
18 g_no_valid_formula_id		number := to_number(null);
19 
20 
21 /******************************************************************************/
22 /* Public function to determine the Id of a FastFormula                       */
23 /******************************************************************************/
24 FUNCTION get_formula_id(p_business_group_id    IN NUMBER
25                        ,p_formula_name         IN VARCHAR2)
26              RETURN NUMBER IS
27 
28   l_formula_id       ff_formulas_f.formula_id%type := 0;
29 
30   CURSOR customer_formula_csr IS
31   SELECT formula_id
32   FROM ff_formulas_x
33   WHERE formula_name = 'BUDGET_' || p_formula_name
34   AND business_group_id = p_business_group_id;
35 
36   CURSOR template_formula_csr IS
37   SELECT formula_id
38   FROM ff_formulas_x
39   WHERE formula_name = 'TEMPLATE_' || p_formula_name
40   AND business_group_id IS NULL;
41 
42 BEGIN
43 
44   IF (p_formula_name IS NULL) OR (p_business_group_id IS NULL) THEN
45 /* Fast formula depends upon business group and formula name */
46     RETURN(0);
47   ELSE
48 
49     IF (p_formula_name = g_last_formula_name) AND
50        (p_business_group_id = g_last_bg_id) THEN
51       RETURN(g_last_formula_id);
52     ELSE
53       OPEN customer_formula_csr;
54       FETCH customer_formula_csr INTO l_formula_id;
55       IF customer_formula_csr%FOUND THEN
56         CLOSE customer_formula_csr;
57         g_last_formula_name := p_formula_name;
58         g_last_bg_id := p_business_group_id;
59         g_last_formula_id := l_formula_id;
60         RETURN(l_formula_id);
61       ELSE
62         CLOSE customer_formula_csr;
63         OPEN template_formula_csr;
64         FETCH template_formula_csr INTO l_formula_id;
65         CLOSE template_formula_csr;
66         g_last_formula_name := p_formula_name;
67         g_last_bg_id := p_business_group_id;
68         g_last_formula_id := l_formula_id;
69         RETURN(l_formula_id);
70       END IF;
71     END IF;
72   END IF;
73 
74 EXCEPTION
75   WHEN OTHERS THEN
76 
77   RETURN(0);
78 
79 END get_formula_id;
80 
81 
82 /******************************************************************************/
83 /* Public function to determine the appropriate FastFormula Id to be used for */
84 /* calculating manpower actuals                                               */
85 /******************************************************************************/
86 FUNCTION get_manpower_formula_id(p_business_group_id       IN NUMBER
87                                 ,p_budget_measurement_code IN VARCHAR2)
88               RETURN NUMBER IS
89 
90   l_return_value     NUMBER;
91 
92 BEGIN
93 
94   l_return_value := get_formula_id
95                        (p_business_group_id => p_business_group_id,
96                         p_formula_name => p_budget_measurement_code);
97 
98   IF (l_return_value = 0) THEN
99     RETURN (g_no_valid_formula_id);
100   ELSE
101     RETURN l_return_value;
102   END IF;
103 
104 END get_manpower_formula_id;
105 
106 /******************************************************************************/
107 /* Public function to calculate manpower actuals for a single assignment      */
108 /******************************************************************************/
109 FUNCTION get_ff_actual_value(p_budget_id         IN NUMBER
110                             ,p_formula_id        IN NUMBER
111                             ,p_grade_id          IN NUMBER DEFAULT NULL
112                             ,p_job_id            IN NUMBER DEFAULT NULL
113                             ,p_organization_id   IN NUMBER DEFAULT NULL
114                             ,p_position_id       IN NUMBER DEFAULT NULL
115                             ,p_time_period_id    IN NUMBER)
116              RETURN NUMBER IS
117 
118   CURSOR budget_csr IS
119   SELECT
120    b.unit
121   ,b.business_group_id
122   FROM per_budgets   b
123   WHERE b.budget_id = p_budget_id;
124 
125   CURSOR time_period_csr IS
126   SELECT tp.end_date
127   FROM per_time_periods    tp
128   WHERE tp.time_period_id	= p_time_period_id;
129 
130 /* 115.22 - replaced NVL logic with ORs */
131 /*----------------------------------------------------------------------------*/
132 /* Bug 2483207 - To fix high cost SQL it was necessary to split out the one   */
133 /* main cursor into five cursors. Depending on the values of the parameters   */
134 /* passed in a different cursor is used. The most selective parameter to use  */
135 /* is p_position_id, so this is checked first, followed by grade, job and     */
136 /* organization. If all parameters are null, then business group id is used.  */
137 /* Note that the option of using this index is disabled in the former four    */
138 /* cursors. This is to prevent an inefficient query plan being used.          */
139 /*----------------------------------------------------------------------------*/
140 /* To be accessed if p_position_id is not null */
141   CURSOR pos_assignment_csr(
142          p_business_group_id	NUMBER
143         ,p_grade_id		NUMBER
144         ,p_job_id		NUMBER
145         ,p_organization_id	NUMBER
146         ,p_position_id		NUMBER
147         ,p_period_end_date	DATE) is
148   SELECT asg.assignment_id
149   FROM  per_assignments_f    asg
150        ,per_assignment_status_types   ast
151   WHERE p_position_id = asg.position_id
152   AND (p_organization_id IS NULL OR asg.organization_id = p_organization_id)
153   AND (p_job_id IS NULL OR asg.job_id = p_job_id)
154   AND (p_grade_id IS NULL OR asg.grade_id = p_grade_id)
155   AND asg.business_group_id + 0 = p_business_group_id
156   AND asg.assignment_type = 'E'
157   AND p_period_end_date BETWEEN asg.effective_start_date
158                             AND asg.effective_end_date
159   AND asg.assignment_status_type_id = ast.assignment_status_type_id
160   AND ast.per_system_status = 'ACTIVE_ASSIGN';
161 
162 /* If p_position_id is null, then use this if p_grade_id is not null */
163   CURSOR grd_assignment_csr(
164          p_business_group_id	NUMBER
165         ,p_grade_id		NUMBER
166         ,p_job_id		NUMBER
167         ,p_organization_id	NUMBER
168         ,p_period_end_date	DATE) is
169   SELECT asg.assignment_id
170   FROM  per_assignments_f    asg
171        ,per_assignment_status_types   ast
172   WHERE (p_organization_id IS NULL OR asg.organization_id = p_organization_id)
173   AND (p_job_id IS NULL OR asg.job_id = p_job_id)
174   AND p_grade_id = asg.grade_id
175   AND asg.business_group_id + 0 = p_business_group_id
176   AND asg.assignment_type = 'E'
177   AND p_period_end_date BETWEEN asg.effective_start_date
178                             AND asg.effective_end_date
179   AND asg.assignment_status_type_id = ast.assignment_status_type_id
180   AND ast.per_system_status = 'ACTIVE_ASSIGN';
181 
182 /* If position and grade are null, access this with p_job_id if not null */
183   CURSOR job_assignment_csr(
184          p_business_group_id	NUMBER
185         ,p_job_id		NUMBER
186         ,p_organization_id	NUMBER
187         ,p_period_end_date	DATE) is
188   SELECT asg.assignment_id
189   FROM  per_assignments_f    asg
190        ,per_assignment_status_types   ast
191   WHERE (p_organization_id IS NULL OR asg.organization_id = p_organization_id)
192   AND p_job_id = asg.job_id
193   AND asg.business_group_id + 0 = p_business_group_id
194   AND asg.assignment_type = 'E'
195   AND p_period_end_date BETWEEN asg.effective_start_date
196                             AND asg.effective_end_date
197   AND asg.assignment_status_type_id = ast.assignment_status_type_id
198   AND ast.per_system_status = 'ACTIVE_ASSIGN';
199 
200 /* If position, grade and job are null, use p_organization_id if not null */
201   CURSOR org_assignment_csr(
202          p_business_group_id	NUMBER
203         ,p_organization_id	NUMBER
204         ,p_period_end_date	DATE) is
205   SELECT asg.assignment_id
206   FROM  per_assignments_f    asg
207        ,per_assignment_status_types   ast
208   WHERE p_organization_id = asg.organization_id
209   AND asg.business_group_id + 0 = p_business_group_id
210   AND asg.assignment_type = 'E'
211   AND p_period_end_date BETWEEN asg.effective_start_date
212                             AND asg.effective_end_date
213   AND asg.assignment_status_type_id = ast.assignment_status_type_id
214   AND ast.per_system_status = 'ACTIVE_ASSIGN';
215 
216 /* If organization, position, grade and job are null, use p_business_group_id */
217   CURSOR bgr_assignment_csr(
218          p_business_group_id	NUMBER
219         ,p_period_end_date	DATE) is
220   SELECT asg.assignment_id
221   FROM  per_assignments_f    asg
222        ,per_assignment_status_types   ast
223   WHERE asg.business_group_id = p_business_group_id
224   AND asg.assignment_type = 'E'
225   AND p_period_end_date BETWEEN asg.effective_start_date
226                             AND asg.effective_end_date
227   AND asg.assignment_status_type_id = ast.assignment_status_type_id
228   AND ast.per_system_status = 'ACTIVE_ASSIGN';
229 
230   l_actuals		NUMBER := 0;
231   l_actuals_total       NUMBER := 0;
232   l_assignment_id       per_all_assignments_f.assignment_id%type;
233   l_budget_type_code    per_budgets.unit%type;
234   l_business_group_id   per_budgets.business_group_id%type;
235   l_formula_id          ff_formulas_f.formula_id%type;
236   l_grade_id            per_budget_elements.grade_id%type;
237   l_job_id              per_budget_elements.job_id%type;
238   l_organization_id     per_budget_elements.organization_id%type;
239   l_period_end_date     per_time_periods.end_date%type;
240   l_position_id	        per_budget_elements.position_id%type;
241 
242 BEGIN
243 
244 -- Return zero if any of the mandatory input parameters is null
245   IF (p_budget_id IS NULL) OR (p_formula_id IS NULL) OR (p_time_period_id IS NULL) THEN
246     RETURN 0;
247   END IF;
248 
249 -- Get Budget Type Code and confirm budget exists
250   OPEN budget_csr;
251   FETCH budget_csr INTO l_budget_type_code, l_business_group_id;
252   IF budget_csr%FOUND THEN
253     CLOSE budget_csr;
254   ELSE
255     CLOSE budget_csr;
256     RETURN(0);
257   END IF;
258 
259 -- Get End Date of the time period
260   OPEN time_period_csr;
261   FETCH time_period_csr INTO l_period_end_date;
262   IF time_period_csr%FOUND THEN
263     CLOSE time_period_csr;
264   ELSE
265     CLOSE time_period_csr;
266     RETURN(0);
267   END IF;
268 
269 /* JRHYDE - 1999/11/05 Bug -
270    Call to get_ff_actual_value replaced with call to GetBudgetValue function
271    that tests the ABV first then if that does not exist it calls the
272    Fast Formula (thus being much quicker than calling the ff for each row) */
273 
274 -- Sum the budget values for all relevant assignments
275 
276 /*----------------------------------------------------------------------------*/
277 /* Bug 2483207 - To fix high cost SQL it was necessary to split out the one   */
278 /* main cursor into five cursors. Depending on the values of the parameters   */
279 /* passed in a different cursor is used. The most selective parameter to use  */
280 /* is p_position_id, so this is checked first, followed by grade, job and     */
281 /* organization. If all parameters are null, then business group id is used.  */
282 /* Note that the option of using this index is disabled in the former four    */
283 /* cursors. This is to prevent an inefficient query plan being used.          */
284 /*----------------------------------------------------------------------------*/
285 
286   IF (p_position_id IS NOT NULL) THEN
287 
288     FOR assignment_rec in pos_assignment_csr(
289 	 l_business_group_id
290 	,p_grade_id
291 	,p_job_id
292 	,p_organization_id
293 	,p_position_id
294 	,l_period_end_date) LOOP
295 
296       l_assignment_id := assignment_rec.assignment_id;
297 
298       l_actuals := HrFastAnswers.GetBudgetValue(
299          p_budget_metric_formula_id    => p_formula_id
300         ,p_budget_metric               => l_budget_type_code
301         ,p_assignment_id               => l_assignment_id
302         ,p_effective_date              => l_period_end_date
303         ,p_session_date                => sysdate );
304 
305       l_actuals_total := l_actuals_total + l_actuals;
306 
307     END LOOP;
308 
309   ELSIF (p_grade_id IS NOT NULL) THEN
310 
311     FOR assignment_rec in grd_assignment_csr(
312 	 l_business_group_id
313 	,p_grade_id
314 	,p_job_id
315 	,p_organization_id
316 	,l_period_end_date) LOOP
317 
318       l_assignment_id := assignment_rec.assignment_id;
319 
320       l_actuals := HrFastAnswers.GetBudgetValue(
321          p_budget_metric_formula_id    => p_formula_id
322         ,p_budget_metric               => l_budget_type_code
323         ,p_assignment_id               => l_assignment_id
324         ,p_effective_date              => l_period_end_date
325         ,p_session_date                => sysdate );
326 
327       l_actuals_total := l_actuals_total + l_actuals;
328 
329     END LOOP;
330 
331   ELSIF (p_job_id IS NOT NULL) THEN
332 
333     FOR assignment_rec in job_assignment_csr(
334 	 l_business_group_id
335 	,p_job_id
336 	,p_organization_id
337 	,l_period_end_date
338 	) LOOP
339 
340       l_assignment_id := assignment_rec.assignment_id;
341 
342       l_actuals := HrFastAnswers.GetBudgetValue(
343          p_budget_metric_formula_id    => p_formula_id
344         ,p_budget_metric               => l_budget_type_code
345         ,p_assignment_id               => l_assignment_id
346         ,p_effective_date              => l_period_end_date
347         ,p_session_date                => sysdate );
348 
349       l_actuals_total := l_actuals_total + l_actuals;
350 
351     END LOOP;
352 
353   ELSIF (p_organization_id IS NOT NULL) THEN
354 
355     FOR assignment_rec in org_assignment_csr(
356 	 l_business_group_id
357 	,p_organization_id
358 	,l_period_end_date) LOOP
359 
360       l_assignment_id := assignment_rec.assignment_id;
361 
362       l_actuals := HrFastAnswers.GetBudgetValue(
363          p_budget_metric_formula_id    => p_formula_id
364         ,p_budget_metric               => l_budget_type_code
365         ,p_assignment_id               => l_assignment_id
366         ,p_effective_date              => l_period_end_date
367         ,p_session_date                => sysdate );
368 
369       l_actuals_total := l_actuals_total + l_actuals;
370 
371     END LOOP;
372 
373   ELSE
374 
375     FOR assignment_rec in bgr_assignment_csr(
376 	 l_business_group_id
377 	,l_period_end_date) LOOP
378 
379       l_assignment_id := assignment_rec.assignment_id;
380 
381       l_actuals := HrFastAnswers.GetBudgetValue(
382          p_budget_metric_formula_id    => p_formula_id
383         ,p_budget_metric               => l_budget_type_code
384         ,p_assignment_id               => l_assignment_id
385         ,p_effective_date              => l_period_end_date
386         ,p_session_date                => sysdate );
387 
388       l_actuals_total := l_actuals_total + l_actuals;
389 
390     END LOOP;
391 
392   END IF;
393 
394   RETURN(l_actuals_total);
395 
396 EXCEPTION
397   WHEN OTHERS THEN
398 
399   RETURN(0);
400 
401 END get_ff_actual_value;
402 
403 /******************************************************************************/
404 /* Function to get an assignment budget value for an assignment               */
405 /******************************************************************************/
406 FUNCTION get_asg_budget_value(p_budget_metric_formula_id  IN NUMBER
407                              ,p_budget_metric             IN VARCHAR2
408                              ,p_assignment_id             IN NUMBER
409                              ,p_effective_date            IN DATE
410                              ,p_session_date              IN DATE )
411                RETURN NUMBER IS
412 
413   l_budget_value    NUMBER;
414 
415 BEGIN
416 
417   l_budget_value := HrFastAnswers.GetBudgetValue
418   ( p_budget_metric_formula_id => p_budget_metric_formula_id
419   , p_budget_metric            => p_budget_metric
420   , p_assignment_id            => p_assignment_id
421   , p_effective_date           => p_effective_date
422   , p_session_date             => p_session_date );
423 
424   RETURN l_budget_value;
425 
426 EXCEPTION
427   WHEN hrfastanswers.ff_not_compiled THEN
428     RETURN g_no_valid_formula;
429 
430   WHEN hrfastanswers.ff_not_exist THEN
431     RETURN g_no_valid_formula;
432 
433 END get_asg_budget_value;
434 
435 
436 /******************************************************************************/
437 /* cbridge, 28/06/2001 , pqh budgets support function for                     */
438 /* hrfv_workforce_budgets business view                                       */
439 /* Public function to calculate workforce actuals for a single assignment     */
440 /* using new PQH budgets schema model                                         */
441 /* bug enhancement 1317484                                                    */
442 /******************************************************************************/
443 FUNCTION get_ff_actual_value_pqh
444 (p_budget_id            IN NUMBER
445 ,p_business_group_id    IN NUMBER
446 ,p_grade_id             IN NUMBER       DEFAULT NULL
447 ,p_job_id               IN NUMBER       DEFAULT NULL
448 ,p_organization_id      IN NUMBER       DEFAULT NULL
449 ,p_position_id          IN NUMBER       DEFAULT NULL
450 ,p_time_period_id       IN NUMBER
451 ,p_budget_metric        IN VARCHAR2
452 )
453 RETURN NUMBER IS
454 
455 cursor budget_csr is
456 select  pst1.system_type_cd     unit1_name
457       , pst2.system_type_cd     unit2_name
458       , pst3.system_type_cd     unit3_name
459       , bgt.business_group_id   business_group_id
460 from    pqh_budgets     bgt
461       , per_shared_types_vl pst1
462       , per_shared_types_vl pst2
463       , per_shared_types_vl pst3
464 where bgt.budget_id     = p_budget_id
465 AND   bgt.budget_unit1_id               = pst1.shared_type_id (+)
466 AND   bgt.budget_unit2_id               = pst2.shared_type_id (+)
467 AND   bgt.budget_unit3_id               = pst3.shared_type_id (+);
468 
469 cursor time_period_csr is
470 select  tp.end_date
471 from    per_time_periods        tp, pqh_budget_periods bpr
472 where   bpr.budget_period_id = p_time_period_id
473 and     tp.time_period_id    = bpr.end_time_period_id;
474 
475 /* 115.22 - replaced NVL logic with ORs */
476 /*----------------------------------------------------------------------------*/
477 /* Bug 2483207 - To fix high cost SQL it was necessary to split out the one   */
478 /* main cursor into five cursors. Depending on the values of the parameters   */
479 /* passed in a different cursor is used. The most selective parameter to use  */
480 /* is p_position_id, so this is checked first, followed by grade, job and     */
481 /* organization. If all parameters are null, then business group id is used.  */
482 /* Note that the option of using this index is disabled in the former four    */
483 /* cursors. This is to prevent an inefficient query plan being used.          */
484 /*----------------------------------------------------------------------------*/
485 /* To be used if p_position_id is not null */
486 cursor pos_assignment_csr(
487          p_business_group_id    NUMBER
488         ,p_grade_id             NUMBER
489         ,p_job_id               NUMBER
490         ,p_organization_id      NUMBER
491         ,p_position_id          NUMBER
492         ,p_period_end_date      DATE
493         ) is
494 select  asg.assignment_id
495 from     per_assignments_f              asg
496         ,per_assignment_status_types    ast
497 where   (p_organization_id IS NULL OR asg.organization_id = p_organization_id)
498 and     p_position_id = asg.position_id
499 and     (p_job_id IS NULL OR asg.job_id = p_job_id)
500 and     (p_grade_id IS NULL OR asg.grade_id = p_grade_id)
501 and     asg.business_group_id + 0 = p_business_group_id
502 and     asg.assignment_type     = 'E'
503 and     p_period_end_date between asg.effective_start_date and
504         asg.effective_end_date
505 and     asg.assignment_status_type_id   = ast.assignment_status_type_id
506 and     ast.per_system_status           = 'ACTIVE_ASSIGN';
507 
508 /* To be used if p_grade_id is not null */
509 cursor grd_assignment_csr(
510          p_business_group_id    NUMBER
511         ,p_grade_id             NUMBER
512         ,p_job_id               NUMBER
513         ,p_organization_id      NUMBER
514         ,p_period_end_date      DATE
515         ) is
516 select  asg.assignment_id
517 from     per_assignments_f              asg
518         ,per_assignment_status_types    ast
519 where   (p_organization_id IS NULL OR asg.organization_id = p_organization_id)
520 and     (p_job_id IS NULL OR asg.job_id = p_job_id)
521 and     p_grade_id = asg.grade_id
522 and     asg.business_group_id + 0 = p_business_group_id
523 and     asg.assignment_type     = 'E'
524 and     p_period_end_date between asg.effective_start_date and
525         asg.effective_end_date
526 and     asg.assignment_status_type_id   = ast.assignment_status_type_id
527 and     ast.per_system_status           = 'ACTIVE_ASSIGN';
528 
529 /* To be used if p_job_id is not null */
530 cursor job_assignment_csr(
531          p_business_group_id    NUMBER
532         ,p_job_id               NUMBER
533         ,p_organization_id      NUMBER
534         ,p_period_end_date      DATE
535         ) is
536 select  asg.assignment_id
537 from     per_assignments_f              asg
538         ,per_assignment_status_types    ast
539 where   (p_organization_id IS NULL OR asg.organization_id = p_organization_id)
540 and     p_job_id = asg.job_id
541 and     asg.business_group_id + 0 = p_business_group_id
542 and     asg.assignment_type     = 'E'
543 and     p_period_end_date between asg.effective_start_date and
544         asg.effective_end_date
545 and     asg.assignment_status_type_id   = ast.assignment_status_type_id
546 and     ast.per_system_status           = 'ACTIVE_ASSIGN';
547 
548 /* To be used if p_organization_id is not null */
549 cursor org_assignment_csr(
550          p_business_group_id    NUMBER
551         ,p_organization_id      NUMBER
552         ,p_period_end_date      DATE
553         ) is
554 select  asg.assignment_id
555 from     per_assignments_f              asg
556         ,per_assignment_status_types    ast
557 where   p_organization_id = asg.organization_id
558 and     asg.business_group_id + 0 = p_business_group_id
559 and     asg.assignment_type     = 'E'
560 and     p_period_end_date between asg.effective_start_date and
561         asg.effective_end_date
562 and     asg.assignment_status_type_id   = ast.assignment_status_type_id
563 and     ast.per_system_status           = 'ACTIVE_ASSIGN';
564 
565 /* To be used if all parameters are null */
566 cursor bgr_assignment_csr(
567          p_business_group_id    NUMBER
568         ,p_period_end_date      DATE
569         ) is
570 select  asg.assignment_id
571 from     per_assignments_f              asg
572         ,per_assignment_status_types    ast
573 where   asg.business_group_id = p_business_group_id
574 and     asg.assignment_type     = 'E'
575 and     p_period_end_date between asg.effective_start_date and
576         asg.effective_end_date
577 and     asg.assignment_status_type_id   = ast.assignment_status_type_id
578 and     ast.per_system_status           = 'ACTIVE_ASSIGN';
579 
580 l_actuals               number := 0;
581 l_actuals_total         number := 0;
582 l_assignment_id         per_all_assignments_f.assignment_id%type;
583 l_budget_type_code1     per_budgets.unit%type;
584 l_budget_type_code2     per_budgets.unit%type;
585 l_budget_type_code3     per_budgets.unit%type;
586 l_business_group_id     per_budgets.business_group_id%type;
587 l_formula_id            ff_formulas_f.formula_id%type;
588 l_grade_id              per_budget_elements.grade_id%type;
589 l_job_id                per_budget_elements.job_id%type;
590 l_organization_id       per_budget_elements.organization_id%type;
591 l_period_end_date       per_time_periods.end_date%type;
592 l_position_id           per_budget_elements.position_id%type;
593 p_formula_id	        ff_formulas_x.formula_id%type;
594 
595 BEGIN
596 
597 -- Return zero if any of the mandatory input parameters is null
598 
599 p_formula_id := get_manpower_formula_id
600                    (p_business_group_id => p_business_group_id
601                    , p_budget_measurement_code => p_budget_metric);
602 
603 if (p_budget_id is null) or (p_formula_id is null) or (p_time_period_id is null) then
604   return(0);
605 else
606 
607   -- Get Budget Type Code and confirm budget exists
608 
609   open budget_csr;
610   fetch budget_csr into
611      l_budget_type_code1,l_budget_type_code2,l_budget_type_code3, l_business_group_id;
612 
613   if budget_csr%found then
614 
615     if (p_budget_metric = l_budget_type_code1) or
616        (p_budget_metric = l_budget_type_code2) or
617        (p_budget_metric = l_budget_type_code3) then
618         close budget_csr;
619     else
620         close budget_csr;
621         return(0);
622     end if;
623 
624   else
625     close budget_csr;
626     return(0);
627   end if;
628 
629   -- Get End Date of the time period
630 
631   open time_period_csr;
632   fetch time_period_csr into l_period_end_date;
633   close time_period_csr;
634 
635     -- JRHYDE - 1999/11/05 Bug -
636     -- Call to get_ff_actual_value replaced with call to GetBudgetValue function
637     -- that tests the ABV first then if that does not exist it calls the
638     -- Fast Formula (thus being much quicker than calling the ff for each row)
639 
640 /*----------------------------------------------------------------------------*/
641 /* Bug 2483207 - To fix high cost SQL it was necessary to split out the one   */
642 /* main cursor into five cursors. Depending on the values of the parameters   */
643 /* passed in a different cursor is used. The most selective parameter to use  */
644 /* is p_position_id, so this is checked first, followed by grade, job and     */
645 /* organization. If all parameters are null, then business group id is used.  */
646 /* Note that the option of using this index is disabled in the former four    */
647 /* cursors. This is to prevent an inefficient query plan being used.          */
648 /*----------------------------------------------------------------------------*/
649 
650   IF (p_position_id IS NOT NULL) THEN
651 
652     FOR assignment_rec IN pos_assignment_csr(
653          l_business_group_id
654         ,p_grade_id
655         ,p_job_id
656         ,p_organization_id
657         ,p_position_id
658         ,l_period_end_date
659         ) LOOP
660 
661       l_assignment_id := assignment_rec.assignment_id;
662 
663       BEGIN /* cbridge bug 1875197 */
664         l_actuals := HrFastAnswers.GetBudgetValue(
665            p_budget_metric_formula_id    => p_formula_id
666           ,p_budget_metric               => p_budget_metric
667           ,p_assignment_id               => l_assignment_id
668           ,p_effective_date              => l_period_end_date
669           ,p_session_date                => sysdate );
670        EXCEPTION
671           WHEN OTHERS THEN
672            -- fast formula not compiled for an assignment that has no abv,
673            -- so need to trap exception.
674            l_actuals := 0;
675        END;
676 
677       l_actuals_total := l_actuals_total + l_actuals;
678 
679     END LOOP;
680 
681   ELSIF (p_grade_id IS NOT NULL) THEN
682 
683     FOR assignment_rec IN grd_assignment_csr(
684          l_business_group_id
685         ,p_grade_id
686         ,p_job_id
687         ,p_organization_id
688         ,l_period_end_date
689         ) LOOP
690 
691       l_assignment_id := assignment_rec.assignment_id;
692 
693       BEGIN /* cbridge bug 1875197 */
694         l_actuals := HrFastAnswers.GetBudgetValue(
695            p_budget_metric_formula_id    => p_formula_id
696           ,p_budget_metric               => p_budget_metric
697           ,p_assignment_id               => l_assignment_id
698           ,p_effective_date              => l_period_end_date
699           ,p_session_date                => sysdate );
700        EXCEPTION
701           WHEN OTHERS THEN
702            -- fast formula not compiled for an assignment that has no abv,
703            -- so need to trap exception.
704            l_actuals := 0;
705        END;
706 
707       l_actuals_total := l_actuals_total + l_actuals;
708 
709     END LOOP;
710 
711   ELSIF (p_job_id IS NOT NULL) THEN
712 
713     FOR assignment_rec IN job_assignment_csr(
714          l_business_group_id
715         ,p_job_id
716         ,p_organization_id
717         ,l_period_end_date
718         ) LOOP
719 
720       l_assignment_id := assignment_rec.assignment_id;
721 
722       BEGIN /* cbridge bug 1875197 */
723         l_actuals := HrFastAnswers.GetBudgetValue(
724            p_budget_metric_formula_id    => p_formula_id
725           ,p_budget_metric               => p_budget_metric
726           ,p_assignment_id               => l_assignment_id
727           ,p_effective_date              => l_period_end_date
728           ,p_session_date                => sysdate );
729        EXCEPTION
730           WHEN OTHERS THEN
731            -- fast formula not compiled for an assignment that has no abv,
732            -- so need to trap exception.
733            l_actuals := 0;
734        END;
735 
736       l_actuals_total := l_actuals_total + l_actuals;
737 
738     END LOOP;
739 
740   ELSIF (p_organization_id IS NOT NULL) THEN
741 
742     FOR assignment_rec IN org_assignment_csr(
743          l_business_group_id
744         ,p_organization_id
745         ,l_period_end_date
746         ) LOOP
747 
748       l_assignment_id := assignment_rec.assignment_id;
749 
750       BEGIN /* cbridge bug 1875197 */
751         l_actuals := HrFastAnswers.GetBudgetValue(
752            p_budget_metric_formula_id    => p_formula_id
753           ,p_budget_metric               => p_budget_metric
754           ,p_assignment_id               => l_assignment_id
755           ,p_effective_date              => l_period_end_date
756           ,p_session_date                => sysdate );
757        EXCEPTION
758           WHEN OTHERS THEN
759            -- fast formula not compiled for an assignment that has no abv,
760            -- so need to trap exception.
761            l_actuals := 0;
762        END;
763 
764       l_actuals_total := l_actuals_total + l_actuals;
765 
766     END LOOP;
767 
768   ELSE
769 
770     FOR assignment_rec IN bgr_assignment_csr(
771          l_business_group_id
772         ,l_period_end_date
773         ) LOOP
774 
775       l_assignment_id := assignment_rec.assignment_id;
776 
777       BEGIN /* cbridge bug 1875197 */
778         l_actuals := HrFastAnswers.GetBudgetValue(
779            p_budget_metric_formula_id    => p_formula_id
780           ,p_budget_metric               => p_budget_metric
781           ,p_assignment_id               => l_assignment_id
782           ,p_effective_date              => l_period_end_date
783           ,p_session_date                => sysdate );
784        EXCEPTION
785           WHEN OTHERS THEN
786            -- fast formula not compiled for an assignment that has no abv,
787            -- so need to trap exception.
788            l_actuals := 0;
789        END;
790 
791       l_actuals_total := l_actuals_total + l_actuals;
792 
793     END LOOP;
794 
795   END IF;
796 
797   -- Sum the budget values for all relevant assignments
798 
799   return(l_actuals_total);
800 
801 end if;
802 
803 EXCEPTION
804   when others then
805     return(0);
806 
807 END get_ff_actual_value_pqh;
808 
809 
810 /******************************************************************************/
811 /* Function returning the number of direct reports for a person on a date     */
812 /******************************************************************************/
813 FUNCTION direct_reports
814 (p_person_id            IN NUMBER
815 ,p_effective_start_date IN DATE
816 ,p_effective_end_date   IN DATE)
817 RETURN NUMBER IS
818    v_person_id             NUMBER;
819    v_effective_start_date  DATE;
820    v_effective_end_date    DATE;
821    v_direct_reports        NUMBER;
822 BEGIN
823    v_person_id := p_person_id;
824    v_effective_start_date := p_effective_start_date;
825    v_effective_end_date := p_effective_end_date;
826 
827    -- 17-OCT-2001, bug 2052714, fixed to exclude terminated direct reports from the count
828    --
829 
830    SELECT count(*) INTO v_direct_reports
831    FROM   per_all_assignments_f   asg, per_all_people_f peo
832    WHERE  asg.supervisor_id = v_person_id
833    AND    v_effective_end_date BETWEEN asg.effective_start_date
834                                AND     asg.effective_end_date
835    AND    asg.person_id = peo.person_id
836    AND    v_effective_end_date
837       BETWEEN peo.effective_start_date AND peo.effective_end_date
838    AND    peo.current_employee_flag = 'Y' ;
839 
840   RETURN (v_direct_reports);
841 END direct_reports;
842 
843 /******************************************************************************/
844 /* This function will return the lookup code given the meaning for a lookup   */
845 /* type of budget measurement type                                            */
846 /******************************************************************************/
847 PROCEDURE cache_bmt_code(p_bmt_meaning   IN VARCHAR2) IS
848 
849   CURSOR bmt_code_csr IS
850   SELECT lookup_code
851   FROM hr_standard_lookups
852   WHERE lookup_type = 'BUDGET_MEASUREMENT_TYPE'
853   AND meaning = p_bmt_meaning;
854 
855 BEGIN
856 
857 /* Store new BMT code in global */
858   OPEN bmt_code_csr;
859   FETCH bmt_code_csr INTO g_bmt_code;
860   CLOSE bmt_code_csr;
861 
862 /* Store meaning for new BMT code in global */
863   g_bmt_meaning := p_bmt_meaning;
864 
865 END cache_bmt_code;
866 
867 /******************************************************************************/
868 /* Calculates the ABV given a BMT meaning, business group and assignment      */
869 /******************************************************************************/
870 FUNCTION calc_abv_lookup(p_assignment_id     IN NUMBER,
871                          p_business_group_id IN NUMBER,
872                          p_bmt_meaning       IN VARCHAR2,
873                          p_effective_date    IN DATE)
874           RETURN NUMBER IS
875 
876 BEGIN
877 
878   IF (p_bmt_meaning = g_bmt_meaning) THEN
879     null;
880   ELSE
881     cache_bmt_code(p_bmt_meaning => p_bmt_meaning);
882   END IF;
883 
884   RETURN (hri_bpl_abv.calc_abv
885            (p_assignment_id => p_assignment_id,
886             p_business_group_id => p_business_group_id,
887             p_budget_type => g_bmt_code,
888             p_effective_date => p_effective_date));
889 
890 EXCEPTION
891   WHEN OTHERS THEN
892     RETURN to_number(null);
893 END calc_abv_lookup;
894 
895 /******************************************************************************/
896 /* Calculates the ABV given a BMT meaning, business group and assignment      */
897 /******************************************************************************/
898 FUNCTION calc_abv_lookup(p_assignment_id     IN NUMBER,
899                          p_business_group_id IN NUMBER,
900                          p_bmt_meaning       IN VARCHAR2,
901                          p_effective_date    IN DATE,
902                          p_primary_flag      IN VARCHAR2)
903           RETURN NUMBER IS
904 
905 BEGIN
906 
907   IF (p_bmt_meaning = g_bmt_meaning) THEN
908     null;
909   ELSE
910     cache_bmt_code(p_bmt_meaning => p_bmt_meaning);
911   END IF;
912 
913   RETURN (hri_bpl_abv.calc_abv
914            (p_assignment_id => p_assignment_id,
915             p_business_group_id => p_business_group_id,
916             p_budget_type => g_bmt_code,
917             p_effective_date => p_effective_date,
918             p_primary_flag => p_primary_flag));
919 
920 EXCEPTION
921   WHEN OTHERS THEN
922     RETURN to_number(null);
923 END calc_abv_lookup;
924 
925 -- cbridge, 09-JAN-02, new function to return pqh budget
926 -- actual values for a given budget on an effective_date
927 FUNCTION get_ff_actual_value_pqh
928 (p_budget_id            IN NUMBER
929 ,p_business_group_id    IN NUMBER
930 ,p_grade_id             IN NUMBER       DEFAULT NULL
931 ,p_job_id               IN NUMBER       DEFAULT NULL
932 ,p_organization_id      IN NUMBER       DEFAULT NULL
933 ,p_position_id          IN NUMBER       DEFAULT NULL
934 ,p_effective_date       IN DATE
935 ,p_budget_metric        IN VARCHAR2
936 )
937 RETURN NUMBER IS
938 
939 CURSOR budget_csr is
940 SELECT  pst1.system_type_cd     unit1_name
941       , pst2.system_type_cd     unit2_name
942       , pst3.system_type_cd     unit3_name
943       , bgt.business_group_id   business_group_id
944 FROM    pqh_budgets     bgt
945       , per_shared_types_vl pst1
946       , per_shared_types_vl pst2
947       , per_shared_types_vl pst3
948 WHERE bgt.budget_id     = p_budget_id
949 AND   bgt.budget_unit1_id               = pst1.shared_type_id (+)
950 AND   bgt.budget_unit2_id               = pst2.shared_type_id (+)
951 AND   bgt.budget_unit3_id               = pst3.shared_type_id (+);
952 
953 
954 /* To be used if p_position_id is not null */
955 cursor pos_assignment_csr(
956          p_business_group_id    NUMBER
957         ,p_grade_id             NUMBER
958         ,p_job_id               NUMBER
959         ,p_organization_id      NUMBER
960         ,p_position_id          NUMBER
961         ,p_effective_date      DATE
962         ) is
963 select  asg.assignment_id
964 from     per_assignments_f              asg
965         ,per_assignment_status_types    ast
966 where   (p_organization_id IS NULL OR asg.organization_id = p_organization_id)
967 and     p_position_id = asg.position_id
968 and     (p_job_id IS NULL OR asg.job_id = p_job_id)
969 and     (p_grade_id IS NULL OR asg.grade_id = p_grade_id)
970 and     asg.business_group_id   = p_business_group_id
971 and     asg.assignment_type     = 'E'
972 and     p_effective_date between asg.effective_start_date and
973         asg.effective_end_date
974 and     asg.assignment_status_type_id   = ast.assignment_status_type_id
975 and     ast.per_system_status           = 'ACTIVE_ASSIGN';
976 
977 /* To be used if p_grade_id is not null */
978 cursor grd_assignment_csr(
979          p_business_group_id    NUMBER
980         ,p_grade_id             NUMBER
981         ,p_job_id               NUMBER
982         ,p_organization_id      NUMBER
983         ,p_effective_date      DATE
984         ) is
985 select  asg.assignment_id
986 from     per_assignments_f              asg
987         ,per_assignment_status_types    ast
988 where   (p_organization_id IS NULL OR asg.organization_id = p_organization_id)
989 and     (p_job_id IS NULL OR asg.job_id = p_job_id)
990 and     p_grade_id = asg.grade_id
991 and     asg.business_group_id  = p_business_group_id
992 and     asg.assignment_type     = 'E'
993 and     p_effective_date between asg.effective_start_date and
994         asg.effective_end_date
995 and     asg.assignment_status_type_id   = ast.assignment_status_type_id
996 and     ast.per_system_status           = 'ACTIVE_ASSIGN';
997 
998 /* To be used if p_job_id is not null */
999 cursor job_assignment_csr(
1000          p_business_group_id    NUMBER
1001         ,p_job_id               NUMBER
1002         ,p_organization_id      NUMBER
1003         ,p_effective_date      DATE
1004         ) is
1005 select  asg.assignment_id
1006 from     per_assignments_f              asg
1007         ,per_assignment_status_types    ast
1008 where   (p_organization_id IS NULL OR asg.organization_id = p_organization_id)
1009 and     p_job_id = asg.job_id
1010 and     asg.business_group_id   = p_business_group_id
1011 and     asg.assignment_type     = 'E'
1012 and     p_effective_date between asg.effective_start_date and
1013         asg.effective_end_date
1014 and     asg.assignment_status_type_id   = ast.assignment_status_type_id
1015 and     ast.per_system_status           = 'ACTIVE_ASSIGN';
1016 
1017 /* To be used if p_organization_id is not null */
1018 cursor org_assignment_csr(
1019          p_business_group_id    NUMBER
1020         ,p_organization_id      NUMBER
1021         ,p_effective_date      DATE
1022         ) is
1023 select  asg.assignment_id
1024 from     per_assignments_f              asg
1025         ,per_assignment_status_types    ast
1026 where   p_organization_id = asg.organization_id
1027 and     asg.business_group_id  = p_business_group_id
1028 and     asg.assignment_type     = 'E'
1029 and     p_effective_date between asg.effective_start_date and
1030         asg.effective_end_date
1031 and     asg.assignment_status_type_id   = ast.assignment_status_type_id
1032 and     ast.per_system_status           = 'ACTIVE_ASSIGN';
1033 
1034 /* To be used if all parameters are null */
1035 cursor bgr_assignment_csr(
1036          p_business_group_id    NUMBER
1037         ,p_effective_date      DATE
1038         ) is
1039 select  asg.assignment_id
1040 from     per_assignments_f              asg
1041         ,per_assignment_status_types    ast
1042 where   asg.business_group_id = p_business_group_id
1043 and     asg.assignment_type     = 'E'
1044 and     p_effective_date between asg.effective_start_date and
1045         asg.effective_end_date
1046 and     asg.assignment_status_type_id   = ast.assignment_status_type_id
1047 and     ast.per_system_status           = 'ACTIVE_ASSIGN';
1048 
1049 l_actuals               number := 0;
1050 l_actuals_total         number := 0;
1051 l_assignment_id         per_all_assignments_f.assignment_id%type;
1052 l_budget_type_code1     per_budgets.unit%type;
1053 l_budget_type_code2     per_budgets.unit%type;
1054 l_budget_type_code3     per_budgets.unit%type;
1055 l_business_group_id     per_budgets.business_group_id%type;
1056 l_formula_id            ff_formulas_f.formula_id%type;
1057 l_grade_id              per_budget_elements.grade_id%type;
1058 l_job_id                per_budget_elements.job_id%type;
1059 l_organization_id       per_budget_elements.organization_id%type;
1060 l_period_end_date       per_time_periods.end_date%type;
1061 l_position_id           per_budget_elements.position_id%type;
1062 p_formula_id	        ff_formulas_x.formula_id%type;
1063 
1064 BEGIN
1065 
1066 
1067 p_formula_id := get_manpower_formula_id
1068                    (p_business_group_id => p_business_group_id
1069                    , p_budget_measurement_code => p_budget_metric);
1070 
1071 if (p_budget_id is null) or (p_formula_id is null) or (p_effective_date is null) then
1072   return(0);
1073 else
1074 
1075   -- Get Budget Type Code and confirm budget exists
1076 
1077   open budget_csr;
1078   fetch budget_csr into
1079      l_budget_type_code1,l_budget_type_code2,l_budget_type_code3, l_business_group_id;
1080 
1081   if budget_csr%found then
1082 
1083     if (p_budget_metric = l_budget_type_code1) or
1084        (p_budget_metric = l_budget_type_code2) or
1085        (p_budget_metric = l_budget_type_code3) then
1086         close budget_csr;
1087     else
1088         close budget_csr;
1089         return(0);
1090     end if;
1091 
1092   else
1093     close budget_csr;
1094     return(0);
1095   end if;
1096 
1097   IF (p_position_id IS NOT NULL) THEN
1098 
1099     FOR assignment_rec IN pos_assignment_csr(
1100          l_business_group_id
1101         ,p_grade_id
1102         ,p_job_id
1103         ,p_organization_id
1104         ,p_position_id
1105         ,p_effective_date
1106         ) LOOP
1107 
1108       l_assignment_id := assignment_rec.assignment_id;
1109 
1110       BEGIN /* cbridge bug 1875197 */
1111         l_actuals := HrFastAnswers.GetBudgetValue(
1112            p_budget_metric_formula_id    => p_formula_id
1113           ,p_budget_metric               => p_budget_metric
1114           ,p_assignment_id               => l_assignment_id
1115           ,p_effective_date              => p_effective_date
1116           ,p_session_date                => sysdate );
1117        EXCEPTION
1118           WHEN OTHERS THEN
1119            -- fast formula not compiled for an assignment that has no abv,
1120            -- so need to trap exception.
1121            l_actuals := 0;
1122        END;
1123 
1124       l_actuals_total := l_actuals_total + l_actuals;
1125 
1126     END LOOP;
1127 
1128   ELSIF (p_grade_id IS NOT NULL) THEN
1129 
1130     FOR assignment_rec IN grd_assignment_csr(
1131          l_business_group_id
1132         ,p_grade_id
1133         ,p_job_id
1134         ,p_organization_id
1135         ,p_effective_date
1136         ) LOOP
1137 
1138       l_assignment_id := assignment_rec.assignment_id;
1139 
1140       BEGIN /* cbridge bug 1875197 */
1141         l_actuals := HrFastAnswers.GetBudgetValue(
1142            p_budget_metric_formula_id    => p_formula_id
1143           ,p_budget_metric               => p_budget_metric
1144           ,p_assignment_id               => l_assignment_id
1145           ,p_effective_date              => p_effective_date
1146           ,p_session_date                => sysdate );
1147        EXCEPTION
1148           WHEN OTHERS THEN
1149            -- fast formula not compiled for an assignment that has no abv,
1150            -- so need to trap exception.
1151            l_actuals := 0;
1152        END;
1153 
1154       l_actuals_total := l_actuals_total + l_actuals;
1155 
1156     END LOOP;
1157 
1158   ELSIF (p_job_id IS NOT NULL) THEN
1159 
1160     FOR assignment_rec IN job_assignment_csr(
1161          l_business_group_id
1162         ,p_job_id
1163         ,p_organization_id
1164         ,p_effective_date
1165         ) LOOP
1166 
1167       l_assignment_id := assignment_rec.assignment_id;
1168 
1169 
1170       BEGIN /* cbridge bug 1875197 */
1171         l_actuals := HrFastAnswers.GetBudgetValue(
1172            p_budget_metric_formula_id    => p_formula_id
1173           ,p_budget_metric               => p_budget_metric
1174           ,p_assignment_id               => l_assignment_id
1175           ,p_effective_date              => p_effective_date
1176           ,p_session_date                => sysdate );
1177        EXCEPTION
1178           WHEN OTHERS THEN
1179            -- fast formula not compiled for an assignment that has no abv,
1180            -- so need to trap exception.
1181            l_actuals := 0;
1182        END;
1183 
1184       l_actuals_total := l_actuals_total + l_actuals;
1185 
1186     END LOOP;
1187 
1188   ELSIF (p_organization_id IS NOT NULL) THEN
1189 
1190 
1191     FOR assignment_rec IN org_assignment_csr(
1192          l_business_group_id
1193         ,p_organization_id
1194         ,p_effective_date
1195         ) LOOP
1196 
1197       l_assignment_id := assignment_rec.assignment_id;
1198 
1199       BEGIN /* cbridge bug 1875197 */
1200         l_actuals := HrFastAnswers.GetBudgetValue(
1201            p_budget_metric_formula_id    => p_formula_id
1202           ,p_budget_metric               => p_budget_metric
1203           ,p_assignment_id               => l_assignment_id
1204           ,p_effective_date              => p_effective_date
1205           ,p_session_date                => sysdate );
1206        EXCEPTION
1207           WHEN OTHERS THEN
1208            -- fast formula not compiled for an assignment that has no abv,
1209            -- so need to trap exception.
1210            l_actuals := 0;
1211        END;
1212 
1213       l_actuals_total := l_actuals_total + l_actuals;
1214 
1215     END LOOP;
1216 
1217   ELSE
1218 
1219     FOR assignment_rec IN bgr_assignment_csr(
1220          l_business_group_id
1221         ,p_effective_date
1222         ) LOOP
1223 
1224       l_assignment_id := assignment_rec.assignment_id;
1225 
1226       BEGIN /* cbridge bug 1875197 */
1227         l_actuals := HrFastAnswers.GetBudgetValue(
1228            p_budget_metric_formula_id    => p_formula_id
1229           ,p_budget_metric               => p_budget_metric
1230           ,p_assignment_id               => l_assignment_id
1231           ,p_effective_date              => p_effective_date
1232           ,p_session_date                => sysdate );
1233        EXCEPTION
1234           WHEN OTHERS THEN
1235            -- fast formula not compiled for an assignment that has no abv,
1236            -- so need to trap exception.
1237            l_actuals := 0;
1238        END;
1239 
1240       l_actuals_total := l_actuals_total + l_actuals;
1241 
1242     END LOOP;
1243 
1244   END IF;
1245 
1246   -- Sum the budget values for all relevant assignments
1247 
1248   return(l_actuals_total);
1249 
1250 end if;
1251 
1252 EXCEPTION
1253   when others then
1254     return(0);
1255 
1256 END get_ff_actual_value_pqh;
1257 
1258 -- returns period of time, in months, of the persons period of service
1259 -- taking into account breaks in service for employee rehires
1260 FUNCTION get_period_service_in_months(p_person_id IN NUMBER
1261                                      ,p_period_of_service_id IN NUMBER
1262                                      ,p_effective_date IN DATE) RETURN NUMBER
1263 
1264 IS
1265 
1266 CURSOR get_pps_months_cur IS
1267 SELECT sum(months_between(least(nvl(actual_termination_date + 1,
1268        p_effective_date + 1), p_effective_date + 1), date_start)) total_months
1269 FROM  per_periods_of_service
1270 WHERE  person_id             = p_person_id
1271 AND    date_start           <= p_effective_date
1272 AND    period_of_service_id <= p_period_of_service_id;
1273 
1274 
1275 l_period_service_months NUMBER :=0;
1276 
1277 BEGIN
1278 
1279     OPEN  get_pps_months_cur;
1280     FETCH get_pps_months_cur INTO l_period_service_months;
1281     CLOSE get_pps_months_cur;
1282 
1283     RETURN (l_period_service_months);
1284 
1285 EXCEPTION
1286      WHEN OTHERS THEN
1287      BEGIN
1288          IF get_pps_months_cur%ISOPEN THEN
1289             CLOSE get_pps_months_cur;
1290          END IF;
1291          RETURN (l_period_service_months);
1292      END; -- exception
1293 
1294 END get_period_service_in_months;
1295 
1296 -- returns period of time, in years, of the persons period of service
1297 -- taking into account breaks in service for employee rehires
1298 FUNCTION get_period_service_in_years(p_person_id IN NUMBER
1299                                      ,p_period_of_service_id IN NUMBER
1300                                      ,p_effective_date IN DATE) RETURN NUMBER
1301 
1302 IS
1303 
1304 CURSOR get_pps_years_cur IS
1305 SELECT sum(months_between
1306                 (least(nvl(actual_termination_date + 1, p_effective_date + 1),
1307                    p_effective_date + 1), date_start)) / 12   total_years
1308 FROM  per_periods_of_service
1309 WHERE  person_id             = p_person_id
1310 AND    date_start           <= p_effective_date
1311 AND    period_of_service_id <= p_period_of_service_id;
1312 
1313 l_period_service_years NUMBER :=0;
1314 
1315 BEGIN
1316 
1317     OPEN  get_pps_years_cur;
1318     FETCH get_pps_years_cur INTO l_period_service_years;
1319     CLOSE get_pps_years_cur;
1320 
1321     RETURN (l_period_service_years);
1322 
1323 EXCEPTION
1324      WHEN OTHERS THEN
1325      BEGIN
1326          IF get_pps_years_cur%ISOPEN THEN
1327             CLOSE get_pps_years_cur;
1328          END IF;
1329          RETURN (l_period_service_years);
1330      END; -- exception
1331 
1332 END get_period_service_in_years;
1333 
1334 
1335 END hri_oltp_disc_wrkfrc;