DBA Data[Home] [Help]

PACKAGE BODY: APPS.PAY_FR_SCHEDULE_CALCULATION

Source


1 package body pay_fr_schedule_calculation as
2 /* $Header: pyfrwktm.pkb 120.1 2005/06/14 05:17:28 aparkes noship $ */
3 --
4 g_udt_name VARCHAR2(50) := 'FR_COMPANY_WORK_PATTERNS';
5 g_date_start date;
6 g_date_end date;
7 g_assignment_id number;
8 g_asg_start_date date;
9 g_asg_end_date date;
10 g_person_id number;
11 g_business_group_id number;
12 g_asg_periods number;
13 g_default_offset number := 1;
14 --
15 TYPE wp_rec_type is RECORD (start_date date
16                               ,end_date  date
17                               ,pattern varchar2(30)
18                               ,pattern_start number
19                               ,pattern_index number
20                               ,pattern_length number
21                             );
22 TYPE wp_tab_type is TABLE of wp_rec_type INDEX BY BINARY_INTEGER;
23 --
24 TYPE days_rec_type is RECORD (hours number
25                              ,protected varchar2(1)
26                              ,public_holiday varchar2(1)
27                              ,public_holiday_override varchar2(1)
28                              ,public_holiday_in_lieu varchar2(1)
29                              ,absence_non_working varchar2(1)
30                              );
31 TYPE days_tab_type is TABLE of days_rec_type INDEX BY BINARY_INTEGER;
32 --
33 TYPE pattern_tab_type is TABLE of VARCHAR2(2) INDEX BY BINARY_INTEGER;
34 days_tab days_tab_type;
35 work_pattern wp_tab_type;
36 pattern pattern_tab_type;
37 --
38 procedure initialise(p_assignment_id number
39                     ,p_effective_date date) is
40 --
41 cursor csr_asg is
42 select trunc(a.effective_start_date) effective_start_date
43 ,      trunc(a.effective_end_date) effective_end_date
44 ,      a.person_id
45 ,      a.business_group_id business_group_id
46 ,      scl.segment5 work_pattern
47 ,      nvl(scl.segment11,g_default_offset) work_pattern_start_day
48 from per_all_assignments_f a
49 ,    hr_soft_coding_keyflex scl
50 where a.assignment_id = p_assignment_id
51 and   a.soft_coding_keyflex_id = scl.soft_coding_keyflex_id(+)
52 order by a.effective_start_date;
53 --
54 --
55 l_days_worked number;
56 l_start number;
57 l_end number;
58 l_prev_work_pattern varchar2(30);
59 l_prev_pattern_start Number;
60 l_prev_start_date date;
61 l_prev_end_date date;
62 i number;
63 l_shift_pattern_index number := 1;
64 --
65 procedure load_pattern(p_pattern in varchar2
66                      ,p_effective_date date
67                      ,p_pattern_index out nocopy number
68                      ,p_pattern_length out nocopy number) is
69 --
70   cursor c_get_days is
71   select ci.value
72   from pay_user_tables t
73   ,    pay_user_columns c
74   ,    pay_user_rows_f r
75   ,    pay_user_column_instances_f ci
76   where t.user_table_name = g_udt_name
77   and c.business_group_id = g_business_group_id
78   and   t.user_table_id = r.user_table_id
79   and   t.user_table_id = c.user_table_id
80   and   c.user_column_name = p_pattern
81   and   ci.user_column_id = c.user_column_id
82   and   ci.user_row_id = r.user_row_id
83   and p_effective_date
84       between r.effective_start_date and r.effective_end_date
85   and p_effective_date
86       between ci.effective_start_date and ci.effective_end_date
87   order by r.display_sequence;
88 --
89 l_length number := 0;
90 l_pattern_index number;
91 begin
92    l_pattern_index := l_shift_pattern_index;
93    --
94    for d in c_get_days loop
95        pattern(l_shift_pattern_index) := d.value;
96        l_shift_pattern_index := l_shift_pattern_index + 1;
97        l_length := l_length + 1;
98    end loop;
99    --
100    p_pattern_index := l_pattern_index;
101    p_pattern_length := l_length;
102 end load_pattern;
103 --
104 begin
105 --
106 /* if the assignment has already been initialised then exit */
107 if g_assignment_id = p_assignment_id  then
108    null;
109 else
110 --
111 /* Get distinct working pattern details for the assignment */
112    l_prev_work_pattern := null;
113    l_prev_start_date := null;
114    l_prev_end_date := null;
115    l_prev_pattern_start := null;
116    i := 0;
117    pattern.delete;
118      for l_asg_rec in csr_asg loop
119        g_person_id         := l_asg_rec.person_id;
120        g_business_group_id := l_asg_rec.business_group_id;
121        g_assignment_id     := p_assignment_id;
122        if g_asg_start_date is Null then
123 	   g_asg_start_date := l_asg_rec.effective_start_date;
124        end if;
125        --Bug:2454782.Also checked the update of pattern start day.
126        if l_asg_rec.work_pattern = l_prev_work_pattern and
127           l_asg_rec.work_pattern_start_day = l_prev_pattern_start then
128           l_prev_end_date := l_asg_rec.effective_end_date;
129        else
130           if l_prev_work_pattern is not null then
131              i := i + 1;
132              work_pattern(i).start_date := l_prev_start_date;
133              work_pattern(i).end_date := l_prev_end_date;
134              work_pattern(i).pattern := l_prev_work_pattern;
135              work_pattern(i).pattern_start :=l_prev_pattern_start;
136              --
137              load_pattern(l_prev_work_pattern
138                          ,p_effective_date
139                          ,work_pattern(i).pattern_index
140                          ,work_pattern(i).pattern_length);
141              --
142           end if;
143           --
144           l_prev_start_date := l_asg_rec.effective_start_date;
145           l_prev_end_date := l_asg_rec.effective_end_date;
146           l_prev_work_pattern := l_asg_rec.work_pattern;
147           l_prev_pattern_start := l_asg_rec.work_pattern_start_day;
148        end if;
149      end loop;
150    i := i + 1;
151    work_pattern(i).start_date := l_prev_start_date;
152    work_pattern(i).end_date := l_prev_end_date;
153    work_pattern(i).pattern_start := l_prev_pattern_start;
154    work_pattern(i).pattern := l_prev_work_pattern;
155              --
156              load_pattern(l_prev_work_pattern
157                          ,p_effective_date
158                          ,work_pattern(i).pattern_index
159                          ,work_pattern(i).pattern_length);
160              --
161    g_asg_periods := i;
162    g_asg_end_date := l_prev_end_date;
163 
164  -- UNCOMMENT THE FOLLOWING TO DEBUG IN SQL * PLUS
165  /*
166   --Displays Work Pattern info assigned to the employee
167    Dbms_Output.Put_line(rpad('Start Date',10)||' '
168                       ||rpad('End Date',10)||' '
169                       ||rpad('Work Pattern',20)||' '
170                       ||rpad('Start',5)||' '
171                       ||rpad('Index',5)||' '
172                       ||rpad('Length',6));
173    Dbms_Output.Put_line(rpad('-',10,'-')||' '
174                       ||rpad('-',10,'-')||' '
175                       ||rpad('-',20,'-')||' '
176                       ||rpad('-',5,'-')||' '
177                       ||rpad('-',5,'-')||' '
178                       ||rpad('-',5,'-'));
179   For i in 1..g_asg_periods Loop
180    Dbms_output.put_line(rpad(work_pattern(i).start_date,10) || ' '
181                       ||rpad(work_pattern(i).end_date,10) ||' '
182                       ||rpad(work_pattern(i).pattern,20) ||' '
183                       ||rpad(work_pattern(i).pattern_start,5)||' '
184                       ||rpad(work_pattern(i).pattern_index,5)||' '
185                       ||rpad(work_pattern(i).pattern_length,5));
186   End Loop;
187   Dbms_Output.Put_line(chr(10));
188 
189   --Displays Pattern Table information
190   Dbms_Output.Put_Line(rpad('index',5)||' '
191                      ||rpad('Working Hours',13));
192   Dbms_Output.Put_Line(rpad('-',5,'-')||' '
193                      ||rpad('-',13,'-'));
194   For i in 1..l_shift_pattern_index-1 Loop
195   Dbms_Output.Put_Line(rpad(i,5)||' '
196                      ||rpad(pattern(i),13));
197   End Loop;
198   Dbms_Output.Put_line(chr(10));
199 
200    */
201 
202  end if;
203 end initialise;
204 ----------------------------------------------------------
205 --
206 procedure derive_schedule(p_assignment_id number
207                          ,p_date_start date
208                          ,p_date_end date) is
209 cursor csr_ph is
210 select to_number(to_char(holiday_date,'J')) day
211 from per_standard_holidays
212 where legislation_code = 'FR'
213 and holiday_date between p_date_start and p_date_end;
214 --
215 cursor csr_ph_overrides is
216 select to_number(to_char(date_not_taken,'J')) day
217 from per_std_holiday_absences
218 where person_id = g_person_id
219 and date_not_taken between p_date_start and p_date_end;
220 --
221 cursor csr_ph_in_lieu is
222 select to_number(to_char(actual_date_taken,'J')) day
223 from per_std_holiday_absences
224 where person_id = g_person_id
225 and actual_date_taken between p_date_start and p_date_end;
226 --
227 cursor csr_absence_non_working is
228 select to_number(to_char(
229                greatest(a.date_start,p_date_start),'J'))     date_start
230 ,      to_number(to_char(
231           least(nvl(a.date_end,p_date_end),p_date_end),'J')) date_end
232 from per_absence_attendances a
233 ,    per_absence_attendance_types aat
234 ,    per_shared_types nw
235 where a.person_id = g_person_id
236 and a.date_start <= p_date_end
237 and nvl(a.date_end,p_date_end) >= p_date_start
238 and a.absence_attendance_type_id = aat.absence_attendance_type_id
239 and aat.absence_category = nw.system_type_cd
240 and nvl(nw.business_group_id,a.business_group_id) = a.business_group_id
241 and nw.lookup_type = 'ABSENCE_CATEGORY'
242 and nw.information1 = 'Y';
243 --
244 l_start number;
245 l_end number;
246 x number;
247 l_pattern_offset number;
248 l_pattern_start number;
249 i Number;
250 --
251 begin
252 /* In the case of Starters and Leavers it may be necessary to infer the
253 pattern wither before or after their assignment starts/ends.
254 
255 This is achieved by modifying the 1st assignment period start date and the
256 last assignment period end date if they are within the p_date_start and p_date_end date range.
257 */
258 --
259 
260 if p_date_start < g_asg_start_date then
261    l_pattern_offset := p_date_start - work_pattern(1).start_date;
262    work_pattern(1).pattern_start :=
263          mod(l_pattern_offset + work_pattern(1).pattern_start
264             ,work_pattern(1).pattern_length);
265     If work_pattern(1).pattern_start <= 0 Then
266         work_pattern(1).pattern_start := work_pattern(1).pattern_start + work_pattern(1).pattern_length;
267     End If;
268 
269    work_pattern(1).start_date := trunc(p_date_start);
270 end if;
271 --
272 if p_date_end > g_asg_end_date then
273    work_pattern(g_asg_periods).end_date := trunc(p_date_end);
274 end if;
275 --
276 if trunc(p_date_start) = trunc(g_date_start) and
277   trunc(p_date_end) = trunc(g_date_end)  and
278   p_assignment_id = g_assignment_id then
279    null;
280 else
281 
282 
283 days_tab.delete;
284 
285 for a in 1..g_asg_periods loop
286 --
287     if work_pattern(a).end_date >= trunc(p_date_start) and
288        work_pattern(a).start_date <= trunc(p_date_end) then
289        --
290 
291    l_start := to_number(to_char(greatest(p_date_start,work_pattern(a).start_date),'J'));
292    l_end   := to_number(to_char(least(p_date_end,work_pattern(a).end_date),'J'));
293 /* Determine the pattern day on start date of period */
294        l_pattern_offset := greatest(trunc(p_date_start)
295                                   ,work_pattern(a).start_date)
296                           - work_pattern(a).start_date;
297        l_pattern_start := mod(l_pattern_offset + work_pattern(a).pattern_start
298                              ,work_pattern(a).pattern_length);
299        --
300        If l_pattern_start = 0 Then
301          l_pattern_start := work_pattern(a).pattern_length;
302        End If;
303 
304        --
305        x := work_pattern(a).pattern_index + l_pattern_start - 1;
306         for d in l_start..l_end loop
307             if work_pattern(a).pattern_length = 0 then
308                 days_tab(d).hours := 0;
309             else
310                 if pattern(x) = 'P' then
311                    days_tab(d).hours := 0;
312                    days_tab(d).protected := 'Y';
313                 else
314                    days_tab(d).hours := pattern(x);
315                 end if;
316             end if;
317             --
318             /* Increment index counter */
319             if x - work_pattern(a).pattern_index + 1
320                   >= work_pattern(a).pattern_length then
321                x := work_pattern(a).pattern_index;
322             else
323                x := x + 1;
324             end if;
325        end loop;
326     end if;
327 end loop;
328 --
329 
330 /* Load public holidays */
331 for h in csr_ph loop
332    days_tab(h.day).public_holiday := 'Y';
333 end loop;
334 --
335 
336 /* Load public holiday overrides */
337 for o in csr_ph_overrides loop
338    days_tab(o.day).public_holiday_override := 'Y';
339 end loop;
340 --
341 
342 /* Load public holiday taken in lieu */
343 for l in csr_ph_in_lieu loop
344    days_tab(l.day).public_holiday_in_lieu := 'Y';
345 end loop;
346 --
347 
348 /* Load absences treated as non-working days */
349 for a in csr_absence_non_working loop
350    for n in a.date_start..a.date_end loop
351        days_tab(n).absence_non_working := 'Y';
352    end loop;
353 end loop;
354 --
355 l_start := to_number(to_char(p_date_start,'J'));
356 l_end := to_number(to_char(p_date_end,'J'));
357 --
358   g_date_start := trunc(p_date_start);
359   g_date_end := trunc(p_date_end);
360 end if;
361 -----------------------------------------------------
362 l_start := to_number(to_char(p_date_start,'J'));
363 l_end := to_number(to_char(p_date_end,'J'));
364 
365 --Displays the main pl/sql table
366 /*
367 dbms_output.put_line(rpad('Day',21)|| ' '
368                   || rpad('Hours',5)|| ' '
369                   || rpad('Protected',9)|| ' '
370                   || rpad('Public Holiday',14)|| ' '
371                   || rpad('PH Override',11)|| ' '
372                   || rpad('PH in lieu',10)|| ' '
373                   || rpad('Absence NW',10));
374 dbms_output.put_line(rpad('-',21,'-')|| ' '
375                   || rpad('-',5,'-')|| ' '
376                   || rpad('-',9,'-')|| ' '
377                   || rpad('-',14,'-')|| ' '
378                   || rpad('-',11,'-')|| ' '
379                   || rpad('-',10,'-')|| ' '
380                   || rpad('-',10,'-'));
381 
382 for d in l_start..l_end loop
383 dbms_output.put_line(rpad(to_date(d,'J'),10)|| ' '||rpad(TO_CHAR(TO_DATE(d,'J'),'DAY'),10)||' '||
384 rpad(days_tab(d).hours,5) || ' '||
385 rpad(nvl(days_tab(d).protected,' '),9) || ' '||
386 rpad(nvl(days_tab(d).public_holiday,' '),14) || ' '||
387 rpad(nvl(days_tab(d).public_holiday_override,' '),11) || ' '||
388 rpad(nvl(days_tab(d).public_holiday_in_lieu,' '),10) || ' '||
389 rpad(nvl(days_tab(d).absence_non_working,' '),10)
390 );
391 end loop;
392 */
393 end derive_schedule;
394 --
395 /* ---------------------------------------------------------
396 Function holiday_days
397 
398 This function counts the number of working days between the
399 Start and End Dates passed in as parameters.
400 
401 It takes into account public holidays as these should not be
402 counted as holidays if they fall on a working day. If the
403 public holiday is scheduled to be worked then it is treated
404 as working day for the purposes of counting working days.
408 Other types of absence do not affect the count of holidays.
405 A holiday taken in lieu of a public holiday is treated as
406 a non-working day for the purposes of counting working days.
407 
409 ------------------------------------------------------------ */
410 function holiday_days(p_assignment_id number
411                          ,p_effective_date date
412                          ,p_date_start date
413                          ,p_date_end date
414                          ) return number is
415 l_days_worked number := 0;
416 l_start number;
417 l_end number;
418 begin
419 --
420 /* Call initialise in case this is a new person */
421    initialise(p_assignment_id
422              ,p_effective_date);
423 /* Call derive_schedule in case this is a new period */
424    derive_schedule(p_assignment_id
425                   ,p_date_start
426                   ,p_date_end);
427    --
428 /* count the number of days */
429    --
430 l_start := to_number(to_char(p_date_start,'J'));
431 l_end := to_number(to_char(p_date_end,'J'));
432 --
433    for d in l_start..l_end loop
434           if not(days_tab(d).hours = 0) then
435           if days_tab(d).public_holiday = 'Y' then
436              if days_tab(d).public_holiday_override = 'Y' then
437                 l_days_worked := l_days_worked + 1;
438              end if;
439           else
440              if days_tab(d).public_holiday_in_lieu = 'Y' then
441                 null;
442              else
443                 l_days_worked := l_days_worked + 1;
444              end if;
445           end if;
446        end if;
447    end loop;
448    return l_days_worked;
449 end;
450 --
451 /* ---------------------------------------------------------
452 Function protected_days
453 
454 This function takes counts the number of protected days
455 between the Start and End Dates passed in as parameters.
456 
457 It takes into account public holidays as these should
458 not be counted as holidays if they fall on a working day.
459 
460 Other types of absence do not affect the count of holidays.
461 
462  --------------------------------------------------------- */
463 function protected_days(p_assignment_id number
464                          ,p_effective_date date
465                          ,p_date_start date
466                          ,p_date_end date
467                          ) return number is
468 l_protected_days number := 0;
469 l_start number;
470 l_end number;
471 begin
472 --
473 /* Call initialise in case this is a new person */
474    initialise(p_assignment_id
475              ,p_effective_date);
476 /* Call derive_schedule in case this is a new period */
477    derive_schedule(p_assignment_id
478                   ,p_date_start
479                   ,p_date_end);
480    --
481 /* count the number of protected days */
482    --
483 l_start := to_number(to_char(p_date_start,'J'));
484 l_end := to_number(to_char(p_date_end,'J'));
485 --
486    for d in l_start..l_end loop
487        if days_tab(d).protected = 'Y' then
488           if days_tab(d).public_holiday = 'Y' then
489              null;
490           else
491                 l_protected_days := l_protected_days + 1;
492           end if;
493        end if;
494    end loop;
495    return l_protected_days;
496 end;
497 --
498 /* ---------------------------------------------------------
499 Function scheduled_working_days
500 
501 This function will return the number of working days for the
502 assignment between the start and end dates. The effective
503 date parameter is used to determine the work pattern records
504 from the user defined table.
505 
506 Only the work schedule will be used to determine the number
507 of days scheduled to be worked. Public Holidays and other
508 absences are excluded from the evaluation.
509 
510 This will be used by the Sickness functionality to evaluate
511 the Sickness Deduction.
512 
513 ------------------------------------------------------------ */
514 function scheduled_working_days(p_assignment_id number
515                          ,p_effective_date date
516                          ,p_date_start date
517                          ,p_date_end date
518                          ) return number is
519 l_days_worked number := 0;
520 l_start number;
521 l_end number;
522 i Number;
523 begin
524 --
525 /* Call initialise in case this is a new person */
526    initialise(p_assignment_id
527              ,p_effective_date);
528 /* Call derive_schedule in case this is a new period */
529    derive_schedule(p_assignment_id
530                   ,p_date_start
531                   ,p_date_end);
532    --
533 /* count the number of days */
534    --
535 l_start := to_number(to_char(p_date_start,'J'));
536 l_end := to_number(to_char(p_date_end,'J'));
537 --
538 
539    i := days_tab.FIRST;
540    While i Is Not Null Loop
541    If Not(days_tab(i).hours = 0) Then
542           	   l_days_worked := l_days_worked + 1;
543    End If;
544 
545    i := days_tab.NEXT(i);
546    End Loop;
547 
548 
549    return l_days_worked;
550 end;
551 --
552 /* ---------------------------------------------------------
556 assignment between the start and end dates. The effective date
553 Function scheduled_working_hours
554 
555 This function will return the number of working hours for the
557 parameter is used to determine the work pattern records from
558 the user defined table.
559 
560 Only the work schedule will be used to determine the number of
561 hours scheduled to be worked. Public Holidays and other absences
562 are excluded from the evaluation.
563 
564 This will be used by the Proration functionality to evaluate
565 the Scheduled Hours Method.
566 
567 ------------------------------------------------------------ */
568 function scheduled_working_hours(p_assignment_id number
569                          ,p_effective_date date
570                          ,p_date_start date
571                          ,p_date_end date
572                          ) return number is
573 l_hours_worked number := 0;
574 l_start number;
575 l_end number;
576 i Number;
577 begin
578 --
579 /* Call initialise in case this is a new person */
580    initialise(p_assignment_id
581              ,p_effective_date);
582 /* Call derive_schedule in case this is a new period */
583    derive_schedule(p_assignment_id
584                   ,p_date_start
585                   ,p_date_end);
586    --
587 /* count the number of hours */
588    --
589 l_start := to_number(to_char(p_date_start,'J'));
590 l_end := to_number(to_char(p_date_end,'J'));
591 --
592 
593    i := days_tab.FIRST;
594    While i Is Not Null Loop
595    If Not(days_tab(i).hours = 0) Then
596           	   l_hours_worked := l_hours_worked + days_tab(i).hours;
597    End If;
598 
599    i := days_tab.NEXT(i);
600    End Loop;
601 
602 
603 
604    return l_hours_worked;
605 end;
606 --
607 /*------------------------------------------------------------
608 For the purposes of a Sickness report the last working day prior to
609 the sickness and the next working day following a particular day is required.
610 
611 These functions loop through days prior to / following the P_DATE
612 determining whether the day is a working day. If it reaches the
613 P_LIMIT_DATE it stops and returns NULL. The default value
614 for the P_LIMIT_DATE is 12 months prior to / following the P_DATE.
615 
616 ------------------------------------------------------*/
617 function get_next_last_working_day(p_assignment_id number
618                          ,p_effective_date date
619                          ,p_date date
620                          ,p_limit_date date
621                          ,p_next_last number
622                          ) return date is
623 l_date date;
624 l_start number;
625 l_end number;
626 l_working_date date;
627 d number;
628 l_limit_date date;
629 l_act_date Date;
630 l_last_act_date Date;
631 Cursor c_start_asg is
632          Select Min(effective_start_date)
633          From per_all_assignments_f paaf
634          Where
635               paaf.assignment_id = g_assignment_id;
636 
637 begin
638    initialise(p_assignment_id
639              ,p_effective_date);
640 
641 
642    Open c_start_asg ;
643    Fetch c_start_asg into l_act_date;
644    Close c_start_asg;
645    l_last_act_date := l_act_date;
646    l_act_date := greatest(l_act_date,p_date);
647 
648    --
649    if p_limit_date is null then
650       If p_next_last = 1 then
651       l_limit_date := add_months(p_date,12*p_next_last);
652       Else
653       l_limit_date := greatest(add_months(l_act_date,12*p_next_last),l_last_act_date);
654 
655       End If;
656    else
657       if p_next_last = 1 then
658          l_limit_date := greatest(p_date+1,p_limit_date);
659       else
660          l_limit_date := least(l_act_date-1,greatest(p_limit_date,l_act_date));
661       end if;
662    end if;
663    --
664    l_date := l_act_date+p_next_last;
665    while sign(l_limit_date - l_date) <> p_next_last * -1  loop
666     derive_schedule(p_assignment_id
667                   ,l_date
668                   ,l_date);
669      --
670      d := to_number(to_char(l_date,'J'));
671        if not(days_tab(d).hours = 0) then
672           if days_tab(d).public_holiday = 'Y' then
673              if days_tab(d).public_holiday_override = 'Y' then
674                 if days_tab(d).absence_non_working = 'Y' then
675                    null;
676                 else
677                    l_working_date := l_date;
678                    exit;
679                 end if;
680              end if;
681           else
682              if days_tab(d).public_holiday_in_lieu = 'Y' then
683                 null;
684              else
685                 if days_tab(d).absence_non_working = 'Y' then
686                    null;
687                 else
688                    l_working_date := l_date;
689                    exit;
690                 end if;
691              end if;
692           end if;
693        end if;
694      l_date := l_date + p_next_last;
695    end loop;
696    --
697 
698    return l_working_date;
699 end;
700 ------------------------------------------------------------
701 function get_last_working_day(p_assignment_id number
702                          ,p_effective_date date
703                          ,p_date date
704                          ,p_limit_date date
705                          ) return date is
706 begin
707   return get_next_last_working_day(p_assignment_id
708                          ,p_effective_date
709                          ,p_date
710                          ,p_limit_date
711                          ,-1
712                          );
713 end;
714 --
715 function get_next_working_day(p_assignment_id number
716                          ,p_effective_date date
717                          ,p_date date
718                          ,p_limit_date date
719                          ) return date is
720 begin
721   return get_next_last_working_day(p_assignment_id => p_assignment_id
722                          ,p_effective_date => p_effective_date
723                          ,p_date => p_date
724                          ,p_limit_date => p_limit_date
725                          ,p_next_last => 1
726                          );
727 end get_next_working_day;
728 --
729 end pay_fr_schedule_calculation;