DBA Data[Home] [Help]

PACKAGE BODY: APPS.PAY_US_PTO_ACCRUAL

Source


1 package body pay_us_pto_accrual as
2  /* $Header: pyusptoa.pkb 120.1.12020000.5 2012/11/13 05:19:46 lbodired ship $
3    ******************************************************************
4    *                                                                *
5    *  Copyright (C) 1993 Oracle Corporation.                        *
6    *  All rights reserved.                                          *
7    *                                                                *
8    *  This material has been provided pursuant to an agreement      *
9    *  containing restrictions on its use.  The material is also     *
10    *  protected by copyright law.  No part of this material may     *
11    *  be copied or distributed, transmitted or transcribed, in      *
12    *  any form or by any means, electronic, mechanical, magnetic,   *
13    *  manual, or otherwise, or disclosed to third parties without   *
14    *  the express written permission of Oracle Corporation,         *
15    *  500 Oracle Parkway, Redwood City, CA, 94065.                  *
16    *                                                                *
17    ******************************************************************
18     Name        : pay_us_pto_accrual
19     Description : This package holds building blocks used in PTO accrual
20                   calculation.
21     Uses        : hr_utility
22     Change List
23     -----------
24     Date        Name          Vers      Bug No   Description
25     ----        ----          ----      ------   -----------
26     FEB-16-1994 RMAMGAIN      1.0                Created with following proc.
27                                                   . get_accrual
28                                                   . get_accrual_for_plan
29                                                   . get_first_accrual_period
30                                                   . ceiling_calc
31 
32     24-NOV-1994 RFINE				Suppressed index on
33                                                 business_group_id
34 
35     14-JUN-1995	HPARICHA	40.6	287032	Corrected length of service
36 					287076	calculation and accrual
37 						entitlement logic.
38     10-OCT-1995 JTHURING        40.9            Added missing '/', exit
39     11-OCT-1995 JTHURING        40.10           Removed spurious IF clause:
40 				    "if P_net_accrual > P_current_ceiling then
41                			        P_net_accrual := P_current_ceiling;"
42     06-DEC-1995 AMILLS          40.11           Changed date format to DDMMYYYY
43                                                 (on one check of end date)
44                                                 for translation.
45     19-Jan-96	rfine	 40.12	305751  Changed cursor csr_get_time_periods in
46    					proc get_accrual_for_plan so it gets
47 					the correct time periods for the
48 					accrual period. Also allowed a period
49 					after six months eligiblity to count if
50 					its start date matches the six month
51 					anniversary. (i.e. if you join on 1 Jan
52 					and periods start on the first of the
53 					month, you start accruing on 1 Jul, not
54 					1 Aug.
55     04-Nov-96  khabibul  40.13  367438  added close cursor XXX at various places
56 					as the cursors were not closed at the right
57 					time especially when an error was raised. This
58 					left the open cursor's open and during the next
59 					call to this package (same session) the db was
60 					in a confusion state and gave spurious messages.
61 					Also included a new message which is raised if the
62 					effective date is not within the range of payroll
63 					time periods.
64     13-Nov-96  lwthomps  40.14          Added a performance fix to csr_get_plan_details.
65     15-NOV-96  gpaytonm  40.15		Added close cursor csr_get_period
66 
67     25-Mar-98  lwthomps  40.16(110.1)   Truncated date coming in from
68                                         check writer for bug: 464550
69     21-May-98	Djeng	110.2		fixed bug 672443
70     23-Mar-99   Sdoshi  115.2           Flexible Dates Conversion
71     08-APR-99   djoshi                  Verfied and converted for Canonical
72                                         Complience of Date
73     21-May-01  dcasemor 115.10          Removed assignment_action_id check when deciding
74                                         whether to use hard-coded or Fast Formula-based
75                                         PTO solution.
76     22-May-01  dcasemor 115.11          Convert assignment_action_id to -1 if
77                                         a null is passed or defaulted. This
78                                         prevents an error running the formulae.
79     16-Oct-02  dcasemor 115.12 2628433  Added delete_plan_from_cache and
80                                         use_fast_formula.  These remove the dependency
81                                         on the "Use FF-based PTO Accruals" profile
82                                         option.
83     14-DEC-05  risgupta 115.14 4761039  passing -1 into l_assignment_action_id as net
84                                         entitlement during archival process is not getting
85                                         returned correctly,hence discrepancy in SOE and
86                                         payslip.
87     14-DEC-05 risgupta  115.15          CHANGES DONE in VERSION 115.14 UNDONE.
88     06-NOV-12 lbodired  115.16          modified the procedure 'accrual_calc_detail'
89   */
90 --
91 -- Private PL/SQL table to cache a list of accrual plans.
92 --
93 TYPE per_plans IS TABLE OF BOOLEAN INDEX BY binary_integer;
94 g_plan_list    per_plans;
95 g_package      VARCHAR2(30) := 'pay_us_pto_accrual.';
96 
97 --
98 ------------------------- delete_plan_from_cache ----------------------------
99 --
100 PROCEDURE delete_plan_from_cache (p_plan_id IN NUMBER)
101 IS
102 
103 BEGIN
104 
105   IF g_plan_list.exists(p_plan_id) THEN
106     --
107     -- Delete the plan from the cache.
108     --
109     g_plan_list.DELETE(p_plan_id);
110 
111   END IF;
112 
113 END delete_plan_from_cache;
114 --
115 ------------------------- use_fast_formula ----------------------------
116 --
117 FUNCTION use_fast_formula
118   (p_effective_date IN DATE
119   ,p_plan_id        IN NUMBER) RETURN BOOLEAN
120 IS
121 
122   --
123   -- Fetches FALSE if the old 10.7 hard-coded PTO rules can be used
124   -- instead of the Fast Formula.  The sole reason for doing this is
125   -- because its faster to execute PL/SQL than Fast Formula so improves
126   -- the performance of batch processes such as Checkwriter.
127   --
128   CURSOR csr_use_ff IS
129   SELECT NULL
130   FROM   pay_accrual_plans pap
131         ,ff_formulas_f ff
132   WHERE  pap.accrual_plan_id = p_plan_id
133   AND    pap.accrual_formula_id = ff.formula_id
134   AND    p_effective_date BETWEEN
135          ff.effective_start_date and ff.effective_end_date
136   AND   (ff.formula_name = 'PTO_PAYROLL_CALCULATION'
137    OR   (ff.formula_name = 'PTO_PAYROLL_BALANCE_CALCULATION' AND
138          pap.defined_balance_id IS NULL));
139 
140   l_return BOOLEAN := TRUE;
141   l_dummy  NUMBER;
142 
143 BEGIN
144 
145   --
146   -- Check to see if this plan has already been cached.
147   --
148   IF g_plan_list.exists(p_plan_id) THEN
149 
150     l_return := g_plan_list(p_plan_id);
151 
152   ELSE
153 
154     --
155     -- The plan has not been cached. Calculate if the Fast Formula
156     -- must be used and cache the value.
157     --
158     OPEN  csr_use_ff;
159     FETCH csr_use_ff INTO l_dummy;
160     --
161     -- If the cursor returns no rows, l_return will default to its
162     -- declared value of TRUE.
163     --
164     IF csr_use_ff%FOUND THEN
165       l_return := FALSE;
166     END IF;
167 
168     CLOSE csr_use_ff;
169 
170     g_plan_list(p_plan_id) := l_return;
171 
172   END IF;
173 
174   RETURN l_return;
175 
176 END use_fast_formula;
177 --
178 ------------------------- get_accrual ----------------------------
179 --
180 FUNCTION get_accrual
181                     ( P_assignment_id        number,
182                       P_calculation_date     date,
183                       P_plan_id              number   DEFAULT NULL,
184                       P_plan_category        varchar2 DEFAULT NULL)
185          RETURN Number is
186 --
187 -- Function calls the actual proc. which will calc. accrual and pass back all
188 -- the details in formula we will call functions so this will be the cover
189 -- function to call the proc.
190 --
191 l_accrual  number := 0;
192 --
193 c_date date := P_calculation_date;
194 n1 number;
195 n2 number;
196 n3 number;
197 d1 date;
198 d2 date;
199 d3 date;
200 d4 date;
201 d5 date;
202 d6 date;
203 d7 date;
204 p_mod varchar2(1) := 'N';
205 --
206 BEGIN
207 --
208 
209    pay_us_pto_accrual.accrual_calc_detail(
210        P_assignment_id      => P_assignment_id,
211        P_calculation_date   => c_date,
212        P_plan_id            => P_plan_id,
213        P_plan_category      => P_plan_category,
214        P_accrual            => l_accrual,
215        P_payroll_id         => n1,
216        P_first_period_start => d1,
217        P_first_period_end   => d2,
218        P_last_period_start  => d3,
219        P_last_period_end    => d4,
220        P_cont_service_date  => d5,
221        P_start_date         => d6,
222        P_end_date           => d7,
223        P_current_ceiling    => n2,
224        P_current_carry_over => n3);
225 --
226   IF l_accrual is null
227   THEN
228     l_accrual := 0;
229   END IF;
230 --
231   RETURN(l_accrual);
232 --
233 END get_accrual;
234 --
235 ------------------------- accrual_calc_detail ------------------------------
236 --
237 -- This procedure can be called directly this procedure will return start
238 -- date, end dates etc. which can be used by CO or net calc routines.
239 --
240 PROCEDURE accrual_calc_detail
241               (P_assignment_id          IN    number,
242                P_calculation_date    IN OUT nocopy  date,
243                P_plan_id                IN    number   DEFAULT NULL,
244                P_plan_category          IN    varchar2 DEFAULT NULL,
245                P_mode                   IN    varchar2 DEFAULT 'N',
246                P_accrual                OUT nocopy  number,
247                P_payroll_id          IN OUT nocopy  number,
248                P_first_period_start  IN OUT nocopy  date,
249                P_first_period_end    IN OUT nocopy  date,
250                P_last_period_start   IN OUT nocopy  date,
251                P_last_period_end     IN OUT nocopy  date,
252                P_cont_service_date      OUT nocopy  date,
253                P_start_date             OUT nocopy  date,
254                P_end_date               OUT nocopy  date,
255                P_current_ceiling        OUT nocopy  number,
256                P_current_carry_over     OUT nocopy  number)  IS
257 -- Get Plan details
258 -- lwthomps disabled an index on pev, 13-NOV-1996
259 CURSOR csr_get_plan_details ( P_business_group Number) is
260        select pap.accrual_plan_id,
261               pap.accrual_plan_element_type_id,
262               pap.accrual_units_of_measure,
263               pap.ineligible_period_type,
264               pap.ineligible_period_length,
265               pap.accrual_start,
266               pev.SCREEN_ENTRY_VALUE,
267               pee.element_entry_id
268        from   pay_accrual_plans            pap,
269               pay_element_entry_values_f   pev,
270               pay_element_entries_f        pee,
271               pay_element_links_f          pel,
272               pay_element_types_f          pet,
273               pay_input_values_f           piv
274        where  ( pap.accrual_plan_id            = p_plan_id     OR
275                 pap.accrual_category           = P_plan_category )
276        and    pap.business_group_id + 0            = P_business_group
277        and    pap.accrual_plan_element_type_id = pet.element_type_id
278        and    P_calculation_date between pet.effective_start_date and
279                                          pet.effective_end_date
280        and    pet.element_type_id              = pel.element_type_id
281        and    P_calculation_date between pel.effective_start_date and
282                                          pel.effective_end_date
283        and    pel.element_link_id              = pee.element_link_id
284        and    pee.assignment_id                = P_assignment_id
285        and    P_calculation_date between pee.effective_start_date and
286                                          pee.effective_end_date
287        and    piv.element_type_id              =
288                                          pap.accrual_plan_element_type_id
289        and    piv.name                         = 'Continuous Service Date'
290        and    P_calculation_date between piv.effective_start_date and
291                                          piv.effective_end_date
292        and    pev.element_entry_id             = pee.element_entry_id
293        and    pev.input_value_id + 0           = piv.input_value_id
294        and    P_calculation_date between pev.effective_start_date and
295                                          pev.effective_end_date;
296 --
297 --
298 -- Local Variable
299 --
300 l_asg_eff_start_date date   := null;
301 l_asg_eff_end_date   date   := null;
302 l_business_group_id  number := null;
303 l_service_start_date date   := null;
304 l_termination_date   date   := null;
305 --
306 l_calc_period_num    number := 0;
307 l_calc_start_date    date   := null;
308 l_calc_end_date      date   := null;
309 --
310 l_number_of_period   number := 0;
311 --
312 l_acc_plan_type_id   number := 0;
313 l_acc_plan_ele_type  number := 0;
314 l_acc_uom            varchar2(30) := null;
315 l_inelig_period      varchar2(30) := null;
316 l_inelig_p_length    number := 0;
317 l_accrual_start      varchar2(30) := null;
318 l_cont_service_date  date := null;
319 l_csd_screen_value   varchar2(30) := null;
320 l_element_entry_id   number := 0;
321 --
322 l_plan_start_date    date   := null;
323 --
324 l_total_accrual      number := 0;
325 l_plan_accrual       number := 0;
326 --
327 l_temp               varchar2(30) := null;
328 l_temp_date          date         := null;
329 --
330 p_param_first_pstdt  date   := null;
331 p_param_first_pendt  date   := null;
332 p_param_first_pnum   number := 0;
333 p_param_acc_calc_edt date   := null;
334 p_param_acc_calc_pno number := 0;
335 l_plan_enrl_date date;          --14022134
336 --
337 -- Main process
338 --
339 BEGIN
340 --
341   P_payroll_id         := 0;
342   P_first_period_start := null;
343   P_first_period_end   := null;
344   P_last_period_start  := null;
345   P_last_period_end    := null;
346 --
347   hr_utility.set_location('get_accrual',5);
348 ---
349 --- If both param null. RETURN
350 --
351   IF P_plan_id is null AND P_plan_category is null
352   THEN
353     hr_utility.set_message(801, 'HR_6153_ALL_PROCEDURE_FAIL');
354     hr_utility.set_message_token('PROCEDURE','get_accrual');
355     hr_utility.set_message_token('STEP','1');
356     hr_utility.raise_error;
357   END IF;
358 
359   OPEN  csr_get_payroll(P_assignment_id, P_calculation_date);
360   FETCH csr_get_payroll INTO P_payroll_id,
361                              l_asg_eff_start_date,
362                              l_asg_eff_end_date,
363                              l_business_group_id,
364                              l_service_start_date,
365                              l_termination_date;
366   IF csr_get_payroll%NOTFOUND
367   THEN
368     CLOSE csr_get_payroll;
369     hr_utility.set_message(801, 'HR_6153_ALL_PROCEDURE_FAIL');
370     hr_utility.set_message_token('PROCEDURE','get_accrual');
371     hr_utility.set_message_token('STEP','2');
372     hr_utility.raise_error;
373   END IF;
374   CLOSE csr_get_payroll;
375   hr_utility.set_location('get_accrual',10);
376 --
377 -- Get start and end date for the Calculation date
378 --
379   hr_utility.set_location('get_accrual',15);
380 
381   OPEN  csr_get_period(P_payroll_id, P_calculation_date);
382   FETCH csr_get_period INTO l_calc_period_num,
383                             l_calc_start_date,
384                             l_calc_end_date;
385   IF csr_get_period%NOTFOUND
386   THEN
387     CLOSE csr_get_period;
388       hr_utility.set_message(801,'HR_51731_PTO_DATE_OUT_TIMEPRD');
389    -- hr_utility.set_message(801, 'HR_6153_ALL_PROCEDURE_FAIL');
390    -- hr_utility.set_message_token('PROCEDURE','get_accrual');
391    -- hr_utility.set_message_token('STEP','3');
392     hr_utility.raise_error;
393   END IF;
394   CLOSE csr_get_period;
395   hr_utility.set_location('get_accrual',20);
396 --
397 -- Partial first period if start
398 --
399 -- Set return dates for the net process if nothing to accrue in this period
400 --
401       P_start_date := l_calc_start_date;
402       P_end_date   := P_calculation_date;
403 --
404 --
405 /*
406   -- 14 JUN 1995: HPARICHA removed this logic until it can be explained why it's
407   -- required.  "Partial first period is start"..?..
408 
409   IF l_calc_period_num = 1 AND P_calculation_date < l_calc_end_date
410   THEN
411     P_accrual := 0;
412   ELSE
413 */
414 
415 --
416 -- Get total number of periods for the year of calculation
417 --
418 
419   OPEN  csr_get_total_periods(P_payroll_id, l_calc_end_date);
420   FETCH csr_get_total_periods INTO P_first_period_start,
421                                    P_first_period_end,
422                                    P_last_period_start,
423                                    P_last_period_end,
424                                    l_number_of_period;
425   IF csr_get_total_periods%NOTFOUND
426   THEN
427     CLOSE csr_get_total_periods;
428     hr_utility.set_message(801, 'HR_6153_ALL_PROCEDURE_FAIL');
429     hr_utility.set_message_token('PROCEDURE','get_accrual');
430     hr_utility.set_message_token('STEP','4');
431     hr_utility.raise_error;
432   END IF;
433   CLOSE csr_get_total_periods;
434   -- Set l_number_of_period such that it is based on NUMBER_PER_FISCAL_YEAR
435   -- for period type of payroll.  Ie. The number returned from
436   -- csr_get_total_periods is the number of periods defined for this payroll
437   -- in the given calendar year - so payrolls defined mid-year accrue at a
438   -- different rate than if it had a full year of payroll periods.
439   --
440   SELECT number_per_fiscal_year
441   INTO   l_number_of_period
442   FROM   per_time_period_types TPT,
443          pay_payrolls_f PPF
444   WHERE  TPT.period_type = PPF.period_type
445   AND    PPF.payroll_id = P_payroll_id
446   AND    l_calc_end_date BETWEEN PPF.effective_start_date
447 			     AND PPF.effective_end_date;
448   --
449   hr_utility.set_location('get_accrual',25);
450   --
451   -- In case of carry over a dummy date of 31-JUL-YYYY is passed in order to get
452   -- the no. of periods first and last period od that year etc. Check if P_mode
453   -- is 'C' then set the calculation date to the end date of last period and
454   -- get period number for that period again.
455   --
456   hr_utility.set_location('get_accrual',27);
457   IF P_mode = 'C'
458   THEN
459     l_calc_period_num := l_number_of_period;
460     l_calc_start_date := P_last_period_start;
461     l_calc_end_date   := P_last_period_end;
462     P_calculation_date:= nvl(l_termination_date,P_last_period_end);
463   END IF;
464   --
465   --
466   /* Replacing these 3 lines w/call to csr_get_period for 1st period start date.
467    Remember the first period number is NOT NECESSARILY "1".
468    "p_param_first..." become the beginning of accrual time, need to be
469    set according to accrual plans' "Accrual Start Rule" - ie.
470 	Accrual Start Rule	Accrual Begins
471 	Beginning of Year	Beginning of year FOLLOWING year of hire.
472 	Hire Date		As of beginning of month of hire.
473 	6 Months After Hire	As of beginning of the first full pay period
474 				following the 6 month anniversary of hire date.
475 
476    Note: "Hire Date" above refers to the actual period of service hire date
477 	 OR the "Continuous Service Date" element entry value on the accrual
478 	 plan element entry.  This "Continuous Service Date" entry value
479          overrides the employee's period of service start (Hire) date.
480 
481    ALSO: Does "Beginning of Year" need to deal with case of
482          Hire Date = '01-JAN-...." of a calendar year?
483 
484   p_param_first_pnum  := 1;
485   p_param_first_pstdt := P_first_period_start;
486   p_param_first_pendt := P_first_period_end;
487 
488   */
489 
490   hr_utility.set_location('get_accrual',30);
491   OPEN  csr_get_period (P_payroll_id, P_first_period_start);
492   FETCH csr_get_period INTO p_param_first_pnum,
493                             p_param_first_pstdt,
494                             p_param_first_pendt;
495   IF csr_get_period%NOTFOUND
496   THEN
497      CLOSE csr_get_period;
498      hr_utility.set_message(801, 'HR_6153_ALL_PROCEDURE_FAIL');
499      hr_utility.set_message_token('PROCEDURE','get_accrual');
500      hr_utility.set_message_token('STEP','5');
501      hr_utility.raise_error;
502   END IF;
503   CLOSE csr_get_period;
504   --
505   --  Check termination date and adjust end date of the last calc Period
506   --
507   OPEN  csr_get_period (P_payroll_id,
508                         nvl(l_termination_date,P_calculation_date));
509   FETCH csr_get_period INTO p_param_acc_calc_pno,
510                             l_temp_date,
511                             p_param_acc_calc_edt;
512   IF csr_get_period%NOTFOUND
513   THEN
514 	CLOSE csr_get_period;
515         hr_utility.set_message(801, 'HR_6153_ALL_PROCEDURE_FAIL');
516         hr_utility.set_message_token('PROCEDURE','get_accrual');
517         hr_utility.set_message_token('STEP','6');
518         hr_utility.raise_error;
519   END IF;
520   CLOSE csr_get_period;
521 --
522   hr_utility.set_location('get_accrual',35);
523 --
524 -- No accruals for the partial periods
525 --
526   IF nvl(l_termination_date,P_calculation_date) < p_param_acc_calc_edt
527   THEN
528      hr_utility.set_location('get_accrual',36);
529      p_param_acc_calc_pno := p_param_acc_calc_pno - 1;
530      p_param_acc_calc_edt := l_temp_date - 1;
531 
532   END IF;
533 --
534 -- Open plan cursor and check at least one plan should be there
535 --
536   hr_utility.set_location('get_accrual',40);
537   OPEN  csr_get_plan_details(l_business_group_id);
538   FETCH csr_get_plan_details INTO l_acc_plan_type_id,
539                                   l_acc_plan_ele_type,
540                                   l_acc_uom,
541                                   l_inelig_period,
542                                   l_inelig_p_length,
543                                   l_accrual_start,
544                                   l_csd_screen_value,
545                                   l_element_entry_id;
546   IF csr_get_plan_details%NOTFOUND
547   THEN
548     CLOSE csr_get_plan_details;
549     hr_utility.set_message(801, 'HR_6153_ALL_PROCEDURE_FAIL');
550     hr_utility.set_message_token('PROCEDURE','get_accrual');
551     hr_utility.set_message_token('STEP','7');
552     hr_utility.raise_error;
553   END IF;
554 --
555 -- Loop thru all the plans and call function to calc. accruals for a plan
556 --
557   hr_utility.set_location('get_accrual',45);
558   LOOP
559     l_temp_date := null;
560     --
561     hr_utility.set_location('get_accrual',50);
562     --
563     --	"Continous Service Date" is ALWAYS determined by:
564     --	1. "Continuous Service Date" entry value on accrual plan.
565     --	2. Hire Date of current period of service (ie. in absence of 1.)
566     --
567     IF l_csd_screen_value is null
568     THEN
569        hr_utility.set_location('get_accrual',51);
570        l_cont_service_date := l_service_start_date;
571     ELSE
572        hr_utility.set_location('get_accrual',52);
573        l_cont_service_date := fnd_date.canonical_to_date(l_csd_screen_value);
574     END IF;
575     --
576     -- The "p_param_first..." variables determine when accrual begins for this
577     -- plan and assignment.  Accrual begins according to "Accrual Start Rule" and
578     -- hire date as follows:
579     -- Accrual Start Rule	Begin Accrual on...
580     -- ==================	==================================================
581     -- Beginning of Year	First period of new calendar year FOLLOWING hire date.
582     -- Hire Date		First period following hire date.
583     -- 6 Months After Hire	First period following 6 month anniversary of hire date.
584     -- NOTE: "Hire Date" is the "Continuous Service Date" as determined above.
585     --
586       IF l_accrual_start = 'BOY'
587       THEN
588           -- 14022134
589         IF l_csd_screen_value is null then
590         hr_utility.set_location('get_accrual',811);
591 
592        select min (pee.effective_start_date) into l_plan_enrl_date
593        from pay_element_entries_f pee,
594             pay_element_links_f pel,
595             pay_element_types_f pet
596        where pel.element_link_id = pee.element_link_id
597        and   pel.element_type_id = pet.element_type_id
598        and   pee.assignment_id = p_assignment_id
599        and   pet.element_type_id = (select accrual_plan_element_type_id
600 	                            from pay_accrual_plans
601 	                            where accrual_plan_id = p_plan_id)
602        and   p_calculation_date between pee.effective_start_date
603 			   and pee.effective_end_date;
604 
605       if l_plan_enrl_date > l_service_start_date
606       then
607 	  hr_utility.set_location('get_accrual',820);
608           l_cont_service_date :=l_plan_enrl_date;
609       end if;
610 	 hr_utility.set_location('get_accrual',830);
611       end if;
612       -- 14022134
613 
614        -- Fix for the bug 14837603
615          -- l_temp_date := TRUNC(ADD_MONTHS(l_cont_service_date,12),'YEAR');
616            if months_between (fnd_date.canonical_to_date(l_csd_screen_value),p_calculation_date) < 12 then
617           l_temp_date := TRUNC(ADD_MONTHS(l_cont_service_date,12),'YEAR');
618 	  hr_utility.set_location('get_accrual :l_temp_date' ||l_temp_date,821);
619 
620 	 ELSE
621 
622 	 l_temp_date :=p_calculation_date;
623 	 hr_utility.set_location('get_accrual :l_temp_date' ||l_temp_date,822);
624 	 END IF;
625 
626           OPEN  csr_get_period (P_payroll_id, p_calculation_date);
627 
628          -- OPEN  csr_get_period (P_payroll_id, l_temp_date);
629 
630           FETCH csr_get_period INTO p_param_first_pnum,
631                                     p_param_first_pstdt,
632                                     p_param_first_pendt;
633           IF csr_get_period%NOTFOUND
634           THEN
635              CLOSE csr_get_period;
636              hr_utility.set_message(801, 'HR_6153_ALL_PROCEDURE_FAIL');
637              hr_utility.set_message_token('PROCEDURE','get_accrual');
638              hr_utility.set_message_token('STEP','8');
639              hr_utility.raise_error;
640           END IF;
641           CLOSE csr_get_period;
642           l_temp_date := null;
643       ELSIF l_accrual_start = 'HD'
644       THEN
645         NULL;
646           -- p_param_first... vars have been set above (location get_accrual.30)
647       ELSIF l_accrual_start = 'PLUS_SIX_MONTHS'
648       THEN
649 	  --
650 	  -- Actually get the period in force the day before the six months is up.
651 	  -- This is because we subsequently get the following period as the one
652 	  -- in which accruals should start. If a period starts on the six
653 	  -- month anniversary, the asg should qualify from that period, and
654 	  -- not have to wait for the next one. Example:
655 	  --
656 	  -- Assume monthly periods.
657 	  --
658 	  -- l_cont_service_date = 02-Jan-95
659 	  -- six month anniversary = 02-Jul-95
660 	  -- accruals start on 01-Aug-95
661 	  --
662 	  -- l_cont_service_date = 01-Jan-95
663 	  -- six month anniversary = 01-Jul-95
664 	  -- accruals should start on 01-Jul-95, not 01-Aug-95
665 	  --
666 	  -- RMF 19-Jan-96.
667 	  --
668           OPEN  csr_get_period (P_payroll_id,
669 		  	        ADD_MONTHS(l_cont_service_date,6) -1 );
670           FETCH csr_get_period INTO p_param_first_pnum,
671                                     p_param_first_pstdt,
672 				    l_temp_date;
673           IF csr_get_period%NOTFOUND
674           THEN
675              CLOSE csr_get_period;
676              hr_utility.set_message(801, 'HR_6153_ALL_PROCEDURE_FAIL');
677              hr_utility.set_message_token('PROCEDURE','get_accrual');
678              hr_utility.set_message_token('STEP','10');
679              hr_utility.raise_error;
680           END IF;
681           CLOSE csr_get_period;
682           --
683           OPEN  csr_get_period (P_payroll_id, l_temp_date + 1);
684           FETCH csr_get_period INTO p_param_first_pnum,
685                                     p_param_first_pstdt,
686                                     p_param_first_pendt;
687           IF csr_get_period%NOTFOUND
688           THEN
689              CLOSE csr_get_period;
690              hr_utility.set_message(801, 'HR_6153_ALL_PROCEDURE_FAIL');
691              hr_utility.set_message_token('PROCEDURE','get_accrual');
692              hr_utility.set_message_token('STEP','11');
693              hr_utility.raise_error;
694           END IF;
695           CLOSE csr_get_period;
696           l_temp_date := null;
697       END IF;
698       hr_utility.set_location('get_accrual',55);
699 --
700 --    Add period of ineligibility
701 --
702       IF l_accrual_start   <> 'PLUS_SIX_MONTHS'  AND
703          l_inelig_p_length >  0
704       THEN
705         hr_utility.set_location('get_accrual',60);
706         IF l_inelig_period = 'BM'
707         THEN
708           l_temp_date := ADD_MONTHS(l_cont_service_date,
709                                     (l_inelig_p_length * 2));
710         ELSIF l_inelig_period = 'F'
711         THEN
712           l_temp_date := fnd_date.canonical_to_date(to_char(l_cont_service_date +
713 	                  (l_inelig_p_length * 14),'YYYY/MM/DD'));
714         ELSIF l_inelig_period = 'CM'
715         THEN
716           l_temp_date := ADD_MONTHS(l_cont_service_date,
717                                     l_inelig_p_length);
718         ELSIF l_inelig_period = 'LM'
719         THEN
720           l_temp_date := fnd_date.canonical_to_date(to_char(l_cont_service_date +
721 	                     (l_inelig_p_length * 28),'YYYY/MM/DD'));
722         ELSIF l_inelig_period = 'Q'
723         THEN
724           l_temp_date := ADD_MONTHS(l_cont_service_date,
725                                     (l_inelig_p_length * 3));
726         ELSIF l_inelig_period = 'SM'
727         THEN
728           l_temp_date := ADD_MONTHS(l_cont_service_date,
729                                    (l_inelig_p_length/2));
730         ELSIF l_inelig_period = 'SY'
731         THEN
732           l_temp_date := ADD_MONTHS(l_cont_service_date,
733                                     (l_inelig_p_length * 6));
734         ELSIF l_inelig_period = 'W'
735         THEN
736           l_temp_date := fnd_date.canonical_to_date(to_char(l_cont_service_date +
737 	                    (l_inelig_p_length * 7),'YYYY/MM/DD'));
738         ELSIF l_inelig_period = 'Y'
739         THEN
740           l_temp_date := ADD_MONTHS(l_cont_service_date,
741                                     (l_inelig_p_length * 12));
742         END IF;
743       END IF;
744 
745 --
746 -- Determine start and end date and setup return parmas.
747 --    check Period of Service start date, plan element entry start date
748 --    if later then first period start. Accrual period start date accordingly.
749 --
750       hr_utility.set_location('get_accrual',65);
751       select min(effective_start_date)
752       into   l_plan_start_date
753       from   pay_element_entries_f
754       where  element_entry_id = l_element_entry_id;
755       hr_utility.set_location('get_accrual',67);
756 ---
757 
758 --- Set the return params
759 --
760       P_cont_service_date := l_cont_service_date;
761       P_start_date := GREATEST(l_service_start_date,l_cont_service_date,
762                               l_plan_start_date,P_first_period_start);
763       P_end_date   := LEAST(NVL(L_termination_date,P_calculation_date)
764                              ,P_calculation_date);
765 
766 --
767     hr_utility.set_location('get_accrual',68);
768     IF ( l_temp_date is not null AND
769          l_temp_date >= p_param_acc_calc_edt ) OR
770        l_cont_service_date >= p_param_acc_calc_edt OR
771 
772        p_param_first_pstdt >= p_param_acc_calc_edt
773 
774     THEN
775       hr_utility.set_location('get_accrual',70);
776       l_plan_accrual := 0;
777     ELSE
778       --
779       -- Set the Start Date appropriately.
780       -- #305751. Don't understand why this code is here at all, seeing as these
781       -- parameters have already been set up above. However, I'll leave the code
782       -- alone, except to prevent it from resetting a later start date to earlier,
783       -- which sometimes happened on 6 Month plans.  Added a test to prevent the
784       -- date being reset if it's already been set, to later than l_temp_date
785       -- below. RMF 18-Jan-96.
786       --
787       l_temp_date := GREATEST(l_service_start_date,l_cont_service_date,
788                               l_plan_start_date);
789       --
790       IF  l_temp_date > P_first_period_start
791           AND l_temp_date > nvl(p_param_first_pstdt, l_temp_date - 1)
792       THEN
793            hr_utility.set_location('get_accrual',71);
794            OPEN  csr_get_period (P_payroll_id, l_temp_date);
795            FETCH csr_get_period INTO p_param_first_pnum,
796                                      p_param_first_pstdt,
797                                      p_param_first_pendt;
798            IF csr_get_period%NOTFOUND
799            THEN
800 	      CLOSE csr_get_period;
801               hr_utility.set_message(801, 'HR_6153_ALL_PROCEDURE_FAIL');
802               hr_utility.set_message_token('PROCEDURE','get_accrual');
803               hr_utility.set_message_token('STEP','12');
804               hr_utility.raise_error;
805            END IF;
806            CLOSE csr_get_period;
807            hr_utility.set_location('get_accrual',80);
808       --
809       -- No Accruals fro the partial periods. First period to start the
810       -- accrual will be next one.
811       --
812            IF l_temp_date > p_param_first_pstdt
813            THEN
814               hr_utility.set_location('get_accrual',85);
815               p_param_first_pendt := p_param_first_pendt +1;
816               OPEN  csr_get_period (P_payroll_id, p_param_first_pendt);
817               FETCH csr_get_period INTO p_param_first_pnum,
818                                          p_param_first_pstdt,
819                                          p_param_first_pendt;
820               IF csr_get_period%NOTFOUND
821               THEN
822 	         CLOSE csr_get_period;
823                  hr_utility.set_message(801, 'HR_6153_ALL_PROCEDURE_FAIL');
824                  hr_utility.set_message_token('PROCEDURE','get_accrual');
825                  hr_utility.set_message_token('STEP','13');
826                  hr_utility.raise_error;
827               END IF;
828               CLOSE csr_get_period;
829            END IF;
830       END IF;
831       --
832       --      Call Function to Calculate accruals for a plan
833       --
834       IF p_param_acc_calc_edt < P_first_period_end
835       THEN
836         l_plan_accrual := 0;
837       ELSE
838       --
839         hr_utility.set_location('get_accrual_for_plan',90);
840         pay_us_pto_accrual.get_accrual_for_plan
841                   ( p_plan_id                 => l_acc_plan_type_id,
842                     p_first_p_start_date      => p_param_first_pstdt,
843                     p_first_p_end_date        => p_param_first_pendt,
844                     p_first_calc_P_number     => p_param_first_pnum,
845                     p_accrual_calc_p_end_date => p_param_acc_calc_edt,
846                     P_accrual_calc_P_number   => p_param_acc_calc_pno,
847                     P_number_of_periods       => l_number_of_period,
848                     P_payroll_id              => P_payroll_id,
849                     P_assignment_id           => P_assignment_id,
850                     P_plan_ele_type_id        => l_acc_plan_ele_type,
851                     P_continuous_service_date => l_cont_service_date,
852                     P_Plan_accrual            => l_plan_accrual,
853                     P_current_ceiling         => P_current_ceiling,
854                     P_current_carry_over      => P_current_carry_over);
855       END IF;
856       --
857     END IF;
858 --
859 --    Add accrual to the total and Fetch next set of plan
860 --
861     hr_utility.set_location('get_accrual',95);
862     l_total_accrual := l_total_accrual + l_plan_accrual;
863     l_plan_accrual  := 0;
864 
865     FETCH csr_get_plan_details INTO l_acc_plan_type_id,
866                                     l_acc_plan_ele_type,
867                                     l_acc_uom,
868                                     l_inelig_period,
869                                     l_inelig_p_length,
870                                     l_accrual_start,
871                                     l_csd_screen_value,
872                                     l_element_entry_id;
873 --
874 
875     EXIT WHEN csr_get_plan_details%NOTFOUND;
876     hr_utility.set_location('get_accrual',100);
877 --
878   END LOOP;
879 --
880   CLOSE csr_get_plan_details;
881 --
882   IF l_total_accrual is null
883   THEN
884      hr_utility.set_location('get_accrual',105);
885      l_total_accrual := 0;
886   END IF;
887   hr_utility.set_location('get_accrual',110);
888   l_total_accrual := round(l_total_accrual,3);
889   P_accrual := l_total_accrual;
890 --
891 -- Partial first period if end
892 --
893 /*
894  END IF; -- Start Date...partial eh?
895 */
896 
897 --
898 END accrual_calc_detail;
899 --
900 ---------------- get_accrual_for_plan -------------------------------------
901 --
902 PROCEDURE get_accrual_for_plan
903                     ( p_plan_id                 Number,
904                       p_first_p_start_date      date,
905                       p_first_p_end_date        date,
906                       p_first_calc_P_number     number,
907                       p_accrual_calc_p_end_date date,
908                       P_accrual_calc_P_number   number,
909                       P_number_of_periods       number,
910                       P_payroll_id              number,
911                       P_assignment_id           number,
912                       P_plan_ele_type_id        number,
913                       P_continuous_service_date date,
914                       P_Plan_accrual            OUT nocopy number,
915                       P_current_ceiling         OUT nocopy number,
916                       P_current_carry_over      OUT nocopy number) IS
917 --
918 --
919 CURSOR csr_all_asg_status is
920        select a.effective_start_date,
921               a.effective_end_date,
922               b.PER_SYSTEM_STATUS
923        from   per_assignments_f           a,
924               per_assignment_status_types b
925        where  a.assignment_id       = P_assignment_id
926        and    a.effective_end_date between p_first_p_start_date and
927                                    to_date('31-12-4712','DD-MM-YYYY')
928        and    a.ASSIGNMENT_STATUS_TYPE_ID =
929                                       b.ASSIGNMENT_STATUS_TYPE_ID;
930 --
931 --
932 CURSOR csr_get_bands (P_time_worked number ) is
933        select annual_rate,
934               ceiling,
935               lower_limit,
936               upper_limit,
937               max_carry_over
938        from   pay_accrual_bands
939        where  accrual_plan_id     = P_plan_id
940        and    P_time_worked      >= lower_limit
941        and    P_time_worked      <  upper_limit;
942 --
943 -- #305751 I think this cursor is intended to get all the time periods over
944 -- which the accrual should be calculated. However, it looks as if the select
945 -- only gets the numbered periods for which the asg qualified in its first year.
946 -- So, if they qualified from Aug in year 1, this cursor only ever returns
947 -- the periods from Aug onwards. Perhaps this was put in to make the first
948 -- year work correctly, but it works too widely.
949 --
950 -- Revised the cursor so it picks up all the time periods from the start of
951 -- year to the current point unless the asg only qualified for the plan at
952 -- some point during the year, in which case start from then. The old version
953 -- of the cursor is retained here, commented out.
954 --
955 -- The decode in the cursor means: "If the year for which we're doing the
956 -- calculation is also the year in which the asg qualified for the plan, just
957 -- take it from the first qualifying period; otherwise, take it from the
958 -- first period of the year. RMF 18-Jan96.
959 --
960 -- CURSOR csr_get_time_periods is
961 --        select start_date,
962 --               end_date,
963 --              period_num
964 --       from   per_time_periods
965 --       where  to_char(end_date,'YYYY') =
966 --                         to_char(p_first_p_end_date,'YYYY')
967 --       and    end_date                  <= p_accrual_calc_p_end_date
968 --       and    period_num                >= p_first_calc_P_number
969 --       and    payroll_id                 = p_payroll_id
970 --ORDER by period_num;
971 --
972 CURSOR csr_get_time_periods is
973        select start_date,
974               end_date,
975               period_num
976        from   per_time_periods
977        where  to_char(end_date,'YYYY') =
978                          to_char(p_accrual_calc_p_end_date,'YYYY')
979        and    end_date                 <= p_accrual_calc_p_end_date
980        and    period_num               >=
981 		decode (to_char(p_first_p_start_date,'YYYY'),
982 			to_char(p_accrual_calc_p_end_date,'YYYY'),
983 			p_first_calc_P_number, 1)
984        and    payroll_id                 = p_payroll_id
985 ORDER by period_num;
986 --
987 --
988 --Local varaiables
989 l_start_Date         date :=null;
990 l_end_date           date :=null;
991 l_period_num         number := 0;
992 l_asg_eff_start_date date := null;
993 l_asg_eff_end_date   date := null;
994 l_asg_status         varchar2(30) := null;
995 l_acc_rate_pp_1      number := 0;
996 l_acc_rate_pp_2      number := 0;
997 l_acc_deds           number := 0;
998 l_annual_rate        number := 0;
999 l_ceiling_1          number := 0;
1000 l_ceiling_2          number := 0;
1001 l_carry_over_1       number := 0;
1002 l_carry_over_2       number := 0;
1003 l_lower_limit        number := 0;
1004 l_upper_limit        number := 0;
1005 l_year_1             number := 0;
1006 l_year_2             number := 0;
1007 l_accrual            number := 0;
1008 l_temp               number := 0;
1009 l_temp2              varchar2(30) := null;
1010 l_band_change_date   date   := null;
1011 l_ceiling_flag       varchar2(1) := 'N';
1012 l_curr_p_stdt        date   := null;
1013 l_curr_p_endt        date   := null;
1014 l_curr_p_num         number := 0;
1015 l_mult_factor        number := 0;
1016 l_unpaid_day         number := 0;
1017 l_vac_taken          number := 0;
1018 l_prev_end_date      date   := null;
1019 l_running_total      number := 0;
1020 l_curr_p_acc         number := 0;
1021 l_working_day        number := 0;
1022 l_curr_ceiling       number := 0;
1023 --
1024 --
1025 BEGIN
1026 --
1027   hr_utility.set_location('get_accrual_for_plan',1);
1028   l_year_1 := TRUNC(ABS(months_between(P_continuous_service_date,
1029                              P_first_p_end_date)/12));
1030   l_year_2 := TRUNC(ABS(months_between(P_continuous_service_date,
1031                              p_accrual_calc_p_end_date)/12));
1032 
1033 --
1034 -- Get the band details using the years of service.
1035 --
1036   OPEN  csr_get_bands (l_year_1);
1037   FETCH csr_get_bands INTO l_annual_rate,l_ceiling_1,
1038                            l_lower_limit,l_upper_limit,
1039                            l_carry_over_1;
1040   hr_utility.set_location('get_accrual_for_plan',5);
1041 
1042   IF csr_get_bands%NOTFOUND THEN
1043      l_acc_rate_pp_1 := 0;
1044   ELSE
1045      l_acc_rate_pp_1 := l_annual_rate/P_number_of_periods;
1046      IF l_ceiling_1 is not null THEN
1047         l_ceiling_flag := 'Y';
1048      END IF;
1049   END IF;
1050   CLOSE csr_get_bands;
1051   hr_utility.set_location('get_accrual_for_plan',10);
1052   --
1053   IF l_year_2 < l_upper_limit and l_acc_rate_pp_1 > 0 THEN
1054      l_acc_rate_pp_2 := 0;
1055   ELSE
1056      hr_utility.set_location('get_accrual_for_plan',15);
1057      OPEN  csr_get_bands (l_year_2);
1058      FETCH csr_get_bands INTO l_annual_rate,l_ceiling_2,
1059                               l_lower_limit,l_upper_limit,
1060                               l_carry_over_2;
1061 
1062      IF csr_get_bands%NOTFOUND THEN
1063 --        CLOSE csr_get_bands;   -- bug 672443
1064         l_accrual := 0;
1065         P_current_ceiling    := 0;
1066         P_current_carry_over := 0;
1067         CLOSE csr_get_bands;
1068         GOTO exit_out;
1069      ELSE
1070         l_acc_rate_pp_2 := l_annual_rate/P_number_of_periods;
1071         IF l_ceiling_1 is not null THEN
1072            l_ceiling_flag := 'Y';
1073         END IF;
1074         CLOSE csr_get_bands;
1075      END IF;
1076   END IF;
1077   hr_utility.set_location('get_accrual_for_plan',20);
1078 --
1079 --
1080   IF ((l_acc_rate_pp_1 <> l_acc_rate_pp_2) AND
1081        l_acc_rate_pp_2 <> 0 ) THEN
1082      l_temp := trunc(ABS(months_between(P_continuous_service_date,
1083                              p_accrual_calc_p_end_date))/12) * 12 ;
1084 
1085      l_band_change_date := ADD_MONTHS(P_continuous_service_date,l_temp);
1086 
1087   ELSE
1088      l_band_change_date := (p_accrual_calc_p_end_date + 2);
1089 
1090   END IF;
1091   --
1092   -- Set output params.
1093   --
1094   IF l_ceiling_2 = 0 OR l_ceiling_2 is null
1095   THEN
1096      P_current_ceiling := l_ceiling_1;
1097   ELSE
1098      P_current_ceiling := l_ceiling_2;
1099   END IF;
1100   --
1101   IF l_carry_over_2 = 0 OR l_carry_over_2 is null
1102   THEN
1103      P_current_carry_over := l_carry_over_1;
1104   ELSE
1105      P_current_carry_over := l_carry_over_2;
1106   END IF;
1107   --
1108   hr_utility.set_location('get_accrual_for_plan',25);
1109   OPEN  csr_all_asg_status;
1110   FETCH csr_all_asg_status into l_asg_eff_start_date,
1111                                 l_asg_eff_end_date,
1112                                 l_asg_status;
1113   hr_utility.set_location('get_accrual_for_plan',30);
1114   --
1115   -- Check if calc method should use ceiling calculation or Non-ceiling
1116   -- calculation. For simplicity if there is any asg. status change then
1117   -- ceiling calculation method is used.
1118   --
1119   IF l_ceiling_flag = 'N'
1120      and  (p_first_p_end_date   	>= l_asg_eff_start_date
1121      and   p_accrual_calc_p_end_date    <= l_asg_eff_end_date
1122      and   l_asg_status                  =  'ACTIVE_ASSIGN') THEN
1123     --
1124     -- Non Ceiling Calc
1125     --
1126     OPEN  csr_get_period(P_Payroll_id, l_band_change_date);
1127     FETCH csr_get_period INTO l_curr_p_num,l_curr_p_stdt,l_curr_p_endt;
1128     hr_utility.set_location('get_accrual_for_plan',35);
1129     IF csr_get_period%NOTFOUND THEN
1130       CLOSE csr_get_period;
1131       hr_utility.set_message(801, 'HR_6153_ALL_PROCEDURE_FAIL');
1132       hr_utility.set_message_token('PROCEDURE','get_accrual_for_plan');
1133       hr_utility.set_message_token('STEP','14');
1134       hr_utility.raise_error;
1135     END IF;
1136     CLOSE csr_get_period;
1137 --
1138 -- gpaytonm 15-nov mod - added close csr_get_period
1139 --
1140     --
1141     hr_utility.set_location('get_accrual_for_plan',40);
1142     if l_curr_p_num = 1 AND
1143       p_accrual_calc_p_end_date < l_band_change_date
1144     then
1145       l_curr_p_num := P_number_of_periods;
1146     elsif p_accrual_calc_p_end_date >= l_band_change_date  then
1147       l_curr_p_num := l_curr_p_num - 1;
1148     else
1149       l_curr_p_num := P_accrual_calc_P_number;
1150     end if;
1151     --
1152     -- Entitlement from first period to Band change date.
1153     --
1154     l_accrual := l_acc_rate_pp_1 * (l_curr_p_num - (p_first_calc_P_number - 1));
1155     hr_utility.set_location('get_accrual_for_plan',45);
1156     --
1157     -- Entitlement from Band change date to Calc. date
1158     --
1159     IF p_accrual_calc_p_end_date >= l_band_change_date  THEN
1160       l_accrual := l_accrual + l_acc_rate_pp_2 * (P_accrual_calc_P_number - l_curr_p_num);
1161     END IF;
1162  ELSE
1163    --
1164    -- Ceiling Calc
1165    --
1166    hr_utility.set_location('get_accrual_for_plan',50);
1167    OPEN  csr_get_time_periods;
1168    l_running_total := 0;
1169    l_curr_p_acc    := 0;
1170    LOOP
1171      hr_utility.set_location('get_accrual_for_plan',55);
1172      FETCH csr_get_time_periods into l_start_Date,
1173                                        	l_end_date,
1174                                        	l_period_num;
1175      EXIT WHEN csr_get_time_periods%NOTFOUND;
1176      IF l_period_num > P_accrual_calc_P_number then
1177        EXIT;
1178      END IF;
1179   	--
1180   	-- #305751 Remove the following IF statement. The csr_get_time_periods cursor
1181   	-- already restricts which period numbers we get.
1182   	--
1183   	--   IF l_period_num >= p_first_calc_P_number then
1184   	--      Check for Any assignment status change in the current period
1185   	--
1186         	l_mult_factor   := 1;
1187         	l_working_day   := 0;
1188         	l_unpaid_day    := 0;
1189         	l_vac_taken     := 0;
1190         	l_prev_end_date := l_asg_eff_end_date;
1191         	hr_utility.set_location('get_accrual_for_plan',60);
1192         	--
1193         	IF l_asg_eff_end_date between l_start_Date and l_end_date
1194         	THEN
1195           	  IF l_asg_status <> 'ACTIVE_ASSIGN' THEN
1196              	  l_unpaid_day := get_working_days(l_start_Date,
1197                                               l_asg_eff_end_date);
1198             	END IF;
1199           	--
1200           	--
1201           	hr_utility.set_location('get_accrual_for_plan',65);
1202           	LOOP
1203             		hr_utility.set_location('get_accrual_for_plan',70);
1204             		l_prev_end_date := l_asg_eff_end_date;
1205             		FETCH csr_all_asg_status into 	l_asg_eff_start_date,
1206                                          		l_asg_eff_end_date,
1207                                           		l_asg_status;
1208             		IF csr_all_asg_status%NOTFOUND THEN
1209                		  CLOSE csr_all_asg_status;
1210                		  EXIT;
1211             		ELSIF l_asg_status <> 'ACTIVE_ASSIGN'  and
1212                   	  l_asg_eff_start_date <= l_end_date
1213             		THEN
1214                		  l_unpaid_day := l_unpaid_day +
1215                           get_working_days(l_asg_eff_start_date,
1216                           least(l_end_date,l_asg_eff_end_date));
1217             		END IF;
1218             	EXIT WHEN l_asg_eff_end_date > l_end_date;
1219           	END LOOP;
1220            	--
1221            	--
1222  ELSIF csr_all_asg_status%ISOPEN and l_asg_status <> 'ACTIVE_ASSIGN'   THEN
1223    l_mult_factor   := 0;
1224    hr_utility.set_location('get_accrual_for_plan',75);
1225  ELSIF NOT (csr_all_asg_status%ISOPEN ) THEN
1226     hr_utility.set_location('get_accrual_for_plan',80);
1227     l_mult_factor   := 0;
1228  ELSE
1229     hr_utility.set_location('get_accrual_for_plan',85);
1230     l_mult_factor   := 1;
1231  END IF;
1232  --
1233  --
1234  IF l_unpaid_day <> 0 THEN
1235     hr_utility.set_location('get_accrual_for_plan',90);
1236     l_working_day := get_working_days(l_start_Date,l_end_date);
1237     IF l_working_day = l_unpaid_day THEN
1238        l_mult_factor := 0;
1239     ELSE
1240        l_mult_factor := (1 - (l_unpaid_day/l_working_day));
1241     END IF;
1242  END IF;
1243 --
1244 -- Find out vacation and carry over if the method is ceiling
1245 --
1246  IF l_ceiling_flag = 'Y' THEN
1247     hr_utility.set_location('get_accrual_for_plan',95);
1248     OPEN  csr_calc_accrual(l_start_Date,    l_end_date,
1249                            P_assignment_id, P_plan_id);
1250     FETCH csr_calc_accrual INTO l_vac_taken;
1251     IF csr_calc_accrual%NOTFOUND  or l_vac_taken is null THEN
1252            l_vac_taken := 0;
1253     END IF;
1254            CLOSE csr_calc_accrual;
1255  END IF;
1256  --
1257  --  Multiply the Accrual rate for the current band and  Multiplication
1258  --  Factor to get current period accrual.
1259  --
1260   hr_utility.set_location('get_accrual_for_plan',100);
1261   IF (l_band_change_date between l_start_Date and l_end_date)
1262       OR ( l_band_change_date < l_end_date)
1263   THEN
1264      l_curr_p_acc   := l_acc_rate_pp_2 * l_mult_factor;
1265      l_curr_ceiling := l_ceiling_2;
1266   ELSE
1267      l_curr_p_acc   := l_acc_rate_pp_1 * l_mult_factor;
1268      l_curr_ceiling := l_ceiling_1;
1269   END IF;
1270   --
1271   --
1272   --   Check for ceiling limits
1273   --
1274   hr_utility.set_location('get_accrual_for_plan',105);
1275   IF l_ceiling_flag = 'Y' THEN
1276      l_running_total := l_running_total + l_vac_taken + l_curr_p_acc;
1277      IF l_running_total > l_curr_ceiling THEN
1278         IF (l_running_total - l_curr_ceiling) < l_curr_p_acc
1279            THEN
1280               l_temp    := (l_curr_p_acc -
1281                            (l_running_total - l_curr_ceiling));
1282               l_accrual := l_accrual + l_temp;
1283               l_running_total := l_running_total + l_temp;
1284          END IF;
1285               l_running_total := l_running_total - l_curr_p_acc;
1286          ELSE
1287               l_accrual := l_accrual + l_curr_p_acc;
1288          END IF;
1289      ELSE
1290        l_accrual := l_accrual + l_curr_p_acc;
1291      END IF;
1292      hr_utility.set_location('get_accrual_for_plan',110);
1293      --
1294      --
1295      -- #305751 Remove the END IF matching the removed IF above.
1296      --
1297      --   END IF;
1298      --
1299    END LOOP;
1300    --
1301    CLOSE csr_get_time_periods;
1302   --
1303   END IF;
1304 --
1305 --
1306 IF l_accrual is null THEN
1307    l_accrual := 0;
1308 END IF;
1309 --
1310 <<exit_out>>
1311 P_Plan_accrual := l_accrual;
1312 --
1313 --
1314 END get_accrual_for_plan;
1315 --
1316 --------------------------- get_working_days ------------------------
1317 --
1318 FUNCTION get_working_days (P_start_date date,
1319                            P_end_date   date )
1320          RETURN   NUMBER is
1321 l_total_days    NUMBER        := 0;
1322 l_curr_date     DATE          := NULL;
1323 l_curr_day      VARCHAR2(3)   := NULL;
1324 --
1325 BEGIN
1326 --
1327 -- Check for valid range
1328 hr_utility.set_location('get_working_days', 5);
1329 IF p_start_date > P_end_date THEN
1330   hr_utility.set_location('get_working_days', 8);
1331   RETURN l_total_days;
1332 END IF;
1333 --
1334 l_curr_date := P_start_date;
1335 hr_utility.set_location('get_working_days', 10);
1336 LOOP
1337   l_curr_day := TO_CHAR(l_curr_date, 'DY');
1338   hr_utility.set_location('get_working_days', 15);
1339   IF UPPER(l_curr_day) in ('MON', 'TUE', 'WED', 'THU', 'FRI') THEN
1340     l_total_days := l_total_days + 1;
1341     hr_utility.set_location('get_working_days', 20);
1342   END IF;
1343   l_curr_date := l_curr_date + 1;
1344   EXIT WHEN l_curr_date > P_end_date;
1345 END LOOP;
1346 --
1347 RETURN l_total_days;
1348 --
1349 END get_working_days;
1350 --
1351 --
1352 ----------------------- get_net_accrual --------------------------------------
1353 --
1354 FUNCTION get_net_accrual
1355                     ( P_assignment_id        number,
1356                       P_calculation_date     date,
1357                       P_plan_id              number   default null,
1358                       P_plan_category        Varchar2 default null,
1359                       P_assignment_action_id number   default null)
1360          RETURN NUMBER is
1361 --
1362 --
1363 -- Function calls the actual proc. which will calc. net accrual and pass back
1364 -- the details.In formula we will call functions so this will be the cover
1365 -- function to call the proc.
1366 --
1367 
1368 cursor c_asg_details is
1369 select business_group_id,
1370        payroll_id
1371 from per_all_assignments_f
1372 where assignment_id = p_assignment_id
1373 and p_calculation_date between effective_start_date
1374                        and     effective_end_date;
1375 
1376 l_proc                 varchar2(80) := g_package||'get_net_accrual';
1377 l_entitlement          number := 0;
1378 l_payroll_id           number;
1379 l_business_group_id    number;
1380 l_assignment_action_id number;
1381 
1382 --
1383 c_date date := P_calculation_date;
1384 n1 number;
1385 n2 number;
1386 n3 number;
1387 n4 number;
1388 d1 date;
1389 d2 date;
1390 d3 date;
1391 d4 date;
1392 d5 date;
1393 d6 date;
1394 d7 date;
1395 --
1396 BEGIN
1397 --
1398   hr_utility.set_location('Entering: '||l_proc, 10);
1399 
1400   IF NOT use_fast_formula(p_effective_date => p_calculation_date
1401                          ,p_plan_id        => p_plan_id) THEN
1402     --
1403     -- It has been determined that:
1404     --   a) the Fast Formula used by this accrual plan contain
1405     --      the same logic as the old 10.7 PL/SQL code and
1406     --   b) this accrual plan does not store accruals in a
1407     --      payroll balance.
1408     -- For this reason, the old 10.7 code is called because it
1409     -- is significantly faster than executing Fast Formula.
1410     --
1411     hr_utility.set_location(l_proc, 20);
1412 
1413     pay_us_pto_accrual.net_accruals(
1414        P_assignment_id      => P_assignment_id,
1415        P_calculation_date   => c_date,
1416        P_plan_id            => P_plan_id,
1417        P_plan_category      => P_plan_category,
1418        P_mode               => 'N',
1419        P_accrual            => n4,
1420        P_net_accrual        => l_entitlement,
1421        P_payroll_id         => n1,
1422        P_first_period_start => d1,
1423        P_first_period_end   => d2,
1424        P_last_period_start  => d3,
1425        P_last_period_end    => d4,
1426        P_cont_service_date  => d5,
1427        P_start_date         => d6,
1428        P_end_date           => d7,
1429        P_current_ceiling    => n2,
1430        P_current_carry_over => n3);
1431 
1432     if l_entitlement is null then
1433       l_entitlement := 0;
1434     end if;
1435   --
1436   ELSE
1437     --
1438     -- It has been determined that:
1439     --   a) the Fast Formula used by this accrual plan differ
1440     --      from the logic used in the old 10.7 PL/SQL code or
1441     --   b) this accrual plan stores the accruals in a payroll
1442     --      balance.
1443     -- For either of these reasons, the newer call to
1444     -- get_net_accrual (in per_accrual_calc_functions) is used.
1445     --
1446     -- If the assignment_action_id is passed the accruals are
1447     -- simply retrieved from a payroll balance, if the
1448     -- assignment_action_id is not passed, the Fast Formula
1449     -- must instead be executed.
1450     --
1451     open c_asg_details;
1452     fetch c_asg_details into l_business_group_id,
1453                              l_payroll_id;
1454     close c_asg_details;
1455 
1456     -- Here we set a null assignment_action_id to -1 to prevent
1457     -- an error running the Accrual formula later.
1458 
1459 
1460     if p_assignment_action_id is null then
1461       l_assignment_action_id := -1;
1462     else
1463       l_assignment_action_id := p_assignment_action_id;
1464     end if;
1465 
1466     hr_utility.set_location(l_proc, 30);
1467 
1468     per_accrual_calc_functions.get_net_accrual(
1469        P_assignment_id          => p_assignment_id,
1470        P_plan_id                => p_plan_id,
1471        P_payroll_id             => l_payroll_id,
1472        p_business_group_id      => l_business_group_id,
1473        p_assignment_action_id   => l_assignment_action_id,
1474        P_calculation_date       => p_calculation_date,
1475        p_accrual_start_date     => null,
1476        p_accrual_latest_balance => null,
1477        p_calling_point          => 'BP',
1478        P_start_date             => d1,
1479        P_End_Date               => d2,
1480        P_Accrual_End_Date       => d3,
1481        P_accrual                => n1,
1482        P_net_entitlement        => l_entitlement
1483        );
1484   --
1485   end if;
1486 
1487   hr_utility.trace('l_entitlement: '||to_char(l_entitlement));
1488 
1489   hr_utility.set_location('Leaving: '||l_proc, 90);
1490 
1491   RETURN(l_entitlement);
1492 --
1493 END get_net_accrual;
1494 ---
1495 ---
1496 --------------------------- net_accruals -----------------------------------
1497 --
1498 --
1499 -- This procedure can be called directly this procedure will return start
1500 -- date, end dates etc. which can be used by CO.
1501 --
1502 PROCEDURE net_accruals
1503               (P_assignment_id          IN    number,
1504                P_calculation_date    IN OUT nocopy  date,
1505                P_plan_id                IN    number   DEFAULT NULL,
1506                P_plan_category          IN    varchar2 DEFAULT NULL,
1507                P_mode                   IN    varchar2 DEFAULT 'N',
1508                P_accrual             IN OUT nocopy  number,
1509                P_net_accrual            OUT nocopy  number,
1510                P_payroll_id          IN OUT nocopy  number,
1511                P_first_period_start  IN OUT nocopy  date,
1512                P_first_period_end    IN OUT nocopy  date,
1513                P_last_period_start   IN OUT nocopy  date,
1514                P_last_period_end     IN OUT nocopy  date,
1515                P_cont_service_date      OUT nocopy  date,
1516                P_start_date          IN OUT nocopy  date,
1517                P_end_date            IN OUT nocopy  date,
1518                P_current_ceiling        OUT nocopy  number,
1519                P_current_carry_over     OUT nocopy  number)  IS
1520 --
1521 --
1522 l_taken              number := 0;
1523 --
1524 l_temp               number := 0;
1525 --
1526 BEGIN
1527 --
1528 -- Get vaction accrued
1529 --
1530   hr_utility.set_location('get_net_accrual',5);
1531   pay_us_pto_accrual.accrual_calc_detail(
1532        P_assignment_id      => P_assignment_id,
1533        P_calculation_date   => P_calculation_date,
1534        P_plan_id            => P_plan_id,
1535        P_plan_category      => P_plan_category,
1536        P_mode               => P_mode,
1537        P_accrual            => P_accrual,
1538        P_payroll_id         => P_payroll_id,
1539        P_first_period_start => P_first_period_start,
1540        P_first_period_end   => P_first_period_end,
1541        P_last_period_start  => P_last_period_start,
1542        P_last_period_end    => P_last_period_end,
1543        P_cont_service_date  => P_cont_service_date,
1544        P_start_date         => P_start_date,
1545        P_end_date           => P_end_date,
1546        P_current_ceiling    => P_current_ceiling,
1547        P_current_carry_over => P_current_carry_over);
1548 --
1549 -- Get vac taken purchase etc using net Calc rules.
1550 --
1551 
1552    OPEN  csr_calc_accrual(P_start_Date,    P_end_date,
1553                           P_assignment_id, P_plan_id);
1554    FETCH csr_calc_accrual INTO l_taken;
1555    IF csr_calc_accrual%NOTFOUND  or
1556       l_taken is null
1557    THEN
1558       l_taken := 0;
1559    END IF;
1560    CLOSE csr_calc_accrual;
1561    hr_utility.set_location('get_net_accrual',20);
1562 --
1563 --
1564    P_net_accrual := ROUND((P_accrual + l_taken),3);
1565 
1566 --
1567 -- if mode is carry over then return next years first period start
1568 -- and end dates in P_start_date nad P_end_date params.
1569 --
1570    IF P_mode = 'C'
1571    THEN
1572      OPEN csr_get_period(p_payroll_id,(P_last_period_end +1));
1573      hr_utility.set_location('get_net_accrual',21);
1574      FETCH csr_get_period into l_temp,P_start_date,P_end_date;
1575      IF csr_get_period%NOTFOUND THEN
1576        CLOSE csr_get_period;
1577        hr_utility.set_message(801, 'HR_6153_ALL_PROCEDURE_FAIL');
1578        hr_utility.set_message_token('PROCEDURE','net_accruals');
1579        hr_utility.set_message_token('STEP','15');
1580        hr_utility.raise_error;
1581      END IF;
1582      CLOSE csr_get_period;
1583      hr_utility.set_location('get_net_accrual',22);
1584    END IF;
1585 --
1586 --
1587 END net_accruals;
1588 --
1589 END pay_us_pto_accrual;