DBA Data[Home] [Help]

PACKAGE BODY: APPS.PER_ABS_BUS

Source


1 Package Body per_abs_bus as
2 /* $Header: peabsrhi.pkb 120.27.12020000.3 2012/11/05 11:44:22 srannama ship $ */
3 --
4 -- ----------------------------------------------------------------------------
5 -- |                     Private Global Definitions                           |
6 -- ----------------------------------------------------------------------------
7 --
8 g_package  varchar2(33) := '  per_abs_bus.';  -- Global package name
9 --
10 -- The following two global variables are only to be
11 -- used by the return_legislation_code function.
12 --
13 g_legislation_code            varchar2(150)  default null;
14 g_absence_attendance_id       number         default null;
15 
16 --
17 --  ---------------------------------------------------------------------------
18 --  |---------------------<  get_running_totals  >----------------------------|
19 --  ---------------------------------------------------------------------------
20 --
21 --  Description:
22 --    This procedure gets the year to date totals and running totals for
23 --    both days and hours.
24 --
25 --  Pre-conditions:
26 --    None.
27 --
28 --  In Arguments:
29 --    p_person_id
30 --    p_absence_attendance_type_id
31 --    p_effective_date
32 --
33 --  Out Arguments:
34 --    p_running_total_hours
35 --    p_running_total_days
36 --    p_year_to_date_hours
37 --    p_year_to_date_days
38 --
39 --  Post Success:
40 --    If validation passes, processing continues.
41 --
42 --  Post Failure:
43 --    If validation fails, an error is raised and processing stops.
44 --
45 --  Access Status:
46 --    Internal Table Handler Use Only. API updating is not required as this
47 --    is called from other chk procedures that use API updating.
48 --
49 -- {End Of Comments}
50 -- ----------------------------------------------------------------------------
51 --
52 procedure get_running_totals
53   (p_person_id                  in  number
54   ,p_absence_attendance_type_id in  number
55   ,p_effective_date             in  date
56   ,p_running_total_hours        out nocopy number
57   ,p_running_total_days         out nocopy number
58   ,p_year_to_date_hours         out nocopy number
59   ,p_year_to_date_days          out nocopy number)
60 is
61 
62   l_proc    varchar2(72)  :=  g_package||'get_running_totals';
63   l_absence_hours            number;
64   l_absence_days             number;
65   l_absence_year             date;
66   l_effective_year           date;
67   l_hours_or_days            varchar2(1);
68   l_increasing_or_decreasing varchar2(1);
69   l_screen_entry_value       number;
70   l_effective_start_date     date;
71   l_effective_end_date       date;
72 
73   cursor c_get_running_totals is
74   select nvl(abs.absence_hours, 0),
75          nvl(abs.absence_days, 0),
76          to_date('01/01/'||
77                  to_char(abs.date_end,'YYYY'),'DD/MM/YYYY'),
78          abt.hours_or_days,
79          abt.increasing_or_decreasing_flag
80   from   per_absence_attendances abs,
81          per_absence_attendance_types abt
82   where  abs.person_id = p_person_id
83   and    abs.absence_attendance_type_id = abt.absence_attendance_type_id
84   and    abs.date_end is not null
85   and    abs.date_end <= p_effective_date
86   and    abt.input_value_id is not null
87   and    abt.input_value_id = (select abt2.input_value_id
88                                from   per_absence_attendance_types abt2
89                                where  abt2.absence_attendance_type_id
90                                        = p_absence_attendance_type_id);
91 
92   cursor c_get_hours_or_days is
93   select abt.hours_or_days
94   from   per_absence_attendance_types abt
95   where  abt.absence_attendance_type_id = p_absence_attendance_type_id;
96 
97   cursor c_get_upload_elements is
98   -- select /*+ leading(PAA) */ nvl(fnd_number.canonical_to_number(pev.screen_entry_value), 0),
99   select nvl(fnd_number.canonical_to_number(pev.screen_entry_value), 0),     -- bug 7579341, hint removed
100          pev.effective_start_date,
101          pev.effective_end_date
102     from pay_element_entry_values_f pev,
103          pay_element_entries_f pee,
104          per_all_assignments_f paa,
105          per_absence_attendance_types abt
106    where pev.element_entry_id = pee.element_entry_id
107      and pev.input_value_id = abt.input_value_id
108      and pee.assignment_id = paa.assignment_id
109      and paa.person_id = p_person_id
110      and abt.absence_attendance_type_id = p_absence_attendance_type_id
111 --     and pee.creator_type <> 'A'  -- Bug 4422696
112      and pee.creator_type not in('A','EE','NR','PR','R','RR')  -- Bug 4422696
113      and pee.element_type_id =
114          (select pet.element_type_id
115             from pay_element_types_f pet,
116                  pay_input_values_f piv
117            where abt.input_value_id = piv.input_value_id
118              and piv.element_type_id = pet.element_type_id
119              and p_effective_date between piv.effective_start_date
120              and piv.effective_end_date
121              and p_effective_date between pet.effective_start_date
122              and pet.effective_end_date)
123      and p_effective_date between paa.effective_start_date
124      and paa.effective_end_date
125      and paa.primary_flag = 'Y';
126 
127 begin
128 
129   hr_utility.set_location('Entering:'|| l_proc, 10);
130 
131   --
132   -- Initialise all out parameters to zero.
133   --
134   p_running_total_hours := 0;
135   p_running_total_days  := 0;
136   p_year_to_date_hours  := 0;
137   p_year_to_date_days   := 0;
138 
139   --
140   -- Set the effective year.
141   --
142   l_effective_year := to_date('01/01/'||
143                                to_char(p_effective_date,'YYYY'), 'DD/MM/YYYY');
144 
145   hr_utility.set_location(l_proc, 20);
146 
147   --
148   -- Get the running totals for this element type for this person.
149   -- Both the year to dates and running totals are collected in the
150   -- same loop construct.
151   -- A loop is required because for each absence, its type could
152   -- have a different unit of measure and a different increasing
153   -- or decreasing flag.
154   --
155   open  c_get_running_totals;
156   loop
157 
158     fetch c_get_running_totals into l_absence_hours,
159                                     l_absence_days,
160                                     l_absence_year,
161                                     l_hours_or_days,
162                                     l_increasing_or_decreasing;
163 
164     exit when c_get_running_totals%notfound;
165 
166     if l_hours_or_days = 'H'
167     and l_increasing_or_decreasing = 'D' then
168 
169       hr_utility.set_location(l_proc, 25);
170 
171       p_running_total_hours := p_running_total_hours - l_absence_hours;
172 
173         --
174         -- If the current absence is in the same year as the effective
175         -- date, the year to date balance is adjusted.
176         --
177         if l_absence_year = l_effective_year then
178            p_year_to_date_hours := p_year_to_date_hours - l_absence_hours;
179         end if;
180 
181     elsif l_hours_or_days = 'H'
182     and   l_increasing_or_decreasing = 'I' then
183 
184       hr_utility.set_location(l_proc, 30);
185 
186       p_running_total_hours := p_running_total_hours + l_absence_hours;
187 
188         --
189         -- If the current absence is in the same year as the effective
190         -- date, the year to date balance is adjusted.
191         --
192         if l_absence_year = l_effective_year then
193            p_year_to_date_hours := p_year_to_date_hours + l_absence_hours;
194         end if;
195 
196     elsif l_hours_or_days is null
197     and   l_increasing_or_decreasing = 'I' then
198 
199       hr_utility.set_location(l_proc, 35);
200 
201       p_running_total_hours := p_running_total_hours + l_absence_hours;
202       p_running_total_days  := p_running_total_days + l_absence_days;
203 
204         --
205         -- If the current absence is in the same year as the effective
206         -- date, the year to date balance is adjusted.
207         --
208         if l_absence_year = l_effective_year then
209            p_year_to_date_hours := p_year_to_date_hours + l_absence_hours;
210            p_year_to_date_days := p_year_to_date_days + l_absence_days;
211         end if;
212 
213     elsif l_hours_or_days = 'D'
214     and   l_increasing_or_decreasing = 'D' then
215 
216       hr_utility.set_location(l_proc, 40);
217 
218       p_running_total_days := p_running_total_days - l_absence_days;
219 
220         --
221         -- If the current absence is in the same year as the effective
222         -- date, the year to date balance is adjusted.
223         --
224         if l_absence_year = l_effective_year then
225            p_year_to_date_days := p_year_to_date_days - l_absence_days;
226         end if;
227 
228     elsif l_hours_or_days = 'D'
229     and   l_increasing_or_decreasing = 'I' then
230 
231       hr_utility.set_location(l_proc, 45);
232 
233       p_running_total_days := p_running_total_days + l_absence_days;
234 
235         --
236         -- If the current absence is in the same year as the effective
237         -- date, the year to date balance is adjusted.
238         --
239         if l_absence_year = l_effective_year then
240            p_year_to_date_days := p_year_to_date_days + l_absence_days;
241         end if;
242 
243     elsif l_hours_or_days is null
244     and   l_increasing_or_decreasing = 'D' then
245 
246       hr_utility.set_location(l_proc, 50);
247 
248       p_running_total_hours := p_running_total_hours - l_absence_hours;
249       p_running_total_days  := p_running_total_days - l_absence_days;
250 
251         --
252         -- If the current absence is in the same year as the effective
253         -- date, the year to date balance is adjusted.
254         --
255         if l_absence_year = l_effective_year then
256            p_year_to_date_hours := p_year_to_date_hours - l_absence_hours;
257            p_year_to_date_days := p_year_to_date_days - l_absence_days;
258         end if;
259 
260     end if;
261 
262   end loop;
263   close c_get_running_totals;
264 
265   hr_utility.set_location(l_proc, 55);
266 
267   --
268   -- Is this absence type in hours or days?
269   --
270   open  c_get_hours_or_days;
271   fetch c_get_hours_or_days into l_hours_or_days;
272   close c_get_hours_or_days;
273 
274   hr_utility.set_location(l_proc, 60);
275 
276   --
277   -- Add any upload elements to the balance.  Upload elements
278   -- are elements linked to the absence type but do not
279   -- have an associated absence record. We ADD the upload
280   -- elements to the balance regardless of whether the
281   -- absence type is increasing or decreasing. This is
282   -- because the element could be linked to n number of absence
283   -- types (1/2 could be increasing and 1/2 could be decreasing).
284   --
285   open  c_get_upload_elements;
286   loop
287 
288     fetch c_get_upload_elements into l_screen_entry_value
289                                     ,l_effective_start_date
290                                     ,l_effective_end_date;
291 
292     exit when c_get_upload_elements%notfound;
293 
294     --
295     -- Add to the running total balance.
296     --
297     if l_hours_or_days = 'D' then
298 
299       hr_utility.set_location(l_proc, 65);
300       p_running_total_days := p_running_total_days + l_screen_entry_value;
301 
302     elsif l_hours_or_days = 'H' then
303 
304       hr_utility.set_location(l_proc, 70);
305       p_running_total_hours := p_running_total_hours + l_screen_entry_value;
306 
307     end if;
308 
309     --
310     -- If its in the current year add the year to date balance.
311     --
312     if to_char(l_effective_start_date, 'YYYY') = to_char(p_effective_date, 'YYYY')
313       and to_char(l_effective_end_date, 'YYYY') = to_char(p_effective_date, 'YYYY')
314     then
315 
316       hr_utility.set_location(l_proc, 75);
317 
318       if l_hours_or_days = 'D' then
319         p_year_to_date_days := p_year_to_date_days + l_screen_entry_value;
320 
321       elsif l_hours_or_days = 'H' then
322         p_year_to_date_hours := p_year_to_date_hours + l_screen_entry_value;
323 
324       end if;
325 
326     end if;
327 
328   end loop;
329 
330   hr_utility.set_location(l_proc, 80);
331   --
332   -- Null out any irrelevant balances.
333   --
334   if l_hours_or_days = 'D' then
335     p_running_total_hours := null;
336     p_year_to_date_hours  := null;
337 
338   elsif l_hours_or_days = 'H' then
339     p_running_total_days  := null;
340     p_year_to_date_days   := null;
341 
342   else
343     p_running_total_hours := null;
344     p_year_to_date_hours  := null;
345     p_running_total_days  := null;
346     p_year_to_date_days   := null;
347 
348   end if;
349 
350   hr_utility.set_location('Leaving:'|| l_proc, 85);
351 
352 end get_running_totals;
353 --
354 --  ---------------------------------------------------------------------------
355 --  |---------------------<  per_valid_for_absence  >-------------------------|
356 --  ---------------------------------------------------------------------------
357 --
358 --  Description:
359 --    This function validates that the person exists and that they have
360 --    a valid period of service or period of placement for the entire absence
361 --    duration.
362 --
363 --  Pre-conditions:
364 --    None.
365 --
366 --  In Arguments:
367 --    p_person_id
368 --    p_business_group_id
369 --    p_person_type
370 --    p_date_projected_start
371 --    p_date_projected_end
372 --    p_date_start
373 --    p_date_end
374 --
375 --  Post Success:
376 --    If validation passes, the function returns TRUE.
377 --
378 --  Post Failure:
379 --    IF validation fails, the function returns FALSE.
380 --
381 --  Access Status:
382 --    Internal Table Handler Use Only. API updating is not required as this
383 --    is called from other chk procedures that use API updating.
384 --
385 -- {End Of Comments}
386 -- ----------------------------------------------------------------------------
387 function per_valid_for_absence
388   (p_person_id            in number
389   ,p_business_group_id    in number
390   ,p_date_projected_start in date
391   ,p_date_projected_end   in date
392   ,p_date_start           in date
393   ,p_date_end             in date) return boolean
394 is
395 
396   --
397   -- Check the person is valid for the entire absence term.
398   -- For contingent workers there is a join to per_all_workforce_v
399   -- so that contingent workers are only included when the profile
400   -- option HR_TREAT_CWK_AS_EMP is Yes.
401   --
402   cursor c_per_valid_for_absence is
403   select null
404   from   per_all_people_f ppf,
405          per_periods_of_service pos
406   where  ppf.person_id = p_person_id
407   and    ppf.person_id = pos.person_id
408   and    ppf.current_employee_flag = 'Y'
409   and  ((nvl(fnd_profile.value('HR_CROSS_BUSINESS_GROUP'), 'N') = 'N' and
410          ppf.business_group_id = p_business_group_id)
411    or    nvl(fnd_profile.value('HR_CROSS_BUSINESS_GROUP'), 'N') = 'Y')
412   and   (p_date_projected_start is null or p_date_projected_start
413          between pos.date_start and nvl(pos.actual_termination_date,hr_api.g_eot))
414   and   (p_date_projected_end is null or p_date_projected_end
415          between pos.date_start and nvl(pos.actual_termination_date,hr_api.g_eot))
416   and   (p_date_start is null or p_date_start
417          between pos.date_start and nvl(pos.actual_termination_date,hr_api.g_eot))
418   and   (p_date_end is null or p_date_end
419          between pos.date_start and nvl(pos.actual_termination_date,hr_api.g_eot))
420   union select null
421   from   per_all_people_f ppf,
422          per_periods_of_placement pop,
423          per_all_workforce_v pawv
424   where  ppf.person_id = p_person_id
425   and    ppf.person_id = pop.person_id
426   and    ppf.person_id = pawv.person_id
427   and    ppf.current_npw_flag = 'Y'
428   and  ((nvl(fnd_profile.value('HR_CROSS_BUSINESS_GROUP'), 'N') = 'N' and
429          ppf.business_group_id = p_business_group_id)
430    or    nvl(fnd_profile.value('HR_CROSS_BUSINESS_GROUP'), 'N') = 'Y')
431   and   (p_date_projected_start is null or p_date_projected_start
432          between pop.date_start and nvl(pop.actual_termination_date,hr_api.g_eot))
433   and   (p_date_projected_end is null or p_date_projected_end
434          between pop.date_start and nvl(pop.actual_termination_date,hr_api.g_eot))
435   and   (p_date_start is null or p_date_start
436          between pop.date_start and nvl(pop.actual_termination_date,hr_api.g_eot))
437   and   (p_date_end is null or p_date_end
438          between pop.date_start and nvl(pop.actual_termination_date,hr_api.g_eot));
439 
440   --
441   l_proc    varchar2(72)  :=  g_package||'per_valid_for_absence';
442   l_exists  varchar2(1);
443   --
444 
445 begin
446 
447   hr_utility.set_location('Entering:'|| l_proc, 10);
448 
449   --
450   -- Check that the person exists and that they have a valid period of
451   -- service for the entire absence duration.
452   --
453   open  c_per_valid_for_absence;
454   fetch c_per_valid_for_absence into l_exists;
455 
456   if c_per_valid_for_absence%found then
457     --
458     -- Person is found and they have a valid period of service.
459     --
460     return TRUE;
461   else
462     --
463     -- Person is invalid or the period of service is not valid
464     -- for the duration of the absence.
465     --
466     return FALSE;
467   end if;
468 
469   close c_per_valid_for_absence;
470 
471   --
472   hr_utility.set_location('Leaving:'|| l_proc, 20);
473 
474 end per_valid_for_absence;
475 --
476 --  ---------------------------------------------------------------------------
477 --  |---------------------------<  convert_to_minutes >-----------------------|
478 --  ---------------------------------------------------------------------------
479 --
480 --  Description:
481 --   Converts two times into duration minutes.
482 --
483 --  Pre-conditions:
484 --
485 --  In Arguments:
486 --    p_time_start
487 --    p_time_end
488 --
489 --  Post Success:
490 --    The function returns duration minutes and processing continues.
491 --
492 --  Post Failure:
493 --    The function errors and processing stops.
494 --
495 --  Access Status:
496 --    Internal Development Use Only.
497 --
498 -- {End Of Comments}
499 -- ----------------------------------------------------------------------------
500 function convert_to_minutes
501   (p_time_start in varchar2
502   ,p_time_end   in varchar2) return number
503 is
504   --
505   l_proc           varchar2(72)  :=  g_package||'convert_to_minutes';
506   l_time_duration  number;
507 
508   cursor c_get_time_duration is
509   select ((substr(p_time_end,1,2) * 60) + substr(p_time_end,4,2)) -
510          ((substr(p_time_start,1,2) * 60) + substr(p_time_start,4,2))
511   from   dual;
512   --
513 
514 begin
515 
516   hr_utility.set_location('Entering:'|| l_proc, 10);
517 
518   --
519   -- Calculate the total time in minutes between the start time
520   -- and the end time.
521   --
522   open  c_get_time_duration;
523   fetch c_get_time_duration into l_time_duration;
524   close c_get_time_duration;
525 
526   hr_utility.set_location(' Leaving:'|| l_proc, 20);
527 
528   return l_time_duration;
529 
530 end convert_to_minutes;
531 --
532 --  ---------------------------------------------------------------------------
533 --  |---------------------------<  chk_time_format >--------------------------|
534 --  ---------------------------------------------------------------------------
535 --
536 --  Description:
537 --   Checks that the time format is valid.
538 --
539 --  Pre-conditions:
540 --
541 --  In Arguments:
542 --    p_time
543 --
544 --  Post Success:
545 --    If the time format is valid, processing continues.
546 --
547 --  Post Failure:
548 --    If the time format is invalid processing stops and an error is raised.
549 --
550 --  Access Status:
551 --    Internal Development Use Only.
552 --
553 -- {End Of Comments}
554 -- ----------------------------------------------------------------------------
555 --
556 procedure chk_time_format
557   (p_time in varchar2)
558 is
559   --
560   l_proc              varchar2(72)  :=  g_package||'chk_time_format';
561   --
562 
563 begin
564   hr_utility.set_location('Entering:'|| l_proc, 10);
565   --
566 
567   if p_time is not null then
568      if not (substr(p_time,1,2) between '00' and '23'
569         and substr(p_time,4,2) between '00' and '59'
570         and substr(p_time,3,1) = ':'
571         and length(p_time) = 5) then
572         fnd_message.set_name('PAY','HR_6004_ALL_FORMAT_HHMM');
573         fnd_message.raise_error;
574      end if;
575   end if;
576 
577   --
578   hr_utility.set_location(' Leaving:'|| l_proc, 50);
579 end chk_time_format;
580 --
581 --  +-------------------------------------------------------------------------+
582 --  |-----------------<      good_time_format       >-------------------------|
583 --  +-------------------------------------------------------------------------+
584 --  Description:
585 --    Tests CHAR values for valid time.
586 --
587 --  Pre-conditions:
588 --    None.
589 --
590 --  In Arguments:
591 --    p_time VARCHAR2
592 --
593 --  Out Arguments:
594 --    BOOLEAN
595 --
596 --  Post Success:
597 --    Returns TRUE or FALSE depending on valid time or not.
598 --
599 --  Post Failure:
600 --    Returns FALSE for invalid time.
601 --
602 --  Access Status:
603 --    Internal Development Use Only.
604 --
605 -- {End Of Comments}
606 -- ----------------------------------------------------------------------------
607 --
608 FUNCTION good_time_format ( p_time IN VARCHAR2 ) RETURN BOOLEAN IS
609 --
610 BEGIN
611   --
612   IF p_time IS NOT NULL THEN
613     --
614     IF NOT (SUBSTR(p_time,1,2) BETWEEN '00' AND '23' AND
615             SUBSTR(p_time,4,2) BETWEEN '00' AND '59' AND
616             SUBSTR(p_time,3,1) = ':' AND
617             LENGTH(p_time) = 5) THEN
618       RETURN FALSE;
619     ELSE
620       RETURN TRUE;
621     END IF;
622     --
623   ELSE
624     RETURN FALSE;
625   END IF;
626   --
627 EXCEPTION
628   --
629   WHEN OTHERS THEN
630     RETURN FALSE;
631   --
632 END good_time_format;
633 --
634 --  +-------------------------------------------------------------------------+
635 --  |-----------------<     calc_sch_based_dur      >-------------------------|
636 --  +-------------------------------------------------------------------------+
637 --  Description:
638 --    Calculate the absence duration in hours/days based on the work schedule.
639 --
640 --  Pre-conditions:
641 --    None.
642 --
643 --  In Arguments:
644 --    p_days_or_hours VARCHAR2
645 --    p_date_start    DATE
646 --    p_date_end      DATE
647 --    p_time_start    VARCHAR2
648 --    p_time_end      VARCHAR2
649 --    p_assignment_id NUMBER
650 --
651 --  Out Arguments:
652 --    p_duration NUMBER
653 --
654 --  Post Success:
655 --    Value returned for absence duration.
656 --
657 --  Post Failure:
658 --    If a failure occurs, an application error is raised and
659 --    processing terminates.
660 --
661 --  Access Status:
662 --    Internal Development Use Only.
663 --
664 -- {End Of Comments}
665 -- ----------------------------------------------------------------------------
666 --
667 PROCEDURE calc_sch_based_dur ( p_days_or_hours IN VARCHAR2,
668                                p_date_start    IN DATE,
669                                p_date_end      IN DATE,
670                                p_time_start    IN VARCHAR2,
671                                p_time_end      IN VARCHAR2,
672                                p_assignment_id IN NUMBER,
673                                p_duration      IN OUT NOCOPY NUMBER
674                              ) IS
675   --
676   l_idx             NUMBER;
677   l_ref_date        DATE;
678   l_first_band      BOOLEAN;
679   l_day_start_time  VARCHAR2(5);
680   l_day_end_time    VARCHAR2(5);
681   l_start_time      VARCHAR2(5);
682   l_end_time        VARCHAR2(5);
683   --
684   l_start_date      DATE;
685   l_end_date        DATE;
686   l_schedule        cac_avlblty_time_varray;
687   l_schedule_source VARCHAR2(10);
688   l_return_status   VARCHAR2(1);
689   l_return_message  VARCHAR2(2000);
690   --
691   l_time_start      VARCHAR2(5);
692   l_time_end        VARCHAR2(5);
693   --
694   e_bad_time_format EXCEPTION;
695   --
696 BEGIN
697   hr_utility.set_location('Entering '||g_package||'.calc_sch_based_dur',10);
698   p_duration := 0;
699   l_time_start := p_time_start;
700   l_time_end := p_time_end;
701   --
702   IF l_time_start IS NULL THEN
703     l_time_start := '00:00';
704   ELSE
705     IF NOT good_time_format(l_time_start) THEN
706       RAISE e_bad_time_format;
707     END IF;
708   END IF;
709   /*
710   IF l_time_end IS NULL THEN
711     l_time_end := '23:59';  --changed for bug #6274821
712   ELSE
713     IF NOT good_time_format(l_time_end) THEN
714       RAISE e_bad_time_format;
715     END IF;
716   END IF;
717   */
718   -- fix for the bug 6711896
719    IF l_time_end IS NULL THEN
720 
721    IF p_days_or_hours = 'D' THEN
722       l_time_end := '00:00';
723   else
724     l_time_end := '23:59';
725  --  l_time_end := '00:00';
726    END IF;
727 
728   ELSE
729     IF NOT good_time_format(l_time_end) THEN
730       RAISE e_bad_time_format;
731     END IF;
732   END IF;
733   --fix for the bug 6711896
734   l_start_date := TO_DATE(TO_CHAR(p_date_start,'DD-MM-YYYY')||' '||l_time_start,'DD-MM-YYYY HH24:MI');
735   l_end_date := TO_DATE(TO_CHAR(p_date_end,'DD-MM-YYYY')||' '||l_time_end,'DD-MM-YYYY HH24:MI');
736   IF p_days_or_hours = 'D' THEN
737     l_end_date := l_end_date + 1;
738   END IF;
739   --
740   -- Fetch the work schedule
741   --
742   hr_wrk_sch_pkg.get_per_asg_schedule
743   ( p_person_assignment_id => p_assignment_id
744   , p_period_start_date    => l_start_date
745   , p_period_end_date      => l_end_date
746   , p_schedule_category    => NULL
747   , p_include_exceptions   => 'Y'
748   , p_busy_tentative_as    => 'FREE'
749   , x_schedule_source      => l_schedule_source
750   , x_schedule             => l_schedule
751   , x_return_status        => l_return_status
752   , x_return_message       => l_return_message
753   );
754   --
755   IF l_return_status = '0' THEN
756     --
757     -- Calculate duration
758     --
759     l_idx := l_schedule.first;
760     --
761     IF p_days_or_hours = 'D' THEN
762       --
763       l_first_band := TRUE;
764       l_ref_date := NULL;
765       WHILE l_idx IS NOT NULL
766       LOOP
767         IF l_schedule(l_idx).FREE_BUSY_TYPE IS NOT NULL THEN
768           IF l_schedule(l_idx).FREE_BUSY_TYPE = 'FREE' THEN
769             IF l_first_band THEN
770               l_first_band := FALSE;
771               l_ref_date := TRUNC(l_schedule(l_idx).START_DATE_TIME);
772               IF (TRUNC(l_schedule(l_idx).END_DATE_TIME) = TRUNC(l_schedule(l_idx).START_DATE_TIME)) THEN
773                 p_duration := p_duration + (TRUNC(l_schedule(l_idx).END_DATE_TIME) - TRUNC(l_schedule(l_idx).START_DATE_TIME) + 1);
774               ELSE
775                 p_duration := p_duration + (TRUNC(l_schedule(l_idx).END_DATE_TIME) - TRUNC(l_schedule(l_idx).START_DATE_TIME));
776               END IF;
777             ELSE -- not first time
778               IF TRUNC(l_schedule(l_idx).START_DATE_TIME) = l_ref_date THEN
779                 p_duration := p_duration + (TRUNC(l_schedule(l_idx).END_DATE_TIME) - TRUNC(l_schedule(l_idx).START_DATE_TIME));
780               ELSE
781                 l_ref_date := TRUNC(l_schedule(l_idx).END_DATE_TIME);
782                 IF (TRUNC(l_schedule(l_idx).END_DATE_TIME) = TRUNC(l_schedule(l_idx).START_DATE_TIME)) THEN
783                   p_duration := p_duration + (TRUNC(l_schedule(l_idx).END_DATE_TIME) - TRUNC(l_schedule(l_idx).START_DATE_TIME) + 1);
784                 ELSE
785                   p_duration := p_duration + (TRUNC(l_schedule(l_idx).END_DATE_TIME) - TRUNC(l_schedule(l_idx).START_DATE_TIME));
786                 END IF;
787               END IF;
788             END IF;
789           END IF;
790         END IF;
791         l_idx := l_schedule(l_idx).NEXT_OBJECT_INDEX;
792       END LOOP;
793       --
794     ELSE -- p_days_or_hours is 'H'
795       --
796       l_day_start_time := '00:00';
797       l_day_end_time := '23:59';
798       WHILE l_idx IS NOT NULL
799       LOOP
800         IF l_schedule(l_idx).FREE_BUSY_TYPE IS NOT NULL THEN
801           IF l_schedule(l_idx).FREE_BUSY_TYPE = 'FREE' THEN
802             IF l_schedule(l_idx).END_DATE_TIME < l_schedule(l_idx).START_DATE_TIME THEN
803               -- Skip this invalid slot which ends before it starts
804               NULL;
805             ELSE
806               IF TRUNC(l_schedule(l_idx).END_DATE_TIME) > TRUNC(l_schedule(l_idx).START_DATE_TIME) THEN
807                 -- Start and End on different days
808                 --
809                 -- Get first day hours
810                 l_start_time := TO_CHAR(l_schedule(l_idx).START_DATE_TIME,'HH24:MI');
811                 SELECT p_duration + (((SUBSTR(l_day_end_time,1,2)*60 + SUBSTR(l_day_end_time,4,2)) -
812                                       (SUBSTR(l_start_time,1,2)*60 + SUBSTR(l_start_time,4,2)))/60)
813                 INTO p_duration
814                 FROM DUAL;
815                 --
816                 -- Get last day hours
817                 l_end_time := TO_CHAR(l_schedule(l_idx).END_DATE_TIME,'HH24:MI');
818                 SELECT p_duration + (((SUBSTR(l_end_time,1,2)*60 + SUBSTR(l_end_time,4,2)) -
819                                       (SUBSTR(l_day_start_time,1,2)*60 + SUBSTR(l_day_start_time,4,2)) + 1)/60)
820                 INTO p_duration
821                 FROM DUAL;
822                 --
823                 -- Get between full day hours
824                 SELECT p_duration + ((TRUNC(l_schedule(l_idx).END_DATE_TIME) - TRUNC(l_schedule(l_idx).START_DATE_TIME) - 1) * 24)
825                 INTO p_duration
826                 FROM DUAL;
827               ELSE
828                 -- Start and End on same day
829                 l_start_time := TO_CHAR(l_schedule(l_idx).START_DATE_TIME,'HH24:MI');
830                 l_end_time := TO_CHAR(l_schedule(l_idx).END_DATE_TIME,'HH24:MI');
831                 SELECT p_duration + (((SUBSTR(l_end_time,1,2)*60 + SUBSTR(l_end_time,4,2)) -
832                                       (SUBSTR(l_start_time,1,2)*60 + SUBSTR(l_start_time,4,2)))/60)
833                 INTO p_duration
834                 FROM DUAL;
835               END IF;
836             END IF;
837           END IF;
838         END IF;
839         l_idx := l_schedule(l_idx).NEXT_OBJECT_INDEX;
840       END LOOP;
841       p_duration := ROUND(p_duration,2);
842       --
843     END IF;
844   END IF;
845   --
846   hr_utility.set_location('Leaving '||g_package||'.calc_sch_based_dur',20);
847 EXCEPTION
848   --
849   WHEN e_bad_time_format THEN
850     hr_utility.set_location('Leaving '||g_package||'.calc_sch_based_dur',30);
851     hr_utility.set_location(SQLERRM,35);
852     RAISE;
853   --
854   WHEN OTHERS THEN
855     hr_utility.set_location('Leaving '||g_package||'.calc_sch_based_dur',40);
856     hr_utility.set_location(SQLERRM,45);
857     RAISE;
858   --
859 END calc_sch_based_dur;
860 --
861 --  ---------------------------------------------------------------------------
862 --  |-----------------<  calculate_absence_duration -old>-------------------------|
863 --  ---------------------------------------------------------------------------
864 --
865 --  Description:
866 --    Calculates the absence duration in hours and / or days and sets
867 --    the duration.
868 --
869 --  Pre-conditions:
870 --    None.
871 --
872 --  In Arguments:
873 --    p_absence_attendance_id
874 --    p_absence_attendance_type_id
875 --    p_business_group_id
876 --    p_object_version_number
877 --    p_effective_date
878 --    p_person_id
879 --    p_date_start
880 --    p_date_end
881 --    p_time_start
882 --    p_time_end
883 --
884 --  Out Arguments:
885 --    p_absence_days
886 --    p_absence_hours
887 --    p_use_formula
888 --
889 --  Post Success:
890 --    The absence duration in days and hours is returned.
891 --
892 --  Post Failure:
893 --    If a failure occurs, an application error is raised and
894 --    processing terminates.
895 --
896 --  Access Status:
897 --    Internal Development Use Only.
898 --
899 -- {End Of Comments}
900 --  ---------------------------------------------------------------------------
901 --  |-----------------<  calculate_absence_duration -old>-------------------------|
902 --  ---------------------------------------------------------------------------
903 --
904 --
905 procedure calculate_absence_duration
906  (p_absence_attendance_id      in  number
907  ,p_absence_attendance_type_id in  number
908  ,p_business_group_id          in  number
909  ,p_object_version_number      in  number
910  ,p_effective_date             in  date
911  ,p_person_id                  in  number
912  ,p_date_start                 in  date
913  ,p_date_end                   in  date
914  ,p_time_start                 in  varchar2
915  ,p_time_end                   in  varchar2
916  ,p_absence_days               out nocopy number
917  ,p_absence_hours              out nocopy number
918  ,p_use_formula                out nocopy boolean)
919   is
920 
921   l_proc                 varchar2(72) := g_package||
922                                         'calculate_absence_duration';
923   l_exists               varchar2(1);
924   l_api_updating         boolean;
925   l_assignment_id        number;
926   l_hours_or_days        varchar2(1);
927   l_element_type_id      number;
928   l_legislation_code     varchar2(150);
929   l_formula_id           number;
930   l_inputs               ff_exec.inputs_t;
931   l_outputs              ff_exec.outputs_t;
932   l_user_message         varchar2(1) := 'N';
933   l_invalid_message      fnd_new_messages.message_text%TYPE;
934 
935   /*Added for the bug 6790565 - starts here*/
936   l_invalid_message_txt fnd_new_messages.message_text%TYPE;
937   l_invalid_message_num number;
938   /*Added for the bug 6790565 - ends here*/
939 
940   wrong_parameters       exception;
941   l_normal_time_start    varchar2(5);
942   l_normal_time_end      varchar2(5);
943   l_normal_day_minutes   number;
944   l_first_day_minutes    number;
945   l_last_day_minutes     number;
946   l_same_day_minutes     number;
947   l_absence_days         number;
948   l_absence_hours        number;
949 
950   -- For schedule based calculation
951   l_sch_based_dur        VARCHAR2(1);
952   l_sch_based_dur_found  BOOLEAN;
953   l_absence_duration     NUMBER;
954 
955   --3093970 starts here. comment out the code introduced by 2820155.
956   --2820155 change starts
957   -- l_eff_time_start varchar2(5);
958   -- l_eff_time_end varchar2(5);
959   --2820155 change ends
960   --3093970 ends here.
961 
962   cursor c_get_absence_info is
963   select abt.hours_or_days,
964          piv.element_type_id
965   from   per_absence_attendance_types abt,
966          pay_input_values_f piv
967   where  abt.absence_attendance_type_id = p_absence_attendance_type_id
968   and    abt.input_value_id = piv.input_value_id(+);
969   --
970   cursor c_get_normal_hours (p_assignment_id in number) is
971   select nvl(nvl(asg.time_normal_start, pbg.default_start_time), '00:00'),
972          nvl(nvl(asg.time_normal_finish, pbg.default_end_time), '23:59')
973   FROM   per_all_assignments_f asg,
974          per_business_groups pbg
975   WHERE  asg.assignment_id = p_assignment_id
976   AND    asg.business_group_id = pbg.business_group_id
977   AND    p_effective_date between asg.effective_start_date
978                           and     asg.effective_end_date;
979 
980 --
981 
982   l_use_formula              boolean;
983 
984 begin
985 
986   hr_utility.set_location('Entering Old:'|| l_proc, 10);
987   per_abs_bus.calculate_absence_duration
988 	(p_absence_attendance_id      => p_absence_attendance_id
989        ,p_absence_attendance_type_id => p_absence_attendance_type_id
990        ,p_business_group_id          => p_business_group_id
991        ,p_object_version_number      => p_object_version_number
992        ,p_effective_date             => p_effective_date
993        ,p_person_id                  => p_person_id
994        ,p_date_start                 => p_date_start
995        ,p_date_end                   => p_date_end
996        ,p_time_start                 => p_time_start
997        ,p_time_end                   => p_time_end
998 	,p_ABS_INFORMATION_CATEGORY   => NULL
999         ,p_ABS_INFORMATION1          => NULL
1000         ,p_ABS_INFORMATION2          => NULL
1001 	,p_ABS_INFORMATION3          => NULL
1002 	,p_ABS_INFORMATION4          => NULL
1003 	,p_ABS_INFORMATION5          => NULL
1004 	,p_ABS_INFORMATION6          => NULL
1005         ,p_absence_days               => l_absence_days
1006         ,p_absence_hours              => l_absence_hours
1007         ,p_use_formula                => l_use_formula);
1008 
1009  p_absence_hours := l_absence_hours;
1010  p_absence_days := l_absence_days;
1011  p_use_formula :=l_use_formula;
1012 
1013  hr_utility.set_location('leaving old:'|| l_proc, 10);
1014 end;
1015 --  ---------------------------------------------------------------------------
1016 --  |-----------------<  calculate_absence_duration -new>-------------------------|
1017 --  ---------------------------------------------------------------------------
1018 --
1019 --  Description:
1020 --    Calculates the absence duration in hours and / or days and sets
1021 --    the duration.
1022 --
1023 --  Pre-conditions:
1024 --    None.
1025 --
1026 --  In Arguments:
1027 --    p_absence_attendance_id
1028 --    p_absence_attendance_type_id
1029 --    p_business_group_id
1030 --    p_object_version_number
1031 --    p_effective_date
1032 --    p_person_id
1033 --    p_date_start
1034 --    p_date_end
1035 --    p_time_start
1036 --    p_time_end
1037 --    p_ABS_INFORMATION_CATEGORY
1038 --    p_ABS_INFORMATION1
1039 --    p_ABS_INFORMATION2
1040 --    p_ABS_INFORMATION3
1041 --    p_ABS_INFORMATION4
1042 --    p_ABS_INFORMATION5
1043 --    p_ABS_INFORMATION6
1044 
1045 --  Out Arguments:
1046 --    p_absence_days
1047 --    p_absence_hours
1048 --    p_use_formula
1049 --
1050 --  Post Success:
1051 --    The absence duration in days and hours is returned.
1052 --
1053 --  Post Failure:
1054 --    If a failure occurs, an application error is raised and
1055 --    processing terminates.
1056 --
1057 --  Access Status:
1058 --    Internal Development Use Only.
1059 --
1060 -- {End Of Comments}
1061 -- ----------------------------------------------------------------------------
1062 --
1063 procedure calculate_absence_duration
1064  (p_absence_attendance_id      in  number
1065  ,p_absence_attendance_type_id in  number
1066  ,p_business_group_id          in  number
1067  ,p_object_version_number      in  number
1068  ,p_effective_date             in  date
1069  ,p_person_id                  in  number
1070  ,p_date_start                 in  date
1071  ,p_date_end                   in  date
1072  ,p_time_start                 in  varchar2
1073  ,p_time_end                   in  varchar2
1074  ,p_ABS_INFORMATION_CATEGORY   in varchar2
1075  ,p_ABS_INFORMATION1          in varchar2
1076  ,p_ABS_INFORMATION2          in varchar2
1077  ,p_ABS_INFORMATION3          in varchar2
1078  ,p_ABS_INFORMATION4          in varchar2
1079  ,p_ABS_INFORMATION5          in varchar2
1080  ,p_ABS_INFORMATION6          in varchar2
1081  ,p_absence_days               out nocopy number
1082  ,p_absence_hours              out nocopy number
1083  ,p_use_formula                out nocopy boolean)
1084   is
1085 
1086   l_proc                 varchar2(72) := g_package||
1087                                         'calculate_absence_duration';
1088   l_exists               varchar2(1);
1089   l_api_updating         boolean;
1090   l_assignment_id        number;
1091   l_hours_or_days        varchar2(1);
1092   l_element_type_id      number;
1093   l_legislation_code     varchar2(150);
1094   l_formula_id           number;
1095   l_inputs               ff_exec.inputs_t;
1096   l_outputs              ff_exec.outputs_t;
1097   l_user_message         varchar2(1) := 'N';
1098   l_invalid_message      fnd_new_messages.message_text%TYPE;
1099 
1100   /*Added for the bug 6790565 - starts here*/
1101   l_invalid_message_txt fnd_new_messages.message_text%TYPE;
1102   l_invalid_message_num number;
1103   /*Added for the bug 6790565 - ends here*/
1104 
1105   wrong_parameters       exception;
1106   l_normal_time_start    varchar2(5);
1107   l_normal_time_end      varchar2(5);
1108   l_normal_day_minutes   number;
1109   l_first_day_minutes    number;
1110   l_last_day_minutes     number;
1111   l_same_day_minutes     number;
1112   l_absence_days         number;
1113   l_absence_hours        number;
1114 
1115   -- For schedule based calculation
1116   l_sch_based_dur        VARCHAR2(1);
1117   l_sch_based_dur_found  BOOLEAN;
1118   l_absence_duration     NUMBER;
1119 
1120   --3093970 starts here. comment out the code introduced by 2820155.
1121   --2820155 change starts
1122   -- l_eff_time_start varchar2(5);
1123   -- l_eff_time_end varchar2(5);
1124   --2820155 change ends
1125   --3093970 ends here.
1126 
1127   cursor c_get_absence_info is
1128   select abt.hours_or_days,
1129          piv.element_type_id
1130   from   per_absence_attendance_types abt,
1131          pay_input_values_f piv
1132   where  abt.absence_attendance_type_id = p_absence_attendance_type_id
1133   and    abt.input_value_id = piv.input_value_id(+);
1134   --
1135   cursor c_get_normal_hours (p_assignment_id in number) is
1136   select nvl(nvl(asg.time_normal_start, pbg.default_start_time), '00:00'),
1137          nvl(nvl(asg.time_normal_finish, pbg.default_end_time), '23:59')
1138   FROM   per_all_assignments_f asg,
1139          per_business_groups pbg
1140   WHERE  asg.assignment_id = p_assignment_id
1141   AND    asg.business_group_id = pbg.business_group_id
1142   AND    p_effective_date between asg.effective_start_date
1143                           and     asg.effective_end_date;
1144 
1145 --
1146 begin
1147 
1148   hr_utility.set_location('Entering:'|| l_proc, 10);
1149   --
1150   -- Only proceed with validation if :
1151   -- a) The current g_old_rec is current and
1152   -- b) The date values have changed
1153   --
1154   l_api_updating := per_abs_shd.api_updating
1155          (p_absence_attendance_id  => p_absence_attendance_id
1156          ,p_object_version_number  => p_object_version_number);
1157   --
1158   if (l_api_updating
1159   and nvl(per_abs_shd.g_old_rec.date_start, hr_api.g_date)
1160     = nvl(p_date_start, hr_api.g_date)
1161   and nvl(per_abs_shd.g_old_rec.date_end, hr_api.g_date)
1162     = nvl(p_date_end, hr_api.g_date)
1163   and nvl(per_abs_shd.g_old_rec.time_start, hr_api.g_varchar2)
1164     = nvl(p_time_start, hr_api.g_varchar2)
1165   and nvl(per_abs_shd.g_old_rec.time_end, hr_api.g_varchar2)
1166     = nvl(p_time_end, hr_api.g_varchar2)
1167   and nvl(per_abs_shd.g_old_rec.absence_days, hr_api.g_number)
1168     = nvl(p_absence_days, hr_api.g_number)
1169   and nvl(per_abs_shd.g_old_rec.absence_hours, hr_api.g_number)
1170     = nvl(p_absence_hours, hr_api.g_number)) then
1171      return;
1172   end if;
1173 
1174   hr_utility.set_location(l_proc, 15);
1175 
1176   --
1177   -- See if a Fast Formula exists. Here the Fast Formula names
1178   -- are hard-coded. Fast Formulas with these exact names can
1179   -- be defined at one of three levels to default the absence
1180   -- duration:
1181   --
1182   --  1. Business group (customer-definable)
1183   --  2. Legislation (Oracle internal legislation-specific)
1184   --  3. Core (Oracle internal core product)
1185   --
1186 
1187   --
1188   -- Get the varous additional values that are required for use later.
1189   --
1190 
1191   l_assignment_id := hr_person_absence_api.get_primary_assignment
1192       (p_person_id         => p_person_id
1193       ,p_effective_date    => p_effective_date);
1194 
1195   l_legislation_code := hr_api.return_legislation_code
1196       (p_business_group_id => p_business_group_id);
1197 
1198   open  c_get_absence_info;
1199   fetch c_get_absence_info into l_hours_or_days,
1200                                 l_element_type_id;
1201   close c_get_absence_info;
1202 
1203   l_sch_based_dur := NVL(FND_PROFILE.Value('HR_SCH_BASED_ABS_CALC'),'N');
1204   l_sch_based_dur_found := FALSE;
1205   --
1206   IF l_sch_based_dur = 'Y' THEN
1207     --
1208     hr_utility.set_location(l_proc, 16);
1209     p_use_formula := TRUE; -- set to display
1210     --
1211     calc_sch_based_dur (p_days_or_hours => l_hours_or_days,
1212                         p_date_start    => p_date_start,
1213                         p_date_end      => p_date_end,
1214                         p_time_start    => p_time_start,
1215                         p_time_end      => p_time_end,
1216                         p_assignment_id => l_assignment_id,
1217                         p_duration      => l_absence_duration
1218                        );
1219     --
1220     IF l_absence_duration IS NOT NULL THEN
1221       --
1222       l_sch_based_dur_found := TRUE;
1223       --
1224       IF l_hours_or_days = 'H' THEN
1225         hr_utility.set_location(l_proc, 17);
1226         p_absence_hours := l_absence_duration;
1227       ELSIF l_hours_or_days = 'D' THEN
1228         hr_utility.set_location(l_proc, 18);
1229         p_absence_days := l_absence_duration;
1230       ELSE
1231         hr_utility.set_location(l_proc, 19);
1232         l_sch_based_dur_found := FALSE;
1233       END IF;
1234       --
1235     END IF;
1236     --
1237   END IF; -- sch_based_dur is 'Y'
1238 
1239   IF l_sch_based_dur <> 'Y' OR (l_sch_based_dur = 'Y' AND NOT l_sch_based_dur_found) THEN
1240   --
1241   hr_utility.set_location(l_proc, 20);
1242 
1243   begin
1244     --
1245     -- Look for a customer-defined formula
1246     --
1247     select ff.formula_id
1248     into   l_formula_id
1249     from   ff_formulas_f ff
1250     where  ff.formula_name = 'BG_ABSENCE_DURATION'
1251     and    ff.business_group_id = p_business_group_id
1252     and    p_effective_date between ff.effective_start_date and
1253                                     ff.effective_end_date;
1254   exception
1255 
1256     when no_data_found then
1257       --
1258       -- There is no customer defined formula so look for
1259       -- a legislative formula.
1260       --
1261       begin
1262 
1263         hr_utility.set_location(l_proc, 25);
1264 
1265         select ff.formula_id
1266         into   l_formula_id
1267         from   ff_formulas_f ff
1268         where  ff.formula_name = 'LEGISLATION_ABSENCE_DURATION'
1269         and    ff.legislation_code = l_legislation_code
1270         and    ff.business_group_id is null
1271         and    p_effective_date between ff.effective_start_date and
1272                                         ff.effective_end_date;
1273 
1274       exception
1275 
1276         when no_data_found then
1277           --
1278           -- If none of the two above then select the core formula
1279           --
1280           begin
1281 
1282             hr_utility.set_location(l_proc, 30);
1283 
1284             select ff.formula_id
1285             into   l_formula_id
1286             from   ff_formulas_f ff
1287             where  ff.formula_name = 'CORE_ABSENCE_DURATION'
1288             and    ff.legislation_code is null
1289             and    ff.business_group_id is null
1290             and    p_effective_date between ff.effective_start_date and
1291                                             ff.effective_end_date;
1292 
1293           exception
1294 
1295             when no_data_found then
1296               --
1297               -- No formula is found. We capture the error and do nothing.
1298               --
1299               null;
1300 
1301           end;
1302       end;
1303   end;
1304 
1305   hr_utility.set_location(l_proc, 35);
1306 
1307   if l_formula_id is not null then
1308     --
1309     -- An absence duration Fast Formula should be used so the
1310     -- formula is called. First, the formula is initialised.
1311     --
1312     p_use_formula := TRUE;
1313 
1314     hr_utility.set_location(l_proc, 40);
1315 
1316     --
1317     ff_exec.reset_caches;   -- bug fix 9337533 to clear the cache..
1318 
1319     -- Initalise the formula.
1320     --
1321     ff_exec.init_formula
1322       (p_formula_id     => l_formula_id
1323       ,p_effective_date => p_effective_date
1324       ,p_inputs         => l_inputs
1325       ,p_outputs        => l_outputs);
1326 
1327     hr_utility.set_location(l_proc, 45);
1328 
1329     --
1330     -- Assign the inputs.
1331     --
1332     for i_input in l_inputs.first..l_inputs.last
1333     loop
1334 
1335       if l_inputs(i_input).name    = 'DAYS_OR_HOURS' then
1336          l_inputs(i_input).value  := l_hours_or_days;
1337       elsif l_inputs(i_input).name = 'DATE_START' then
1338          l_inputs(i_input).value  := fnd_date.date_to_canonical(p_date_start);
1339       elsif l_inputs(i_input).name = 'DATE_END' then
1340          l_inputs(i_input).value  := fnd_date.date_to_canonical(p_date_end);
1341       elsif l_inputs(i_input).name = 'TIME_START' then
1342          l_inputs(i_input).value  := p_time_start;
1343       elsif l_inputs(i_input).name = 'TIME_END' then
1344          l_inputs(i_input).value  := p_time_end;
1345       elsif l_inputs(i_input).name = 'DATE_EARNED' then
1346          l_inputs(i_input).value  := fnd_date.date_to_canonical
1347                                      (p_effective_date);
1348       elsif l_inputs(i_input).name = 'BUSINESS_GROUP_ID' then
1349          l_inputs(i_input).value  := p_business_group_id;
1350       elsif l_inputs(i_input).name = 'LEGISLATION_CODE' then
1351          l_inputs(i_input).value  := l_legislation_code;
1352       elsif l_inputs(i_input).name = 'ASSIGNMENT_ID' then
1353          l_inputs(i_input).value  := l_assignment_id;
1354       elsif l_inputs(i_input).name = 'ELEMENT_TYPE_ID' then
1355          l_inputs(i_input).value  := l_element_type_id;
1356       elsif l_inputs(i_input).name = 'ABSENCE_ATTENDANCE_TYPE_ID' then
1357          l_inputs(i_input).value  := p_absence_attendance_type_id;
1358       elsif l_inputs(i_input).name = 'ABS_INFORMATION_CATEGORY' then
1359          l_inputs(i_input).value  := p_ABS_INFORMATION_CATEGORY;
1360     elsif l_inputs(i_input).name = 'ABS_INFORMATION1' then
1361          l_inputs(i_input).value  := p_ABS_INFORMATION1;
1362     elsif l_inputs(i_input).name = 'ABS_INFORMATION2' then
1363          l_inputs(i_input).value  := p_ABS_INFORMATION2;
1364     elsif l_inputs(i_input).name = 'ABS_INFORMATION3' then
1365          l_inputs(i_input).value  := p_ABS_INFORMATION3;
1366     elsif l_inputs(i_input).name = 'ABS_INFORMATION4' then
1367          l_inputs(i_input).value  := p_ABS_INFORMATION4;
1368     elsif l_inputs(i_input).name = 'ABS_INFORMATION5' then
1369          l_inputs(i_input).value  := p_ABS_INFORMATION5;
1370     elsif l_inputs(i_input).name = 'ABS_INFORMATION6' then
1371          l_inputs(i_input).value  := p_ABS_INFORMATION6;
1372 
1373 
1374       else
1375          raise wrong_parameters;
1376       end if;
1377 
1378     end loop;
1379 
1380     hr_utility.set_location(l_proc, 50);
1381 
1382     --
1383     -- Run the formula.
1384     --
1385     ff_exec.run_formula(l_inputs, l_outputs);
1386 
1387     hr_utility.set_location(l_proc, 55);
1388 
1389     --
1390     -- Assign the outputs.
1391     --
1392     for i_output in l_outputs.first..l_outputs.last
1393     loop
1394 
1395       if l_outputs(i_output).name = 'DURATION' then
1396 
1397         if l_outputs(i_output).value = 'FAILED' then
1398           l_user_message := 'Y';
1399         else
1400           --
1401           -- The absence hours / days out parameter is set. If no UOM
1402           -- is set but the start or end time have been entered, the output
1403           -- is returned in hours.
1404           --
1405           if l_hours_or_days = 'H'
1406           or (p_time_start is not null and p_time_end is not null) then
1407             p_absence_hours := round(fnd_number.canonical_to_number(l_outputs(i_output).value),2);
1408           else
1409             p_absence_days := round(fnd_number.canonical_to_number(l_outputs(i_output).value),2);
1410           end if;
1411         end if;
1412 
1413       elsif l_outputs(i_output).name = 'INVALID_MSG' then
1414            --
1415            -- Here any customer-defined messages are set and
1416            -- raised after this loop.
1417            --
1418            l_invalid_message := l_outputs(i_output).value;
1419 
1420         null;
1421       else
1422         raise wrong_parameters;
1423       end if;
1424 
1425     end loop;
1426 
1427     hr_utility.set_location(l_proc, 60);
1428     hr_utility.trace('l_user_message: '||l_user_message);
1429     hr_utility.trace('l_invalid_message: '||l_invalid_message);
1430 
1431 
1432     /*Added for the bug 6790565 - starts here*/
1433     -- Displays the error message text if text is given
1434     -- directly in the fast formula
1435     -- Displays the error message text if the error message
1436     -- name is  given
1437     -- This is done as SSHR supports both text as well as name
1438     select instr(l_invalid_message,' ',1,1)
1439     into l_invalid_message_num from dual;
1440 
1441     if l_invalid_message_num = 0
1442     then
1443     l_invalid_message_txt := fnd_message.get_string('PER',l_invalid_message);
1444     else
1445     l_invalid_message_txt := l_invalid_message;
1446     end if;
1447 
1448     /*Added for the bug 6790565 - ends here*/
1449     --
1450     -- If the Fast Formula raises a user-defined error message,
1451     -- raise the error back to the user.
1452     --
1453     if l_user_message = 'Y' then
1454       -- Start of fix 3553741
1455       hr_utility.set_message(801,'HR_ELE_ENTRY_FORMULA_HINT');
1456             /*Added for the bug 6790565 - starts here*/
1457       -- hr_utility.set_message_token('FORMULA_TEXT', l_invalid_message);
1458       hr_utility.set_message_token('FORMULA_TEXT', l_invalid_message_txt);
1459       /*Added for the bug 6790565 - ends here*/
1460       hr_utility.raise_error;
1461       -- End of fix 3553741
1462     end if;
1463 
1464     hr_utility.set_location(l_proc, 63);
1465 
1466   else
1467     --
1468     -- No formula could be located so we calculate based on the
1469     -- standard hours of the assignment or business group.
1470     --
1471     p_use_formula := FALSE;
1472 
1473     hr_utility.set_location(l_proc, 65);
1474 
1475     --
1476     -- Get the default start and end times. First check the assignment, then
1477     -- the business group. If neither of these, assume 24 hours a day.
1478     --
1479     open  c_get_normal_hours (l_assignment_id);
1480     fetch c_get_normal_hours into l_normal_time_start,
1481                                   l_normal_time_end;
1482     close c_get_normal_hours;
1483 
1484     -- #2734822: verify the time format
1485 
1486     hr_dbchkfmt.is_db_format(p_value            => l_normal_time_start
1487                             ,p_formatted_output => l_normal_time_start
1488                             ,p_arg_name         => 'time_normal_start'
1489                             ,p_format           => 'TIMES');
1490 
1491 
1492     hr_dbchkfmt.is_db_format(p_value            => l_normal_time_end
1493                             ,p_formatted_output => l_normal_time_end
1494                             ,p_arg_name         => 'time_normal_finish'
1495                             ,p_format           => 'TIMES');
1496 
1497     -- end #2734822
1498 
1499     hr_utility.set_location(l_proc, 70);
1500 
1501     --
1502     -- Calculate the number of minutes in each day.
1503     --
1504     -- 3093970 starts here. comment out code introduced by 2820155.
1505     --2820155 changes start
1506     -- Start time and end time should be adjusted to fall between
1507     -- normal start time and end time.
1508   /*
1509     l_eff_time_start :=p_time_start;
1510     l_eff_time_end :=p_time_end;
1511 
1512     IF (
1513     	( (substr(p_time_start,1,2) * 60) + substr(p_time_start,4,2)) <
1514          ( (substr(l_normal_time_start,1,2) * 60) + substr(l_normal_time_start,4,2))
1515     	)    THEN
1516     l_eff_time_start := l_normal_time_start;
1517 
1518     END IF;
1519 
1520     IF (
1521        	( (substr(p_time_start,1,2) * 60) + substr(p_time_start,4,2)) >
1522              ( (substr(l_normal_time_end,1,2) * 60) + substr(l_normal_time_end,4,2))
1523         	)    THEN
1524         l_eff_time_start := l_normal_time_end;
1525 
1526     END IF;
1527 
1528 
1529     IF (
1530        	( (substr(p_time_end,1,2) * 60) + substr(p_time_end,4,2)) <
1531              ( (substr(l_normal_time_start,1,2) * 60) + substr(l_normal_time_start,4,2))
1532         	)    THEN
1533         l_eff_time_end := l_normal_time_start;
1534 
1535     END IF;
1536 
1537 
1538     IF (
1539        	( (substr(p_time_end,1,2) * 60) + substr(p_time_end,4,2)) >
1540              ( (substr(l_normal_time_end,1,2) * 60) + substr(l_normal_time_end,4,2))
1541         	)    THEN
1542         l_eff_time_end := l_normal_time_end;
1543 
1544     END IF;
1545 
1546     -- Pass effective start and end time instead of received start and end time
1547 
1548     l_normal_day_minutes := convert_to_minutes(l_normal_time_start,
1549                                             l_normal_time_end);
1550     l_first_day_minutes := convert_to_minutes(nvl(l_eff_time_start,
1551                                                l_normal_time_start),
1552                                            l_normal_time_end);
1553     l_last_day_minutes := convert_to_minutes(l_normal_time_start,
1554                                           nvl(l_eff_time_end,
1555                                               l_normal_time_end));
1556     l_same_day_minutes := convert_to_minutes(nvl(l_eff_time_start,
1557                                               l_normal_time_start),
1558                                           nvl(l_eff_time_end,
1559                                           l_normal_time_end));
1560 
1561     --2820155 changes end
1562     */
1563     --
1564     -- Calculate the number of minutes in each day.
1565     --
1566     l_normal_day_minutes := convert_to_minutes(l_normal_time_start,
1567                                             l_normal_time_end);
1568     l_first_day_minutes := convert_to_minutes(nvl(p_time_start,
1569                                                l_normal_time_start),
1570                                                l_normal_time_end);
1571     l_last_day_minutes := convert_to_minutes(l_normal_time_start,
1572                                              nvl(p_time_end,
1573                                               l_normal_time_end));
1574     --
1575     -- Bug3093970 starts here.
1576     --
1577     if l_first_day_minutes <= 0 OR l_first_day_minutes > l_normal_day_minutes
1578        OR l_last_day_minutes <= 0 OR l_last_day_minutes > l_normal_day_minutes  THEN
1579        --
1580        -- The leave timings are out off the standard timings.
1581        -- So use 24 hours rule to calculate the first day and last day minutes.
1582        --
1583        hr_utility.set_location(l_proc, 72);
1584        l_first_day_minutes := convert_to_minutes(nvl(p_time_start,
1585                                                  l_normal_time_start),
1586                                                 '24:00');
1587        l_last_day_minutes := convert_to_minutes('00:00', nvl(p_time_end,
1588                                               l_normal_time_end));
1589 
1590     end if;
1591     --
1592     -- Bug3093970 ends here.
1593     --
1594     l_same_day_minutes := convert_to_minutes(nvl(p_time_start,
1595                                               l_normal_time_start),
1596                                           nvl(p_time_end,
1597                                               l_normal_time_end));
1598     --2943479 changes start
1599     if l_normal_time_end = '23:59'
1600     then
1601        l_normal_day_minutes := l_normal_day_minutes +1;
1602        l_first_day_minutes := l_first_day_minutes +1;
1603        --3075512 changes start
1604        if (p_time_end is null or p_time_end = '') then
1605          l_last_day_minutes := l_last_day_minutes +1;
1606          l_same_day_minutes := l_same_day_minutes +1;
1607        end if;
1608        --3075512 changes end
1609     end if;
1610     --2943479 changes end
1611 
1612     hr_utility.trace('Normal Day Minutes: ' || to_char(l_normal_day_minutes));
1613     hr_utility.trace('First Day Minutes: ' || to_char(l_first_day_minutes));
1614     hr_utility.trace('Last Day Minutes: ' || to_char(l_last_day_minutes));
1615     hr_utility.trace('Same Day Minutes: ' || to_char(l_same_day_minutes));
1616 
1617     hr_utility.set_location(l_proc, 75);
1618 
1619     --
1620     -- Calculate the absence days.
1621     --
1622     l_absence_days := (p_date_end - p_date_start) + 1;
1623 
1624     hr_utility.trace('Absence Days: ' || to_char(l_absence_days));
1625 
1626     --
1627     -- Calculate the absence hours.
1628     --
1629     if l_absence_days = 1 then
1630       --
1631       -- The absence starts and ends on the same day.
1632       --
1633       l_absence_hours := l_same_day_minutes / 60;
1634 
1635     elsif l_absence_days = 2 then
1636       --
1637       -- The absence ends the day after another.
1638       --
1639       l_absence_hours := (l_first_day_minutes + l_last_day_minutes) / 60;
1640 
1641     else
1642       --
1643       -- The absence is n number of days.
1644       --
1645       l_absence_hours := (l_first_day_minutes + l_last_day_minutes +
1646                           ((l_absence_days - 2) * l_normal_day_minutes)) / 60;
1647 
1648     end if;
1649 
1650     hr_utility.set_location(l_proc, 80);
1651 
1652     --
1653     -- Check that the absence hours are not less than zero. This could
1654     -- happen if the entered start time is after the normal start time or
1655     -- the entered end time is after the normal end time.
1656     --
1657     If l_absence_hours < 0 then
1658       l_absence_hours := 0;
1659     end if;
1660 
1661     --
1662     -- Set the absence days and hours out parameters.
1663     --
1664     if l_hours_or_days = 'H' then
1665       -- Start of fix 3156665
1666       /* If the standard working hours is not defined at Assignment or
1667          Organization level, then system will take the default start time
1668          as 00:00 and end time as 23:59. Duration of this times will reach
1669          upto 23.983333' only. So if system is using default timings then
1670          rounding the calculated hours to get the default as 24 hours.
1671          Else rounding with 2 decimal places.
1672       */
1673       --
1674       --p_absence_hours := round(l_absence_hours,2);
1675       if p_time_start = '00:00' and p_time_end = '23:59' then
1676          p_absence_hours := round(l_absence_hours);
1677        else
1678          p_absence_hours := round(l_absence_hours,2);
1679       end if;
1680       -- End of fix 3156665
1681     elsif l_hours_or_days = 'D' then
1682       p_absence_days := round(l_absence_days,2);
1683 
1684     else
1685       p_absence_hours := round(l_absence_hours,2);
1686       p_absence_days := round(l_absence_days,2);
1687 
1688     end if;
1689 
1690   end if;
1691 
1692   END IF; -- Schedule based calculation not used
1693 
1694   hr_utility.set_location(' Leaving:'|| l_proc, 85);
1695 
1696 exception
1697 
1698   when wrong_parameters then
1699     --
1700     -- The inputs / outputs of the Fast Formula are incorrect
1701     -- so raise an error.
1702     --
1703     hr_utility.set_location(l_proc, 90);
1704 
1705     hr_utility.set_message(800,'HR_34964_BAD_FF_DEFINITION');
1706     hr_utility.raise_error;
1707 
1708 end calculate_absence_duration;
1709 --
1710 --  ---------------------------------------------------------------------------
1711 --  |---------------------------<  chk_person_id >----------------------------|
1712 --  ---------------------------------------------------------------------------
1713 --
1714 --  Description:
1715 --    Validates that the person exists, that they have a valid period of
1716 --    service and that they match the business group id being passed.
1717 --
1718 --  Pre-conditions:
1719 --
1720 --  In Arguments:
1721 --    p_absence_attendance_id
1722 --    p_person_id
1723 --    p_business_group_id
1724 --
1725 --  Post Success:
1726 --    If the person and their period of service are valid, processing
1727 --    continues.
1728 --
1729 --  Post Failure:
1730 --    An application error will be raised and processing is terminated.
1731 --
1732 --  Access Status:
1733 --    Internal Development Use Only.
1734 --
1735 -- {End Of Comments}
1736 -- ----------------------------------------------------------------------------
1737 --
1738 procedure chk_person_id
1739   (p_absence_attendance_id in number
1740   ,p_person_id             in number
1741   ,p_business_group_id     in number
1742   ,p_object_version_number in number
1743   ,p_date_projected_start  in date
1744   ,p_date_projected_end    in date
1745   ,p_date_start            in date
1746   ,p_date_end              in date)
1747 is
1748 
1749   --
1750   l_proc          varchar2(72)  :=  g_package||'chk_person_id';
1751   l_api_updating  boolean;
1752   --
1753 
1754 begin
1755 
1756   hr_utility.set_location('Entering:'|| l_proc, 10);
1757   --
1758   hr_api.mandatory_arg_error
1759           (p_api_name       => l_proc
1760           ,p_argument       => 'p_person_id'
1761           ,p_argument_value => p_person_id
1762           );
1763   hr_api.mandatory_arg_error
1764           (p_api_name       => l_proc
1765           ,p_argument       => 'p_business_group_id'
1766           ,p_argument_value => p_business_group_id
1767           );
1768 
1769   --
1770   -- Only proceed with validation if :
1771   -- a) The current g_old_rec is current and
1772   -- b) The date values have changed
1773   --
1774   l_api_updating := per_abs_shd.api_updating
1775          (p_absence_attendance_id  => p_absence_attendance_id
1776          ,p_object_version_number  => p_object_version_number);
1777   --
1778   if (l_api_updating
1779   and nvl(per_abs_shd.g_old_rec.date_projected_start, hr_api.g_date)
1780     = nvl(p_date_projected_start, hr_api.g_date)
1781   and nvl(per_abs_shd.g_old_rec.date_projected_end, hr_api.g_date)
1782     = nvl(p_date_projected_end, hr_api.g_date)
1783   and nvl(per_abs_shd.g_old_rec.date_start, hr_api.g_date)
1784     = nvl(p_date_start, hr_api.g_date)
1785   and nvl(per_abs_shd.g_old_rec.date_end, hr_api.g_date)
1786     = nvl(p_date_end, hr_api.g_date)) then
1787      return;
1788   end if;
1789 
1790   --
1791   -- Check that the person exists and that their period of service
1792   -- is valid for the entire absence duration.
1793   --
1794   if not per_valid_for_absence
1795       (p_person_id            => p_person_id
1796       ,p_business_group_id    => p_business_group_id
1797       ,p_date_projected_start => p_date_projected_start
1798       ,p_date_projected_end   => p_date_projected_end
1799       ,p_date_start           => p_date_start
1800       ,p_date_end             => p_date_end)
1801   then
1802 
1803       fnd_message.set_name('PER', 'PER_7715_ABS_TERM_PROJ_DATE');
1804       fnd_message.raise_error;
1805 
1806   end if;
1807 
1808   hr_utility.set_location(' Leaving:'|| l_proc, 20);
1809 
1810 end chk_person_id;
1811 --
1812 --  ---------------------------------------------------------------------------
1813 --  |-----------------<  chk_absence_attendance_type_id >---------------------|
1814 --  ---------------------------------------------------------------------------
1815 --
1816 --  Description:
1817 --    Validates that the absence_attendance_type_id exists in
1818 --    per_absence_attendance_types for the same business group and that it
1819 --    is effective for the entire absence duration.
1820 --
1821 --  Pre-conditions:
1822 --    None.
1823 --
1824 --  In Arguments:
1825 --    p_absence_attendance_id
1826 --    p_business_group_id
1827 --    p_absence_attendance_type_id
1828 --    p_object_version_number
1829 --
1830 --  Post Success:
1831 --    If absence_attendance_type_id exists and is valid,
1832 --    processing continues.
1833 --
1834 --  Post Failure:
1835 --    If absence_attendance_type_id is invalid,
1836 --    an application error is raised and processing terminates.
1837 --
1838 --  Access Status:
1839 --    Internal Development Use Only.
1840 --
1841 -- {End Of Comments}
1842 -- ----------------------------------------------------------------------------
1843 --
1844 procedure chk_absence_attendance_type_id
1845  (p_absence_attendance_id      in  number
1846  ,p_absence_attendance_type_id in  number
1847  ,p_business_group_id          in  number
1848  ,p_object_version_number      in  number
1849  ,p_date_projected_start       in  date
1850  ,p_date_projected_end         in  date
1851  ,p_date_start                 in  date
1852  ,p_date_end                   in  date)
1853   is
1854 
1855   l_exists       varchar2(1);
1856   l_proc         varchar2(72)  :=  g_package||'chk_absence_attendance_type_id';
1857   l_api_updating boolean;
1858 --
1859 
1860   cursor c_absence_within_type_dates is
1861   select null
1862   from   per_absence_attendance_types abt
1863   where  abt.absence_attendance_type_id = p_absence_attendance_type_id
1864   and    abt.business_group_id = p_business_group_id
1865   and   (p_date_projected_start is null or p_date_projected_start
1866          between abt.date_effective and nvl(abt.date_end,hr_api.g_eot))
1867   and   (p_date_projected_end is null or p_date_projected_end
1868          between abt.date_effective and nvl(abt.date_end,hr_api.g_eot))
1869   and   (p_date_start is null or p_date_start
1870          between abt.date_effective and nvl(abt.date_end,hr_api.g_eot))
1871   and   (p_date_end is null or p_date_end
1872          between abt.date_effective and nvl(abt.date_end,hr_api.g_eot));
1873 
1874 --
1875 begin
1876 
1877  hr_utility.set_location('Entering:'|| l_proc, 10);
1878   --
1879   --
1880   -- Check mandatory parameters have been set
1881   --
1882   hr_api.mandatory_arg_error
1883     (p_api_name       => l_proc
1884     ,p_argument       => 'p_absence_attendance_type_id'
1885     ,p_argument_value => p_absence_attendance_type_id
1886     );
1887 
1888   --
1889   -- Only proceed with validation if :
1890   -- a) The current g_old_rec is current and
1891   -- b) The date values have changed
1892   --
1893   l_api_updating := per_abs_shd.api_updating
1894          (p_absence_attendance_id  => p_absence_attendance_id
1895          ,p_object_version_number  => p_object_version_number);
1896   --
1897   if (l_api_updating
1898   and nvl(per_abs_shd.g_old_rec.date_projected_start, hr_api.g_date)
1899     = nvl(p_date_projected_start, hr_api.g_date)
1900   and nvl(per_abs_shd.g_old_rec.date_projected_end, hr_api.g_date)
1901     = nvl(p_date_projected_end, hr_api.g_date)
1902   and nvl(per_abs_shd.g_old_rec.date_start, hr_api.g_date)
1903     = nvl(p_date_start, hr_api.g_date)
1904   and nvl(per_abs_shd.g_old_rec.date_end, hr_api.g_date)
1905     = nvl(p_date_end, hr_api.g_date)) then
1906      return;
1907   end if;
1908 
1909   hr_utility.set_location(l_proc, 15);
1910 
1911   --
1912   -- Check that all the dates are within the effective dates of the
1913   -- absence type.
1914   --
1915   open  c_absence_within_type_dates;
1916   fetch c_absence_within_type_dates into l_exists;
1917 
1918   if c_absence_within_type_dates%notfound then
1919     fnd_message.set_name('PER', 'HR_6457_ABS_DET_DATES');
1920     fnd_message.raise_error;
1921   end if;
1922 
1923   close c_absence_within_type_dates;
1924 
1925   hr_utility.set_location(' Leaving:'|| l_proc, 20);
1926 
1927 end chk_absence_attendance_type_id;
1928 --
1929 --  ---------------------------------------------------------------------------
1930 --  |-----------------<  chk_abs_attendance_reason_id >-----------------------|
1931 --  ---------------------------------------------------------------------------
1932 --
1933 --  Description:
1934 --    Validates that an abs_attendance_reason_id exists in table
1935 --    per_abs_attendance_reasons, also valid in hr_lookups
1936 --    where lookup_type is 'ABSENCE_REASON' and enabled_flag is 'Y'
1937 --    and effective_date is between the active dates (if they are not null).
1938 --
1939 --  Pre-conditions:
1940 --    absence_attendance_type_id must be valid.
1941 --    business_group_id must be valid.
1942 --    effective_date must be valid.
1943 --
1944 --  In Arguments:
1945 --    p_absence_attendance_id
1946 --    p_absence_attendance_type_id
1947 --    p_abs_attendance_reason_id
1948 --    p_business_group_id
1949 --    p_object_version_number
1950 --    p_effective_date
1951 --
1952 --  Post Success:
1953 --    If a row does exist; processing continues.
1954 --
1955 --  Post Failure:
1956 --    If a row does not exist in per_abs_attendance_reason and hr_lookups for
1957 --    a given reason id then an error will be raised and processing terminated.
1958 --
1959 --  Access Status:
1960 --    Internal Table Handler Use Only.
1961 --
1962 -- {End Of Comments}
1963 -- ----------------------------------------------------------------------------
1964 --
1965 procedure chk_abs_attendance_reason_id
1966   (p_absence_attendance_id      in number
1967   ,p_absence_attendance_type_id in number
1968   ,p_abs_attendance_reason_id   in number
1969   ,p_business_group_id          in number
1970   ,p_object_version_number      in number
1971   ,p_effective_date             in date
1972   )
1973 is
1974   --
1975   l_exists         varchar2(1);
1976   l_proc           varchar2(72)  :=  g_package||'chk_abs_attendance_reason_id';
1977   --
1978   l_api_updating      boolean;
1979   l_business_group_id number;
1980   --
1981   cursor csr_valid_abs_reason is
1982      select null
1983      from   per_abs_attendance_reasons abr,
1984             hr_lookups hrl
1985      where  abr.business_group_id = p_business_group_id
1986      and    abr.absence_attendance_type_id = p_absence_attendance_type_id
1987      and    abr.abs_attendance_reason_id = p_abs_attendance_reason_id
1988      and    abr.name = hrl.lookup_code
1989      and    hrl.lookup_type = 'ABSENCE_REASON'
1990      and    p_effective_date between
1991                  nvl(hrl.start_date_active,hr_api.g_sot)
1992                  and nvl(hrl.end_date_active,hr_api.g_eot)
1993      and    hrl.enabled_flag = 'Y';
1994 --
1995 begin
1996 
1997   hr_utility.set_location('Entering:'|| l_proc, 10);
1998 
1999   if p_abs_attendance_reason_id is null then
2000      return;
2001   end if;
2002 
2003   --
2004   -- Only proceed with validation if :
2005   -- a) The current g_old_rec is current and
2006   -- b) The value for abs_attendance_reason_id has changed
2007   --
2008   l_api_updating := per_abs_shd.api_updating
2009          (p_absence_attendance_id  => p_absence_attendance_id
2010          ,p_object_version_number  => p_object_version_number);
2011   --
2012   if (l_api_updating and nvl(per_abs_shd.g_old_rec.abs_attendance_reason_id,
2013      hr_api.g_number) = nvl(p_abs_attendance_reason_id, hr_api.g_number)) then
2014      return;
2015   end if;
2016 
2017   open csr_valid_abs_reason;
2018   fetch csr_valid_abs_reason into l_exists;
2019   if csr_valid_abs_reason%notfound then
2020       --
2021       fnd_message.set_name('PER', 'PER_52749_ABS_REASON_INVALID');
2022       fnd_message.raise_error;
2023       --
2024   end if;
2025   close csr_valid_abs_reason;
2026 
2027   hr_utility.set_location(' Leaving:'|| l_proc, 20);
2028 
2029 end chk_abs_attendance_reason_id;
2030 --
2031 --  ---------------------------------------------------------------------------
2032 --  |-----------------<  chk_absence_period old>---------------------------------|
2033 --  ---------------------------------------------------------------------------
2034 --
2035 --  Description:
2036 --    Validates the projected dates, actual dates, times and the duration.
2037 --
2038 --  Pre-conditions:
2039 --    absence_attendance_type_id must be valid.
2040 --    business_group_id must be valid.
2041 --    effective_date must be valid.
2042 --
2043 --  In Arguments:
2044 --    p_absence_attendance_id
2045 --    p_absence_attendance_type_id
2046 --    p_business_group_id
2047 --    p_object_version_number
2048 --    p_effective_date
2049 --    p_person_id
2050 --    p_date_projected_start
2051 --    p_time_projected_start
2052 --    p_date_projected_end
2053 --    p_time_projected_end
2054 --    p_date_start
2055 --    p_time_start
2056 --    p_date_end
2057 --    p_time_end
2058 --
2059 --  In Out Arguments:
2060 --    p_absence_days
2061 --    p_absence_hours
2062 --
2063 --  Post Success:
2064 --    If validation passes, processing continues.
2065 --
2066 --  Post Failure:
2067 --    IF validation fails, the appropriate error or warning is raised.
2068 --
2069 --  Access Status:
2070 --    Internal Table Handler Use Only.
2071 --
2072 -- {End Of Comments}
2073 
2074 procedure chk_absence_period
2075   (p_absence_attendance_id      in     number
2076   ,p_absence_attendance_type_id in     number
2077   ,p_business_group_id          in     number
2078   ,p_object_version_number      in     number
2079   ,p_effective_date             in     date
2080   ,p_person_id                  in     number
2081   ,p_date_projected_start       in     date
2082   ,p_time_projected_start       in     varchar2
2083   ,p_date_projected_end         in     date
2084   ,p_time_projected_end         in     varchar2
2085   ,p_date_start                 in     date
2086   ,p_time_start                 in     varchar2
2087   ,p_date_end                   in     date
2088   ,p_time_end                   in     varchar2
2089   ,p_absence_days               in out nocopy number
2090   ,p_absence_hours              in out nocopy number
2091   ,p_dur_dys_less_warning       out nocopy    boolean
2092   ,p_dur_hrs_less_warning       out nocopy    boolean
2093   ,p_exceeds_pto_entit_warning  out nocopy    boolean
2094   ,p_exceeds_run_total_warning  out nocopy    boolean
2095   ,p_abs_overlap_warning        out nocopy    boolean
2096   ,p_abs_day_after_warning      out nocopy    boolean
2097   ,p_dur_overwritten_warning    out nocopy    boolean)
2098 is
2099 
2100    --
2101   l_proc   varchar2(72)  :=  g_package||'chk_absence_period';
2102   l_api_updating             boolean;
2103   l_exists                   varchar2(1);
2104   l_hours_or_days            varchar2(1);
2105   l_increasing_or_decreasing varchar2(1);
2106   l_absence_days             number;
2107   l_absence_hours            number;
2108   l_use_formula              boolean;
2109   l_auto_overwrite           varchar(30);
2110   l_assignment_id            number;
2111   l_payroll_id               number;
2112   l_accrual_plan_id          number;
2113   l_dummy_date               date;
2114   l_dummy_number             number;
2115   l_net_entitlement          number;
2116   l_accrual_msg              boolean;
2117   l_running_total_hours      number;
2118   l_running_total_days       number;
2119   l_year_to_date_hours       number;
2120   l_year_to_date_days        number;
2121   l_absence_overlap_flag     varchar2(1);
2122   --
2123   -- ************* Added for Bug 272978 *************
2124   -- ********* Added for AU,NZ by APAC team *********
2125   l_legislation_code varchar2(3);
2126   l_apac_dummy_number number;
2127   l_apac_entitlement number;
2128   l_apac_accrual number;
2129 
2130   cursor csr_legislation(p_business_group_id number) is
2131   select pbg.legislation_code
2132   from   per_business_groups pbg
2133   where  pbg.business_group_id = p_business_group_id;
2134 
2135   -- ********* End Bug 272978 *************
2136 
2137   -- fix for the bug 8492746 starts here
2138   l_dur_ent_hours number;
2139   l_dur_calc_hours number;
2140   -- fix for the bug 8492746 ends here
2141 
2142 
2143 begin
2144 
2145   hr_utility.set_location('Entering: old'|| l_proc, 5);
2146 
2147   --
2148    chk_absence_period
2149     (p_absence_attendance_id      => p_absence_attendance_id
2150     ,p_absence_attendance_type_id => p_absence_attendance_type_id
2151     ,p_business_group_id          => p_business_group_id
2152     ,p_object_version_number      => p_object_version_number
2153     ,p_effective_date             => p_effective_date
2154     ,p_person_id                  => p_person_id
2155     ,p_date_projected_start       => p_date_projected_start
2156     ,p_time_projected_start       => p_time_projected_start
2157     ,p_date_projected_end         => p_date_projected_end
2158     ,p_time_projected_end         => p_time_projected_end
2159     ,p_date_start                 => p_date_start
2160     ,p_time_start                 => p_time_start
2161     ,p_date_end                   => p_date_end
2162     ,p_time_end                   => p_time_end
2163     ,p_ABS_INFORMATION_CATEGORY   => NULL
2164 ,p_ABS_INFORMATION1          => NULL
2165 ,p_ABS_INFORMATION2          => NULL
2166 ,p_ABS_INFORMATION3          => NULL
2167 ,p_ABS_INFORMATION4          => NULL
2168 ,p_ABS_INFORMATION5          => NULL
2169 ,p_ABS_INFORMATION6          => NULL
2170     ,p_absence_days               => per_abs_shd.g_absence_days
2171     ,p_absence_hours              => per_abs_shd.g_absence_hours
2172     ,p_dur_dys_less_warning       => p_dur_dys_less_warning
2173     ,p_dur_hrs_less_warning       => p_dur_hrs_less_warning
2174     ,p_exceeds_pto_entit_warning  => p_exceeds_pto_entit_warning
2175     ,p_exceeds_run_total_warning  => p_exceeds_run_total_warning
2176     ,p_abs_overlap_warning        => p_abs_overlap_warning
2177     ,p_abs_day_after_warning      => p_abs_day_after_warning
2178     ,p_dur_overwritten_warning    => p_dur_overwritten_warning);
2179 
2180 
2181 
2182   hr_utility.set_location('Leaving old:'|| l_proc, 5);
2183 end;
2184 --  ---------------------------------------------------------------------------
2185 --  |-----------------<  chk_absence_period -new >---------------------------------|
2186 --  ---------------------------------------------------------------------------
2187 --
2188 --  Description:
2189 --    Validates the projected dates, actual dates, times and the duration.
2190 --
2191 --  Pre-conditions:
2192 --    absence_attendance_type_id must be valid.
2193 --    business_group_id must be valid.
2194 --    effective_date must be valid.
2195 --
2196 --  In Arguments:
2197 --    p_absence_attendance_id
2198 --    p_absence_attendance_type_id
2199 --    p_business_group_id
2200 --    p_object_version_number
2201 --    p_effective_date
2202 --    p_person_id
2203 --    p_date_projected_start
2204 --    p_time_projected_start
2205 --    p_date_projected_end
2206 --    p_time_projected_end
2207 --    p_date_start
2208 --    p_time_start
2209 --    p_date_end
2210 --    p_time_end
2211 --    p_ABS_INFORMATION_CATEGORY
2212 --    p_ABS_INFORMATION1
2213 --    p_ABS_INFORMATION2
2214 --    p_ABS_INFORMATION3
2215 --    p_ABS_INFORMATION4
2216 --    p_ABS_INFORMATION5
2217 --    p_ABS_INFORMATION6
2218 --
2219 --  In Out Arguments:
2220 --    p_absence_days
2221 --    p_absence_hours
2222 --
2223 --  Post Success:
2224 --    If validation passes, processing continues.
2225 --
2226 --  Post Failure:
2227 --    IF validation fails, the appropriate error or warning is raised.
2228 --
2229 --  Access Status:
2230 --    Internal Table Handler Use Only.
2231 --
2232 -- {End Of Comments}
2233 -- ----------------------------------------------------------------------------
2234 --
2235 procedure chk_absence_period
2236   (p_absence_attendance_id      in     number
2237   ,p_absence_attendance_type_id in     number
2238   ,p_business_group_id          in     number
2239   ,p_object_version_number      in     number
2240   ,p_effective_date             in     date
2241   ,p_person_id                  in     number
2242   ,p_date_projected_start       in     date
2243   ,p_time_projected_start       in     varchar2
2244   ,p_date_projected_end         in     date
2245   ,p_time_projected_end         in     varchar2
2246   ,p_date_start                 in     date
2247   ,p_time_start                 in     varchar2
2248   ,p_date_end                   in     date
2249   ,p_time_end                   in     varchar2
2250   ,p_ABS_INFORMATION_CATEGORY   in varchar2
2251  ,p_ABS_INFORMATION1          in varchar2
2252  ,p_ABS_INFORMATION2          in varchar2
2253  ,p_ABS_INFORMATION3          in varchar2
2254  ,p_ABS_INFORMATION4          in varchar2
2255  ,p_ABS_INFORMATION5          in varchar2
2256  ,p_ABS_INFORMATION6          in varchar2
2257   ,p_absence_days               in out nocopy number
2258   ,p_absence_hours              in out nocopy number
2259   ,p_dur_dys_less_warning       out nocopy    boolean
2260   ,p_dur_hrs_less_warning       out nocopy    boolean
2261   ,p_exceeds_pto_entit_warning  out nocopy    boolean
2262   ,p_exceeds_run_total_warning  out nocopy    boolean
2263   ,p_abs_overlap_warning        out nocopy    boolean
2264   ,p_abs_day_after_warning      out nocopy    boolean
2265   ,p_dur_overwritten_warning    out nocopy    boolean)
2266 is
2267 
2268   cursor c_get_absence_type_info is
2269   select abt.hours_or_days,
2270          abt.increasing_or_decreasing_flag,
2271          abt.absence_overlap_flag
2272   from   per_absence_attendance_types abt
2273   where  abt.absence_attendance_type_id = p_absence_attendance_type_id;
2274 
2275     -- Added for Bug11902652
2276   cursor c_abs_overlap_another is
2277   select nvl(abs.time_start,'00:00') start_time,
2278   	nvl(abs.time_end,'23:59') end_time
2279   from   per_absence_attendances abs
2280   where  abs.person_id = p_person_id
2281   and   (p_absence_attendance_id is null or
2282   	 p_absence_attendance_id <> abs.absence_attendance_id)
2283   and    abs.date_start is not null
2284   and    p_date_start is not null
2285   and   (abs.date_start between p_date_start AND nvl(p_date_end,hr_api.g_eot)
2286          OR
2287 	 p_date_start between abs.date_start and nvl(abs.date_end,hr_api.g_eot) )
2288   order by 1;
2289   -- Added for Bug11902652
2290 
2291   cursor c_abs_day_after_another is
2292   select null
2293   from   per_absence_attendances abs,
2294          per_absence_attendance_types abt
2295   where  abs.person_id = p_person_id
2296   and    abs.absence_attendance_type_id = abt.absence_attendance_type_id
2297   and   (p_absence_attendance_id is null or
2298          p_absence_attendance_id <> abs.absence_attendance_id)
2299   and    abs.date_end = p_date_end -1
2300   and    abt.absence_category = 'S';
2301 
2302   cursor c_get_accrual_plans (p_assignment_id in number) is
2303   select pap.accrual_plan_id, asg.payroll_id
2304   from   pay_element_entries_f pee,
2305          pay_element_links_f pel,
2306          pay_element_types_f pet,
2307          pay_input_values_f piv,
2308          per_all_assignments_f asg,
2309          per_absence_attendance_types abt,
2310          pay_accrual_plans pap
2311   where  abt.absence_attendance_type_id = p_absence_attendance_type_id
2312   and    abt.input_value_id = piv.input_value_id
2313   and    piv.input_value_id = pap.pto_input_value_id
2314   and    asg.assignment_id = p_assignment_id
2315   and    pee.assignment_id = asg.assignment_id
2316   and    pee.element_link_id = pel.element_link_id
2317   and    pel.element_type_id = pet.element_type_id
2318   and    pet.element_type_id = pap.accrual_plan_element_type_id
2319   and    p_effective_date between asg.effective_start_date and
2320                                   asg.effective_end_date
2321   and    p_effective_date between pee.effective_start_date and
2322                                   pee.effective_end_date
2323   and    p_effective_date between pel.effective_start_date and
2324                                   pel.effective_end_date
2325   and    p_effective_date between pet.effective_start_date and
2326                                   pet.effective_end_date
2327   and    p_effective_date between piv.effective_start_date and
2328                                   piv.effective_end_date;
2329 
2330   --
2331 
2332   -- code change for ER 7688779 starts here
2333 
2334   cursor csr_get_abs_type_name is
2335   select abtl.name from PER_ABS_ATTENDANCE_TYPES_TL abtl
2336   where abtl.absence_attendance_type_id = p_absence_attendance_type_id
2337   and abtl.language = userenv('LANG');
2338 
2339   p_abs_type_name varchar2(30);
2340 
2341   -- code change for ER 7688779 ends here
2342 
2343   l_proc   varchar2(72)  :=  g_package||'chk_absence_period';
2344   l_api_updating             boolean;
2345   l_exists                   varchar2(1);
2346   l_hours_or_days            varchar2(1);
2347   l_increasing_or_decreasing varchar2(1);
2348   l_absence_days             number;
2349   l_absence_hours            number;
2350   l_use_formula              boolean;
2351   l_auto_overwrite           varchar(30);
2352   l_assignment_id            number;
2353   l_payroll_id               number;
2354   l_accrual_plan_id          number;
2355   l_dummy_date               date;
2356   l_dummy_number             number;
2357   l_net_entitlement          number;
2358   l_accrual_msg              boolean;
2359   l_running_total_hours      number;
2360   l_running_total_days       number;
2361   l_year_to_date_hours       number;
2362   l_year_to_date_days        number;
2363   l_absence_overlap_flag     varchar2(1);
2364   --
2365   -- ************* Added for Bug 272978 *************
2366   -- ********* Added for AU,NZ by APAC team *********
2367   l_legislation_code varchar2(3);
2368   l_apac_dummy_number number;
2369   l_apac_entitlement number;
2370   l_apac_accrual number;
2371 
2372   cursor csr_legislation(p_business_group_id number) is
2373   select pbg.legislation_code
2374   from   per_business_groups pbg
2375   where  pbg.business_group_id = p_business_group_id;
2376 
2377   -- ********* End Bug 272978 *************
2378 
2379   -- fix for the bug 8492746 starts here
2380   l_dur_ent_hours number;
2381   l_dur_calc_hours number;
2382   -- fix for the bug 8492746 ends here
2383 
2384 
2385 begin
2386 
2387   hr_utility.set_location('Entering:'|| l_proc, 5);
2388 
2389   --
2390   -- Only proceed with validation if :
2391   -- a) The current g_old_rec is current and
2392   -- b) The date and time values have changed
2393   --
2394   l_api_updating := per_abs_shd.api_updating
2395          (p_absence_attendance_id  => p_absence_attendance_id
2396          ,p_object_version_number  => p_object_version_number);
2397   --
2398   if (l_api_updating
2399   and nvl(per_abs_shd.g_old_rec.date_projected_start, hr_api.g_date)
2400     = nvl(p_date_projected_start, hr_api.g_date)
2401   and nvl(per_abs_shd.g_old_rec.time_projected_start, hr_api.g_varchar2)
2402     = nvl(p_time_projected_start, hr_api.g_varchar2)
2403   and nvl(per_abs_shd.g_old_rec.date_projected_end, hr_api.g_date)
2404     = nvl(p_date_projected_end, hr_api.g_date)
2405   and nvl(per_abs_shd.g_old_rec.time_projected_end, hr_api.g_varchar2)
2406     = nvl(p_time_projected_end, hr_api.g_varchar2)
2407   and nvl(per_abs_shd.g_old_rec.date_start, hr_api.g_date)
2408     = nvl(p_date_start, hr_api.g_date)
2409   and nvl(per_abs_shd.g_old_rec.time_start, hr_api.g_varchar2)
2410     = nvl(p_time_start, hr_api.g_varchar2)
2411   and nvl(per_abs_shd.g_old_rec.date_end, hr_api.g_date)
2412     = nvl(p_date_end, hr_api.g_date)
2413   and nvl(per_abs_shd.g_old_rec.time_end, hr_api.g_varchar2)
2414     = nvl(p_time_end, hr_api.g_varchar2)
2415   and nvl(per_abs_shd.g_old_rec.absence_days, hr_api.g_number)
2416     = nvl(p_absence_days, hr_api.g_number)
2417   and nvl(per_abs_shd.g_old_rec.absence_hours, hr_api.g_number)
2418     = nvl(p_absence_hours, hr_api.g_number)) then
2419      return;
2420   end if;
2421 
2422   --
2423   -- Initialise the warning messages to false.
2424   --
2425   p_dur_dys_less_warning       := FALSE;
2426   p_dur_hrs_less_warning       := FALSE;
2427   p_exceeds_pto_entit_warning  := FALSE;
2428   p_exceeds_run_total_warning  := FALSE;
2429   p_abs_overlap_warning        := FALSE;
2430   p_abs_day_after_warning      := FALSE;
2431   p_dur_overwritten_warning    := FALSE;
2432 
2433   --
2434   -- Get the absence type values for use later.
2435   --
2436   open  c_get_absence_type_info;
2437   fetch c_get_absence_type_info into l_hours_or_days,
2438                                      l_increasing_or_decreasing,
2439                                      l_absence_overlap_flag;
2440   close c_get_absence_type_info;
2441 
2442   hr_utility.set_location(l_proc, 10);
2443 
2444   --
2445   -- Check the time formats
2446   --
2447   chk_time_format (p_time => p_time_projected_start);
2448   chk_time_format (p_time => p_time_projected_end);
2449   chk_time_format (p_time => p_time_start);
2450   chk_time_format (p_time => p_time_end);
2451 
2452   --
2453   -- Check that the start dates are entered if the end dates are entered.
2454   --
2455   if (p_date_projected_start is null and p_date_projected_end is not null)
2456   or (p_date_start is null and p_date_end is not null) then
2457     fnd_message.set_name('PER','HR_289294_ABS_SD_NOT_ENTERED');
2458     fnd_message.raise_error;
2459   end if;
2460 
2461   hr_utility.set_location(l_proc, 15);
2462 
2463   --
2464   -- Check that the end dates are after the start dates. If they are the same
2465   -- day, check that the end time is after the start time.
2466   --
2467   if p_date_projected_end < p_date_projected_start then
2468     fnd_message.set_name('PER','PAY_7617_EMP_ABS_DATE_AFTER');
2469     fnd_message.raise_error;
2470 
2471   elsif p_date_end < p_date_start then
2472     fnd_message.set_name('PER','PAY_7616_EMP_ABS_DATE_AFTER');
2473     fnd_message.raise_error;
2474 
2475   elsif p_date_projected_end = p_date_projected_start
2476   and   p_time_projected_end < p_time_projected_start then
2477     fnd_message.set_name('PER','PER_7619_EMP_ABS_END_TIME');
2478     fnd_message.raise_error;
2479 
2480   elsif p_date_end = p_date_start
2481   and   p_time_end < p_time_start then
2482     fnd_message.set_name('PER','PER_7618_EMP_ABS_END_TIME');
2483     fnd_message.raise_error;
2484 
2485   end if;
2486 
2487   hr_utility.set_location(l_proc, 20);
2488 
2489   --
2490   -- Check that times have / have not been entered depending on the
2491   -- UOM of the absence type.
2492   --
2493   if l_hours_or_days = 'D' and
2494    (p_time_projected_start is not null or
2495     p_time_projected_end is not null or
2496     p_time_start is not null or
2497     p_time_end is not null) then
2498      --
2499      -- Times should not have been entered.
2500      --
2501      fnd_message.set_name('PER','HR_289299_ABS_TIME_DISALLOWED');
2502      fnd_message.raise_error;
2503 
2504   else
2505      --
2506      -- The unit of measure is either just hours or both days and hours
2507      -- so check that the times have only been entered when the dates have.
2508      --
2509      if p_time_projected_start is not null
2510      and p_date_projected_start is null then
2511        fnd_message.set_name('PER','HR_289297_ABS_PROJ_START_DATE'); -- Fix 2647747
2512        fnd_message.raise_error;
2513 
2514      elsif p_time_projected_end is not null
2515      and p_date_projected_end is null then
2516        fnd_message.set_name('PER','PER_7621_EMP_ABS_END_TIME');
2517        fnd_message.raise_error;
2518 
2519      elsif p_time_start is not null and p_date_start is null then
2520        fnd_message.set_name('PER','PER_7143_EMP_ABS_START_TIME');
2521        fnd_message.raise_error;
2522 
2523      elsif p_time_end is not null and p_date_end is null then
2524        fnd_message.set_name('PER','PER_7620_EMP_ABS_END_TIME');
2525        fnd_message.raise_error;
2526 
2527      end if;
2528 
2529   end if;
2530 
2531   hr_utility.set_location(l_proc, 25);
2532 
2533   --
2534   -- If the end date is entered, the duration in days and / or hours
2535   -- must be entered. This can be calculated automatically in some
2536   -- circumstances.
2537   --
2538   if p_date_end is not null then
2539     --
2540     -- Calculate the absence duration.
2541     --
2542     calculate_absence_duration
2543        (p_absence_attendance_id      => p_absence_attendance_id
2544        ,p_absence_attendance_type_id => p_absence_attendance_type_id
2545        ,p_business_group_id          => p_business_group_id
2546        ,p_object_version_number      => p_object_version_number
2547        ,p_effective_date             => p_effective_date
2548        ,p_person_id                  => p_person_id
2549        ,p_date_start                 => p_date_start
2550        ,p_date_end                   => p_date_end
2551        ,p_time_start                 => p_time_start
2552        ,p_time_end                   => p_time_end
2553        ,p_ABS_INFORMATION_CATEGORY   =>  p_ABS_INFORMATION_CATEGORY
2554 	,p_ABS_INFORMATION1          => p_ABS_INFORMATION1
2555 	,p_ABS_INFORMATION2          => p_ABS_INFORMATION2
2556 	,p_ABS_INFORMATION3          => p_ABS_INFORMATION3
2557 	,p_ABS_INFORMATION4          => p_ABS_INFORMATION4
2558 	,p_ABS_INFORMATION5          => p_ABS_INFORMATION5
2559 	,p_ABS_INFORMATION6          => p_ABS_INFORMATION6
2560        ,p_absence_days               => l_absence_days
2561        ,p_absence_hours              => l_absence_hours
2562        ,p_use_formula                => l_use_formula);
2563 
2564     hr_utility.trace ('Calc dys: '||to_char(l_absence_days));
2565     hr_utility.trace ('Calc hrs: '||to_char(l_absence_hours));
2566 
2567     --
2568     -- The absence duration is only set if the results returned are
2569     -- from the Fast Formula and the durations are null or
2570     -- auto-overwrite is set to Yes.
2571     --
2572         -- Bug 14659075
2573      l_auto_overwrite :=
2574      nvl(fnd_profile.value('PER_ABSENCE_DURATION_AUTO_OVERWRITE'),'X');
2575 
2576     hr_utility.set_location(l_proc, 30);
2577 
2578     If (l_use_formula)
2579      and ((l_auto_overwrite = 'Y') or
2580           (p_absence_days is null and p_absence_hours is null)) then
2581       --
2582       -- Set the absence duration in days and hours. If the UOM is set
2583       -- to days, only days are populated, if the UOM is hours, only
2584       -- hours are populated and if no UOM is set, both days and hours
2585       -- are set.
2586       --
2587 
2588       hr_utility.trace ('Use Formula = TRUE');
2589 
2590       p_absence_days            := l_absence_days;
2591       p_absence_hours           := l_absence_hours;
2592       p_dur_overwritten_warning := TRUE;
2593 
2594     end if;
2595 
2596     hr_utility.set_location(l_proc, 35);
2597 
2598     -- Bug 14659075
2599     IF l_auto_overwrite ='N' THEN
2600 
2601       hr_utility.set_location('per_abs_shd.g_absence_days '||per_abs_shd.g_absence_days, 36);
2602       hr_utility.set_location('per_abs_shd.g_absence_hours '||per_abs_shd.g_absence_hours, 36);
2603 
2604       p_absence_days :=per_abs_shd.g_absence_days;
2605       p_absence_hours:=per_abs_shd.g_absence_hours;
2606       p_dur_overwritten_warning := TRUE;
2607 
2608     END IF;
2609     --
2610     -- Check that the duration days and / or hours have been entered if the
2611     -- element type is not recurring (recurring entries do not have an
2612     -- input value so do not require the duration days / hours).
2613     --
2614     if hr_person_absence_api.get_processing_type
2615     (p_absence_attendance_type_id) <> 'R' then
2616 
2617       if l_hours_or_days = 'D' then
2618          --
2619          -- The UOM is Days so the days duration should be entered, but not
2620          -- the hours duration.
2621          --
2622          if p_absence_days is null then
2623            fnd_message.set_name('PER','HR_51059_ABS_DUR_NOT_ENTERED');
2624            fnd_message.raise_error;
2625 
2626          elsif p_absence_hours is not null then
2627            fnd_message.set_name('PER','HR_289298_ABS_HRS_DISALLOWED');
2628            fnd_message.raise_error;
2629 
2630          end if;
2631 
2632       elsif l_hours_or_days = 'H' then
2633          --
2634          -- The UOM is Hours so the hours duration should be entered, but not
2635          -- the days duration.
2636          --
2637         if p_absence_hours is null then
2638           fnd_message.set_name('PER','HR_51059_ABS_DUR_NOT_ENTERED');
2639           fnd_message.raise_error;
2640 
2641         elsif p_absence_days is not null then
2642           fnd_message.set_name('PER','HR_289300_ABS_DYS_DISALLOWED');
2643           fnd_message.raise_error;
2644 
2645         end if;
2646 
2647       else
2648          --
2649          -- No UOM is set so either days or hours can be entered (or both).
2650          --
2651         if p_absence_hours is null and p_absence_days is null then
2652           fnd_message.set_name('PER','HR_51059_ABS_DUR_NOT_ENTERED');
2653           fnd_message.raise_error;
2654         end if;
2655 
2656       end if;
2657 
2658     end if;
2659 
2660   end if;
2661 
2662   hr_utility.set_location(l_proc, 40);
2663 
2664   -- fix for the bug 8492746 starts here
2665 
2666   l_dur_ent_hours := nvl(p_absence_hours,l_absence_hours);
2667 
2668   l_dur_calc_hours := (fffunc.days_between(p_date_end,p_date_start)+1)*24;
2669 
2670   if (l_dur_ent_hours > l_dur_calc_hours)
2671   then
2672 
2673   fnd_message.set_name('PER','PER_449852_ABS_HOUR_DUR');
2674   hr_utility.set_message_token('START', p_date_start);
2675   hr_utility.set_message_token('END', p_date_end);
2676   fnd_message.raise_error;
2677 
2678   end if;
2679 
2680   -- fix for the bug 8492746 ends here
2681 
2682   --
2683   -- Check that the dates and / or times have been entered if the duration
2684   -- has been entered.
2685   --
2686   if p_absence_days is not null
2687   and (p_date_start is null or p_date_end is null) then
2688     fnd_message.set_name('PER','PER_7714_ABS_CALC_DURATION');
2689     fnd_message.raise_error;
2690 /*
2691   elsif p_absence_hours is not null
2692   and (p_time_start is null or p_time_end is null) then
2693     fnd_message.set_name('PER','PER_7145_EMP_ABS_UNPAID_HOURS');
2694     fnd_message.raise_error;
2695 */
2696   end if;
2697 
2698   hr_utility.set_location(l_proc, 45);
2699 
2700   --
2701   -- Check if the absence duration in days differs from
2702   -- the amount of time absent.
2703   --
2704   if (p_absence_days <> l_absence_days) then
2705     --
2706     -- Set the warning message.
2707     --
2708     p_dur_dys_less_warning := TRUE;
2709 
2710 
2711  -- Commented as a fix for the bug 4606467
2712  /*
2713   elsif p_absence_days > l_absence_days then
2714     --
2715     -- Raise the error message.  The duration cannot be greater than
2716     -- the system calculated duration.
2717     --
2718     fnd_message.set_name('PER','PER_7622_EMP_ABS_LONG_DURATION');
2719     fnd_message.raise_error;*/
2720 
2721   end if;
2722 
2723   --
2724   -- Check if the absence duration in hours differs from
2725   -- the amount of time absent.
2726   --
2727   if (p_absence_hours <> l_absence_hours) then
2728     --
2729     -- Set the warning message.
2730     --
2731     p_dur_hrs_less_warning := TRUE;
2732 
2733 
2734 -- Commented as a fix for the bug 4606467
2735 /*  elsif p_absence_hours > l_absence_hours then
2736     --
2737     -- Raise the error message.  The duration cannot be greater than
2738     -- the system calculated duration.
2739     --
2740     fnd_message.set_name('PER','PER_7623_EMP_ABS_LONG_DURATION');
2741     fnd_message.raise_error;*/
2742 
2743   end if;
2744 
2745   hr_utility.set_location(l_proc, 50);
2746 
2747   --
2748   -- Check if this absence exceeds the net entitlement on any of the
2749   -- employee's accrual plans.  First the assignment id and plan id(s)
2750   -- are required.
2751   --
2752   if p_absence_days is not null or p_absence_hours is not null then
2753 
2754     l_assignment_id := hr_person_absence_api.get_primary_assignment
2755        (p_person_id      => p_person_id
2756        ,p_effective_date => p_effective_date);
2757 
2758     declare
2759 
2760       l_message_text fnd_new_messages.message_text%TYPE;
2761 
2762     begin
2763 
2764       open c_get_accrual_plans (l_assignment_id);
2765       loop
2766 
2767         fetch c_get_accrual_plans into l_accrual_plan_id, l_payroll_id;
2768         exit when c_get_accrual_plans%notfound;
2769 
2770         --
2771         -- Get the net entitlement of each plan.
2772         --
2773 
2774         -- ****************** Added for Bug 2729784 ***************
2775         -- ************** Added for AU,NZ by APAC team ************
2776 
2777         open csr_legislation(p_business_group_id);
2778         fetch csr_legislation into l_legislation_code;
2779         if csr_legislation%notfound
2780         then
2781           close csr_legislation;
2782           --
2783           -- The primary key is invalid therefore we must error
2784           --
2785           fnd_message.set_name('PAY','HR_7220_INVALID_PRIMARY_KEY');
2786           fnd_message.raise_error;
2787         end if;
2788         close csr_legislation;
2789 
2790         if l_legislation_code = 'AU'
2791         then
2792           hr_utility.set_location('APAC code - '||l_proc,52);
2793           l_net_entitlement := hr_au_holidays.get_net_accrual
2794                                  (p_assignment_id        => l_assignment_id
2795                                  ,p_payroll_id           => l_payroll_id
2796                                  ,p_business_group_id    => p_business_group_id
2797                                  ,p_plan_id              => l_accrual_plan_id
2798                                  ,p_calculation_date     => nvl(p_date_start, p_effective_date)
2799                                  );
2800         elsif l_legislation_code = 'NZ'
2801         then
2802           hr_utility.set_location(l_proc,53);
2803           l_net_entitlement := hr_nz_holidays.get_net_accrual
2804                                  (p_assignment_id        => l_assignment_id
2805                                  ,p_payroll_id           => l_payroll_id
2806                                  ,p_business_group_id    => p_business_group_id
2807                                  ,p_plan_id              => l_accrual_plan_id
2808                                  ,p_calculation_date     => nvl(p_date_start, p_effective_date)
2809                                  );
2810 
2811         else
2812           hr_utility.set_location('APAC code - '||l_proc,54);
2813           -- ********** existing code wrapped by if statement from bug 2729784 *************
2814           per_accrual_calc_functions.get_net_accrual
2815            (p_assignment_id         => l_assignment_id
2816            ,p_plan_id               => l_accrual_plan_id
2817            ,p_payroll_id            => l_payroll_id
2818            ,p_business_group_id     => p_business_group_id
2819            ,p_calculation_date      => nvl(p_date_start, p_effective_date)
2820            ,p_start_date            => l_dummy_date
2821            ,p_end_date              => l_dummy_date
2822            ,p_accrual_end_date      => l_dummy_date
2823            ,p_accrual               => l_dummy_number
2824            ,p_net_entitlement       => l_net_entitlement);
2825           -- ********** end existing code ***************
2826 
2827         end if;
2828         hr_utility.trace('Ent = '||to_char(l_net_entitlement));
2829 
2830         -- ****************** End Bug 2729784 *********************
2831 
2832 
2833 
2834         --
2835         -- The duration value in g_old_rec is first added to the net
2836         -- entitlement. This prevents absence records that are being
2837         -- updated from being double counted (get_net_accrual has already
2838         -- included the absence in the calculation of the net entitlement).
2839         --
2840         if l_hours_or_days = 'H' then
2841           l_net_entitlement := l_net_entitlement
2842                                + nvl(per_abs_shd.g_old_rec.absence_hours, 0)
2843                                - p_absence_hours;
2844 
2845         elsif l_hours_or_days = 'D' then
2846           l_net_entitlement := l_net_entitlement
2847                                + nvl(per_abs_shd.g_old_rec.absence_days, 0)
2848                                - p_absence_days;
2849         end if;
2850 
2851         --
2852         -- Check if the new net entitlement is less than zero.
2853         --
2854         if l_net_entitlement < 0 then
2855           --
2856           -- Instead of raising the message here, the boolean value is set.
2857           -- This prevents the message appearing multiple times.
2858           --
2859           l_accrual_msg := TRUE;
2860         end if;
2861 
2862       end loop;
2863       close c_get_accrual_plans;
2864 
2865     exception
2866 
2867       when others then
2868 
2869         l_message_text := fnd_message.get;
2870         hr_utility.trace('Unable to execute the PTO formula.  '||l_message_text);
2871 
2872     end;
2873 
2874     if (l_accrual_msg) then
2875     -- code change for 7688779  starts here
2876 	if (nvl(fnd_profile.value('HR_ALLOW_NEG_ABS_BAL'),'Y') = 'N') then
2877 
2878 		open csr_get_abs_type_name;
2879 		fetch csr_get_abs_type_name into p_abs_type_name;
2880 		close csr_get_abs_type_name;
2881 
2882 		fnd_message.set_name('PER','PER_449875_ABS_NEGBAL');
2883 		fnd_message.set_token('ABSTYPE',p_abs_type_name);
2884 		fnd_message.raise_error;
2885 	else
2886 
2887 		p_exceeds_pto_entit_warning := TRUE;
2888 	end if;
2889        -- code change for 7688779  ends here
2890     end if;
2891 
2892   end if;
2893 
2894   hr_utility.set_location(l_proc, 55);
2895 
2896   --
2897   -- Get the running totals and check that the values do not
2898   -- decrease to less than zero.
2899   --
2900   get_running_totals
2901      (p_person_id                  => p_person_id
2902      ,p_absence_attendance_type_id => p_absence_attendance_type_id
2903      ,p_effective_date             => p_effective_date
2904      ,p_running_total_hours        => l_running_total_hours
2905      ,p_running_total_days         => l_running_total_days
2906      ,p_year_to_date_hours         => l_year_to_date_hours
2907      ,p_year_to_date_days          => l_year_to_date_days);
2908 
2909   --
2910   -- Here the value of g_old_rec is subtracted first. This prevents
2911   -- records already included in l_running_total_hours / days
2912   -- being double counted (this would occur during update only).
2913   --
2914   if l_increasing_or_decreasing = 'D'
2915   and (l_running_total_hours +
2916        nvl(per_abs_shd.g_old_rec.absence_hours, 0) - p_absence_hours < 0
2917    or  l_running_total_days +
2918        nvl(per_abs_shd.g_old_rec.absence_days, 0) - p_absence_days < 0)
2919   then
2920 
2921     -- code change for 7688779  starts here
2922 	if (nvl(fnd_profile.value('HR_ALLOW_NEG_ABS_BAL'),'Y') = 'N') then
2923 
2924 		open csr_get_abs_type_name;
2925 		fetch csr_get_abs_type_name into p_abs_type_name;
2926 		close csr_get_abs_type_name;
2927 
2928 		fnd_message.set_name('PER','PER_449875_ABS_NEGBAL');
2929 		fnd_message.set_token('ABSTYPE',p_abs_type_name);
2930 		fnd_message.raise_error;
2931 	else
2932 
2933 		p_exceeds_run_total_warning := TRUE;
2934 	end if;
2935        -- code change for 7688779  ends here
2936 
2937     hr_utility.set_location(l_proc, 57);
2938 
2939   end if;
2940 
2941   hr_utility.set_location(l_proc, 60);
2942 
2943   --
2944   -- Check if this absence overlaps another absence for the same person.
2945   --
2946   -- Fix for the Bug11902652
2947 
2948   for i in c_abs_overlap_another
2949   loop
2950 	  hr_utility.trace('check_abs_overlap i.end_time:'||i.end_time);
2951 
2952 	  if	nvl(p_time_start,'00:00') <= i.end_time
2953 		OR	i.start_time <= p_time_start
2954 	  then
2955 
2956 		if nvl(l_absence_overlap_flag,'N') = 'N' then  -- bug 8269612
2957 
2958 			p_abs_overlap_warning := TRUE;
2959 			exit;
2960 
2961 		end if;
2962 
2963 	  end if;
2964 
2965   end loop;
2966   -- Fix for the Bug11902652
2967 
2968   hr_utility.set_location(l_proc, 65);
2969 
2970   --
2971   -- Check if this is a sickness absence that starts the day after another
2972   -- sickness absence for this person.
2973   --
2974   open  c_abs_day_after_another;
2975   fetch c_abs_day_after_another into l_exists;
2976 
2977   if c_abs_day_after_another%found then
2978     --
2979     -- Set the warning message
2980     --
2981     p_abs_day_after_warning := TRUE;
2982 
2983   end if;
2984 
2985   --
2986   hr_utility.set_location('Leaving:'|| l_proc, 70);
2987 
2988 end chk_absence_period;
2989 --
2990 --  ---------------------------------------------------------------------------
2991 --  |----------------------<  chk_replacement_person_id >---------------------|
2992 --  ---------------------------------------------------------------------------
2993 --
2994 --  Description:
2995 --    Validates that the person exists, that they have a valid period of
2996 --    service and that they match the business group id being passed.
2997 --
2998 --  Pre-conditions:
2999 --
3000 --  In Arguments:
3001 --    p_absence_attendance_id
3002 --    p_replacement_person_id
3003 --    p_business_group_id
3004 --
3005 --  Post Success:
3006 --    If the person and their period of service are valid, processing
3007 --    continues.
3008 --
3009 --  Post Failure:
3010 --    An application error will be raised and processing is terminated.
3011 --
3012 --  Access Status:
3013 --    Internal Development Use Only.
3014 --
3015 -- {End Of Comments}
3016 -- ----------------------------------------------------------------------------
3017 --
3018 procedure chk_replacement_person_id
3019   (p_absence_attendance_id in number
3020   ,p_replacement_person_id in number
3021   ,p_business_group_id     in number
3022   ,p_object_version_number in number
3023   ,p_date_projected_start  in date
3024   ,p_date_projected_end    in date
3025   ,p_date_start            in date
3026   ,p_date_end              in date)
3027 is
3028 
3029   --
3030   l_proc          varchar2(72)  :=  g_package||'chk_replacement_person_id';
3031   l_api_updating  boolean;
3032   --
3033 
3034 begin
3035 
3036   hr_utility.set_location('Entering:'|| l_proc, 10);
3037   --
3038   hr_api.mandatory_arg_error
3039           (p_api_name       => l_proc
3040           ,p_argument       => 'p_business_group_id'
3041           ,p_argument_value => p_business_group_id
3042           );
3043 
3044   --
3045   -- Only proceed with validation if :
3046   -- a) The current g_old_rec is current and
3047   -- b) The date values have changed
3048   --
3049   l_api_updating := per_abs_shd.api_updating
3050          (p_absence_attendance_id  => p_absence_attendance_id
3051          ,p_object_version_number  => p_object_version_number);
3052   --
3053   if (l_api_updating
3054   and nvl(per_abs_shd.g_old_rec.replacement_person_id, hr_api.g_number)
3055     = nvl(p_replacement_person_id, hr_api.g_number)
3056   and nvl(per_abs_shd.g_old_rec.date_projected_start, hr_api.g_date)
3057     = nvl(p_date_projected_start, hr_api.g_date)
3058   and nvl(per_abs_shd.g_old_rec.date_projected_end, hr_api.g_date)
3059     = nvl(p_date_projected_end, hr_api.g_date)
3060   and nvl(per_abs_shd.g_old_rec.date_start, hr_api.g_date)
3061     = nvl(p_date_start, hr_api.g_date)
3062   and nvl(per_abs_shd.g_old_rec.date_end, hr_api.g_date)
3063     = nvl(p_date_end, hr_api.g_date)) then
3064      return;
3065   end if;
3066 
3067   if p_replacement_person_id is not null then
3068     --
3069     -- Check that the replacement exists and that their period of service
3070     -- is valid for the entire absence duration.
3071     --
3072     if not per_valid_for_absence
3073         (p_person_id            => p_replacement_person_id
3074         ,p_business_group_id    => p_business_group_id
3075         ,p_date_projected_start => p_date_projected_start
3076         ,p_date_projected_end   => p_date_projected_end
3077         ,p_date_start           => p_date_start
3078         ,p_date_end             => p_date_end)
3079     then
3080 
3081       fnd_message.set_name('PER', 'HR_7553_ASS_REP_INVALID');
3082       fnd_message.raise_error;
3083 
3084     end if;
3085 
3086   end if;
3087 
3088   hr_utility.set_location(' Leaving:'|| l_proc, 20);
3089 
3090 end chk_replacement_person_id;
3091 --
3092 --
3093 --  ---------------------------------------------------------------------------
3094 --  |----------------------<  chk_authorising_person_id >---------------------|
3095 --  ---------------------------------------------------------------------------
3096 --
3097 --  Description:
3098 --    Validates that the person exists, that they have a valid period of
3099 --    service and that they match the business group id being passed.
3100 --
3101 --  Pre-conditions:
3102 --
3103 --  In Arguments:
3104 --    p_absence_attendance_id
3105 --    p_replacement_person_id
3106 --    p_business_group_id
3107 --
3108 --  Post Success:
3109 --    If the person and their period of service are valid, processing
3110 --    continues.
3111 --
3112 --  Post Failure:
3113 --    An application error will be raised and processing is terminated.
3114 --
3115 --  Access Status:
3116 --    Internal Development Use Only.
3117 --
3118 -- {End Of Comments}
3119 -- ----------------------------------------------------------------------------
3120 --
3121 procedure chk_authorising_person_id
3122   (p_absence_attendance_id in number
3123   ,p_authorising_person_id in number
3124   ,p_business_group_id     in number
3125   ,p_object_version_number in number
3126   ,p_date_projected_start  in date
3127   ,p_date_projected_end    in date
3128   ,p_date_start            in date
3129   ,p_date_end              in date)
3130 is
3131 
3132   --
3133   l_proc          varchar2(72)  :=  g_package||'chk_authorising_person_id';
3134   l_api_updating  boolean;
3135   --
3136 
3137 begin
3138 
3139   hr_utility.set_location('Entering:'|| l_proc, 10);
3140   --
3141   hr_api.mandatory_arg_error
3142           (p_api_name       => l_proc
3143           ,p_argument       => 'p_business_group_id'
3144           ,p_argument_value => p_business_group_id
3145           );
3146 
3147   --
3148   -- Only proceed with validation if :
3149   -- a) The current g_old_rec is current and
3150   -- b) The date values have changed
3151   --
3152   l_api_updating := per_abs_shd.api_updating
3153          (p_absence_attendance_id  => p_absence_attendance_id
3154          ,p_object_version_number  => p_object_version_number);
3155   --
3156   if (l_api_updating
3157   and nvl(per_abs_shd.g_old_rec.authorising_person_id, hr_api.g_number)
3158     = nvl(p_authorising_person_id, hr_api.g_number)
3159   and nvl(per_abs_shd.g_old_rec.date_projected_start, hr_api.g_date)
3160     = nvl(p_date_projected_start, hr_api.g_date)
3161   and nvl(per_abs_shd.g_old_rec.date_projected_end, hr_api.g_date)
3162     = nvl(p_date_projected_end, hr_api.g_date)
3163   and nvl(per_abs_shd.g_old_rec.date_start, hr_api.g_date)
3164     = nvl(p_date_start, hr_api.g_date)
3165   and nvl(per_abs_shd.g_old_rec.date_end, hr_api.g_date)
3166     = nvl(p_date_end, hr_api.g_date)) then
3167      return;
3168   end if;
3169 
3170   if p_authorising_person_id is not null then
3171     --
3172     -- Check that the authorisor exists and that their period of service
3173     -- is valid for the entire absence duration.
3174     --
3175     if not per_valid_for_absence
3176         (p_person_id            => p_authorising_person_id
3177         ,p_business_group_id    => p_business_group_id
3178         ,p_date_projected_start => p_date_projected_start
3179         ,p_date_projected_end   => p_date_projected_end
3180         ,p_date_start           => p_date_start
3181         ,p_date_end             => p_date_end)
3182     then
3183 
3184         fnd_message.set_name('PER', 'HR_7552_ASS_AUTH_INVALID');
3185         fnd_message.raise_error;
3186 
3187     end if;
3188 
3189   end if;
3190 
3191   hr_utility.set_location(' Leaving:'|| l_proc, 20);
3192 
3193 end chk_authorising_person_id;
3194 --
3195 --  ---------------------------------------------------------------------------
3196 --  |----------------------< set_security_group_id >--------------------------|
3197 --  ---------------------------------------------------------------------------
3198 --
3199 Procedure set_security_group_id
3200   (p_absence_attendance_id                in number
3201   ) is
3202   --
3203   -- Declare cursor
3204   --
3205   cursor csr_sec_grp is
3206     select pbg.security_group_id
3207       from per_business_groups pbg
3208          , per_absence_attendances abs
3209      where abs.absence_attendance_id = p_absence_attendance_id
3210        and pbg.business_group_id = abs.business_group_id;
3211   --
3212   -- Declare local variables
3213   --
3214   l_security_group_id number;
3215   l_proc              varchar2(72)  :=  g_package||'set_security_group_id';
3216   --
3217 begin
3218   --
3219   hr_utility.set_location('Entering:'|| l_proc, 10);
3220   --
3221   -- Ensure that all the mandatory parameter are not null
3222   --
3223   hr_api.mandatory_arg_error
3224     (p_api_name           => l_proc
3225     ,p_argument           => 'absence_attendance_id'
3226     ,p_argument_value     => p_absence_attendance_id
3227     );
3228   --
3229   open csr_sec_grp;
3230   fetch csr_sec_grp into l_security_group_id;
3231   --
3232   if csr_sec_grp%notfound then
3233      --
3234      close csr_sec_grp;
3235      --
3236      -- The primary key is invalid therefore we must error
3237      --
3238      fnd_message.set_name('PAY','HR_7220_INVALID_PRIMARY_KEY');
3239      fnd_message.raise_error;
3240      --
3241   end if;
3242   close csr_sec_grp;
3243   --
3244   -- Set the security_group_id in CLIENT_INFO
3245   --
3246   hr_api.set_security_group_id
3247     (p_security_group_id => l_security_group_id
3248     );
3249   --
3250   hr_utility.set_location(' Leaving:'|| l_proc, 20);
3251   --
3252 end set_security_group_id;
3253 --
3254 --  ---------------------------------------------------------------------------
3255 --  |---------------------< return_legislation_code >-------------------------|
3256 --  ---------------------------------------------------------------------------
3257 --
3258 Function return_legislation_code
3259   (p_absence_attendance_id                in     number
3260   )
3261   Return Varchar2 Is
3262   --
3263   -- Declare cursor
3264   --
3265   cursor csr_leg_code is
3266     select pbg.legislation_code
3267       from per_business_groups pbg
3268          , per_absence_attendances abs
3269      where abs.absence_attendance_id = p_absence_attendance_id
3270        and pbg.business_group_id = abs.business_group_id;
3271   --
3272   -- Declare local variables
3273   --
3274   l_legislation_code  varchar2(150);
3275   l_proc              varchar2(72)  :=  g_package||'return_legislation_code';
3276   --
3277 Begin
3278   --
3279   hr_utility.set_location('Entering:'|| l_proc, 10);
3280   --
3281   -- Ensure that all the mandatory parameter are not null
3282   --
3283   hr_api.mandatory_arg_error
3284     (p_api_name           => l_proc
3285     ,p_argument           => 'absence_attendance_id'
3286     ,p_argument_value     => p_absence_attendance_id
3287     );
3288   --
3289   if ( nvl(per_abs_bus.g_absence_attendance_id, hr_api.g_number)
3290        = p_absence_attendance_id) then
3291     --
3292     -- The legislation code has already been found with a previous
3293     -- call to this function. Just return the value in the global
3294     -- variable.
3295     --
3296     l_legislation_code := per_abs_bus.g_legislation_code;
3297     hr_utility.set_location(l_proc, 20);
3298   else
3299     --
3300     -- The ID is different to the last call to this function
3301     -- or this is the first call to this function.
3302     --
3303     open csr_leg_code;
3304     fetch csr_leg_code into l_legislation_code;
3305     --
3306     if csr_leg_code%notfound then
3307       --
3308       -- The primary key is invalid therefore we must error
3309       --
3310       close csr_leg_code;
3311       fnd_message.set_name('PAY','HR_7220_INVALID_PRIMARY_KEY');
3312       fnd_message.raise_error;
3313     end if;
3314     hr_utility.set_location(l_proc,30);
3315     --
3316     -- Set the global variables so the values are
3317     -- available for the next call to this function.
3318     --
3319     close csr_leg_code;
3320     per_abs_bus.g_absence_attendance_id:= p_absence_attendance_id;
3321     per_abs_bus.g_legislation_code  := l_legislation_code;
3322   end if;
3323   hr_utility.set_location(' Leaving:'|| l_proc, 40);
3324   return l_legislation_code;
3325 end return_legislation_code;
3326 --
3327 -- ----------------------------------------------------------------------------
3328 -- |-----------------------------< chk_ddf >----------------------------------|
3329 -- ----------------------------------------------------------------------------
3330 --
3331 -- Description:
3332 --   Validates all the Developer Descriptive Flexfield values.
3333 --
3334 -- Prerequisites:
3335 --   All other columns have been validated.  Must be called as the
3336 --   last step from insert_validate and update_validate.
3337 --
3338 -- In Arguments:
3339 --   p_rec
3340 --
3341 -- Post Success:
3342 --   If the Developer Descriptive Flexfield structure column and data values
3343 --   are all valid this procedure will end normally and processing will
3344 --   continue.
3345 --
3346 -- Post Failure:
3347 --   If the Developer Descriptive Flexfield structure column value or any of
3348 --   the data values are invalid then an application error is raised as
3349 --   a PL/SQL exception.
3350 --
3351 -- Access Status:
3352 --   Internal Row Handler Use Only.
3353 --
3354 -- ----------------------------------------------------------------------------
3355 --
3356 procedure chk_ddf
3357   (p_rec in per_abs_shd.g_rec_type
3358   ) is
3359 --
3360   l_proc   varchar2(72) := g_package || 'chk_ddf';
3361 --
3362 begin
3363   hr_utility.set_location('Entering:'||l_proc,10);
3364   --
3365   if ((p_rec.absence_attendance_id is not null)  and (
3366     nvl(per_abs_shd.g_old_rec.abs_information_category, hr_api.g_varchar2) <>
3367     nvl(p_rec.abs_information_category, hr_api.g_varchar2)  or
3368     nvl(per_abs_shd.g_old_rec.abs_information1, hr_api.g_varchar2) <>
3369     nvl(p_rec.abs_information1, hr_api.g_varchar2)  or
3370     nvl(per_abs_shd.g_old_rec.abs_information2, hr_api.g_varchar2) <>
3371     nvl(p_rec.abs_information2, hr_api.g_varchar2)  or
3372     nvl(per_abs_shd.g_old_rec.abs_information3, hr_api.g_varchar2) <>
3373     nvl(p_rec.abs_information3, hr_api.g_varchar2)  or
3374     nvl(per_abs_shd.g_old_rec.abs_information4, hr_api.g_varchar2) <>
3375     nvl(p_rec.abs_information4, hr_api.g_varchar2)  or
3376     nvl(per_abs_shd.g_old_rec.abs_information5, hr_api.g_varchar2) <>
3377     nvl(p_rec.abs_information5, hr_api.g_varchar2)  or
3378     nvl(per_abs_shd.g_old_rec.abs_information6, hr_api.g_varchar2) <>
3379     nvl(p_rec.abs_information6, hr_api.g_varchar2)  or
3380     nvl(per_abs_shd.g_old_rec.abs_information7, hr_api.g_varchar2) <>
3381     nvl(p_rec.abs_information7, hr_api.g_varchar2)  or
3382     nvl(per_abs_shd.g_old_rec.abs_information8, hr_api.g_varchar2) <>
3383     nvl(p_rec.abs_information8, hr_api.g_varchar2)  or
3384     nvl(per_abs_shd.g_old_rec.abs_information9, hr_api.g_varchar2) <>
3385     nvl(p_rec.abs_information9, hr_api.g_varchar2)  or
3386     nvl(per_abs_shd.g_old_rec.abs_information10, hr_api.g_varchar2) <>
3387     nvl(p_rec.abs_information10, hr_api.g_varchar2)  or
3388     nvl(per_abs_shd.g_old_rec.abs_information11, hr_api.g_varchar2) <>
3389     nvl(p_rec.abs_information11, hr_api.g_varchar2)  or
3390     nvl(per_abs_shd.g_old_rec.abs_information12, hr_api.g_varchar2) <>
3391     nvl(p_rec.abs_information12, hr_api.g_varchar2)  or
3392     nvl(per_abs_shd.g_old_rec.abs_information13, hr_api.g_varchar2) <>
3393     nvl(p_rec.abs_information13, hr_api.g_varchar2)  or
3394     nvl(per_abs_shd.g_old_rec.abs_information14, hr_api.g_varchar2) <>
3395     nvl(p_rec.abs_information14, hr_api.g_varchar2)  or
3396     nvl(per_abs_shd.g_old_rec.abs_information15, hr_api.g_varchar2) <>
3397     nvl(p_rec.abs_information15, hr_api.g_varchar2)  or
3398     nvl(per_abs_shd.g_old_rec.abs_information16, hr_api.g_varchar2) <>
3399     nvl(p_rec.abs_information16, hr_api.g_varchar2)  or
3400     nvl(per_abs_shd.g_old_rec.abs_information17, hr_api.g_varchar2) <>
3401     nvl(p_rec.abs_information17, hr_api.g_varchar2)  or
3402     nvl(per_abs_shd.g_old_rec.abs_information18, hr_api.g_varchar2) <>
3403     nvl(p_rec.abs_information18, hr_api.g_varchar2)  or
3404     nvl(per_abs_shd.g_old_rec.abs_information19, hr_api.g_varchar2) <>
3405     nvl(p_rec.abs_information19, hr_api.g_varchar2)  or
3406     nvl(per_abs_shd.g_old_rec.abs_information20, hr_api.g_varchar2) <>
3407     nvl(p_rec.abs_information20, hr_api.g_varchar2)  or
3408     nvl(per_abs_shd.g_old_rec.abs_information21, hr_api.g_varchar2) <>
3409     nvl(p_rec.abs_information21, hr_api.g_varchar2)  or
3410     nvl(per_abs_shd.g_old_rec.abs_information22, hr_api.g_varchar2) <>
3411     nvl(p_rec.abs_information22, hr_api.g_varchar2)  or
3412     nvl(per_abs_shd.g_old_rec.abs_information23, hr_api.g_varchar2) <>
3413     nvl(p_rec.abs_information23, hr_api.g_varchar2)  or
3414     nvl(per_abs_shd.g_old_rec.abs_information24, hr_api.g_varchar2) <>
3415     nvl(p_rec.abs_information24, hr_api.g_varchar2)  or
3416     nvl(per_abs_shd.g_old_rec.abs_information25, hr_api.g_varchar2) <>
3417     nvl(p_rec.abs_information25, hr_api.g_varchar2)  or
3418     nvl(per_abs_shd.g_old_rec.abs_information26, hr_api.g_varchar2) <>
3419     nvl(p_rec.abs_information26, hr_api.g_varchar2)  or
3420     nvl(per_abs_shd.g_old_rec.abs_information27, hr_api.g_varchar2) <>
3421     nvl(p_rec.abs_information27, hr_api.g_varchar2)  or
3422     nvl(per_abs_shd.g_old_rec.abs_information28, hr_api.g_varchar2) <>
3423     nvl(p_rec.abs_information28, hr_api.g_varchar2)  or
3424     nvl(per_abs_shd.g_old_rec.abs_information29, hr_api.g_varchar2) <>
3425     nvl(p_rec.abs_information29, hr_api.g_varchar2)  or
3426     nvl(per_abs_shd.g_old_rec.abs_information30, hr_api.g_varchar2) <>
3427     nvl(p_rec.abs_information30, hr_api.g_varchar2) ))
3428     or (p_rec.absence_attendance_id is null)  then
3429     --
3430     -- Only execute the validation if absolutely necessary:
3431     -- a) During update, the structure column value or any
3432     --    of the attribute values have actually changed.
3433     -- b) During insert.
3434     --
3435     hr_dflex_utility.ins_or_upd_descflex_attribs
3436       (p_appl_short_name                 => 'PER'
3437       ,p_descflex_name                   => 'PER_ABS_DEVELOPER_DF'
3438       ,p_attribute_category              => p_rec.abs_information_category
3439       ,p_attribute1_name                 => 'ABS_INFORMATION1'
3440       ,p_attribute1_value                => p_rec.abs_information1
3441       ,p_attribute2_name                 => 'ABS_INFORMATION2'
3442       ,p_attribute2_value                => p_rec.abs_information2
3443       ,p_attribute3_name                 => 'ABS_INFORMATION3'
3444       ,p_attribute3_value                => p_rec.abs_information3
3445       ,p_attribute4_name                 => 'ABS_INFORMATION4'
3446       ,p_attribute4_value                => p_rec.abs_information4
3447       ,p_attribute5_name                 => 'ABS_INFORMATION5'
3448       ,p_attribute5_value                => p_rec.abs_information5
3449       ,p_attribute6_name                 => 'ABS_INFORMATION6'
3450       ,p_attribute6_value                => p_rec.abs_information6
3451       ,p_attribute7_name                 => 'ABS_INFORMATION7'
3452       ,p_attribute7_value                => p_rec.abs_information7
3453       ,p_attribute8_name                 => 'ABS_INFORMATION8'
3454       ,p_attribute8_value                => p_rec.abs_information8
3455       ,p_attribute9_name                 => 'ABS_INFORMATION9'
3456       ,p_attribute9_value                => p_rec.abs_information9
3457       ,p_attribute10_name                => 'ABS_INFORMATION10'
3458       ,p_attribute10_value               => p_rec.abs_information10
3459       ,p_attribute11_name                => 'ABS_INFORMATION11'
3460       ,p_attribute11_value               => p_rec.abs_information11
3461       ,p_attribute12_name                => 'ABS_INFORMATION12'
3462       ,p_attribute12_value               => p_rec.abs_information12
3463       ,p_attribute13_name                => 'ABS_INFORMATION13'
3464       ,p_attribute13_value               => p_rec.abs_information13
3465       ,p_attribute14_name                => 'ABS_INFORMATION14'
3466       ,p_attribute14_value               => p_rec.abs_information14
3467       ,p_attribute15_name                => 'ABS_INFORMATION15'
3468       ,p_attribute15_value               => p_rec.abs_information15
3469       ,p_attribute16_name                => 'ABS_INFORMATION16'
3470       ,p_attribute16_value               => p_rec.abs_information16
3471       ,p_attribute17_name                => 'ABS_INFORMATION17'
3472       ,p_attribute17_value               => p_rec.abs_information17
3473       ,p_attribute18_name                => 'ABS_INFORMATION18'
3474       ,p_attribute18_value               => p_rec.abs_information18
3475       ,p_attribute19_name                => 'ABS_INFORMATION19'
3476       ,p_attribute19_value               => p_rec.abs_information19
3477       ,p_attribute20_name                => 'ABS_INFORMATION20'
3478       ,p_attribute20_value               => p_rec.abs_information20
3479       ,p_attribute21_name                => 'ABS_INFORMATION21'
3480       ,p_attribute21_value               => p_rec.abs_information21
3481       ,p_attribute22_name                => 'ABS_INFORMATION22'
3482       ,p_attribute22_value               => p_rec.abs_information22
3483       ,p_attribute23_name                => 'ABS_INFORMATION23'
3484       ,p_attribute23_value               => p_rec.abs_information23
3485       ,p_attribute24_name                => 'ABS_INFORMATION24'
3486       ,p_attribute24_value               => p_rec.abs_information24
3487       ,p_attribute25_name                => 'ABS_INFORMATION25'
3488       ,p_attribute25_value               => p_rec.abs_information25
3489       ,p_attribute26_name                => 'ABS_INFORMATION26'
3490       ,p_attribute26_value               => p_rec.abs_information26
3491       ,p_attribute27_name                => 'ABS_INFORMATION27'
3492       ,p_attribute27_value               => p_rec.abs_information27
3493       ,p_attribute28_name                => 'ABS_INFORMATION28'
3494       ,p_attribute28_value               => p_rec.abs_information28
3495       ,p_attribute29_name                => 'ABS_INFORMATION29'
3496       ,p_attribute29_value               => p_rec.abs_information29
3497       ,p_attribute30_name                => 'ABS_INFORMATION30'
3498       ,p_attribute30_value               => p_rec.abs_information30
3499       );
3500   end if;
3501   --
3502   hr_utility.set_location(' Leaving:'||l_proc,20);
3503 end chk_ddf;
3504 --
3505 -- ----------------------------------------------------------------------------
3506 -- |------------------------------< chk_df >----------------------------------|
3507 -- ----------------------------------------------------------------------------
3508 --
3509 -- Description:
3510 --   Validates all the Descriptive Flexfield values.
3511 --
3512 -- Prerequisites:
3513 --   All other columns have been validated.  Must be called as the
3514 --   last step from insert_validate and update_validate.
3515 --
3516 -- In Arguments:
3517 --   p_rec
3518 --
3519 -- Post Success:
3520 --   If the Descriptive Flexfield structure column and data values are
3521 --   all valid this procedure will end normally and processing will
3522 --   continue.
3523 --
3524 -- Post Failure:
3525 --   If the Descriptive Flexfield structure column value or any of
3526 --   the data values are invalid then an application error is raised as
3527 --   a PL/SQL exception.
3528 --
3529 -- Access Status:
3530 --   Internal Row Handler Use Only.
3531 --
3532 -- ----------------------------------------------------------------------------
3533 --
3534 procedure chk_df
3535   (p_rec in per_abs_shd.g_rec_type
3536   ) is
3537 --
3538   l_proc   varchar2(72) := g_package || 'chk_df';
3539 --
3540 begin
3541   hr_utility.set_location('Entering:'||l_proc,10);
3542   --
3543   if ((p_rec.absence_attendance_id is not null)  and (
3544     nvl(per_abs_shd.g_old_rec.attribute_category, hr_api.g_varchar2) <>
3545     nvl(p_rec.attribute_category, hr_api.g_varchar2)  or
3546     nvl(per_abs_shd.g_old_rec.attribute1, hr_api.g_varchar2) <>
3547     nvl(p_rec.attribute1, hr_api.g_varchar2)  or
3548     nvl(per_abs_shd.g_old_rec.attribute2, hr_api.g_varchar2) <>
3549     nvl(p_rec.attribute2, hr_api.g_varchar2)  or
3550     nvl(per_abs_shd.g_old_rec.attribute3, hr_api.g_varchar2) <>
3551     nvl(p_rec.attribute3, hr_api.g_varchar2)  or
3552     nvl(per_abs_shd.g_old_rec.attribute4, hr_api.g_varchar2) <>
3553     nvl(p_rec.attribute4, hr_api.g_varchar2)  or
3554     nvl(per_abs_shd.g_old_rec.attribute5, hr_api.g_varchar2) <>
3555     nvl(p_rec.attribute5, hr_api.g_varchar2)  or
3556     nvl(per_abs_shd.g_old_rec.attribute6, hr_api.g_varchar2) <>
3557     nvl(p_rec.attribute6, hr_api.g_varchar2)  or
3558     nvl(per_abs_shd.g_old_rec.attribute7, hr_api.g_varchar2) <>
3559     nvl(p_rec.attribute7, hr_api.g_varchar2)  or
3560     nvl(per_abs_shd.g_old_rec.attribute8, hr_api.g_varchar2) <>
3561     nvl(p_rec.attribute8, hr_api.g_varchar2)  or
3562     nvl(per_abs_shd.g_old_rec.attribute9, hr_api.g_varchar2) <>
3563     nvl(p_rec.attribute9, hr_api.g_varchar2)  or
3564     nvl(per_abs_shd.g_old_rec.attribute10, hr_api.g_varchar2) <>
3565     nvl(p_rec.attribute10, hr_api.g_varchar2)  or
3566     nvl(per_abs_shd.g_old_rec.attribute11, hr_api.g_varchar2) <>
3567     nvl(p_rec.attribute11, hr_api.g_varchar2)  or
3568     nvl(per_abs_shd.g_old_rec.attribute12, hr_api.g_varchar2) <>
3569     nvl(p_rec.attribute12, hr_api.g_varchar2)  or
3570     nvl(per_abs_shd.g_old_rec.attribute13, hr_api.g_varchar2) <>
3571     nvl(p_rec.attribute13, hr_api.g_varchar2)  or
3572     nvl(per_abs_shd.g_old_rec.attribute14, hr_api.g_varchar2) <>
3573     nvl(p_rec.attribute14, hr_api.g_varchar2)  or
3574     nvl(per_abs_shd.g_old_rec.attribute15, hr_api.g_varchar2) <>
3575     nvl(p_rec.attribute15, hr_api.g_varchar2)  or
3576     nvl(per_abs_shd.g_old_rec.attribute16, hr_api.g_varchar2) <>
3577     nvl(p_rec.attribute16, hr_api.g_varchar2)  or
3578     nvl(per_abs_shd.g_old_rec.attribute17, hr_api.g_varchar2) <>
3579     nvl(p_rec.attribute17, hr_api.g_varchar2)  or
3580     nvl(per_abs_shd.g_old_rec.attribute18, hr_api.g_varchar2) <>
3581     nvl(p_rec.attribute18, hr_api.g_varchar2)  or
3582     nvl(per_abs_shd.g_old_rec.attribute19, hr_api.g_varchar2) <>
3583     nvl(p_rec.attribute19, hr_api.g_varchar2)  or
3584     nvl(per_abs_shd.g_old_rec.attribute20, hr_api.g_varchar2) <>
3585     nvl(p_rec.attribute20, hr_api.g_varchar2) ))
3586     or (p_rec.absence_attendance_id is null)  then
3587     --
3588     -- Only execute the validation if absolutely necessary:
3589     -- a) During update, the structure column value or any
3590     --    of the attribute values have actually changed.
3591     -- b) During insert.
3592     --
3593     hr_dflex_utility.ins_or_upd_descflex_attribs
3594       (p_appl_short_name                 => 'PER'
3595       ,p_descflex_name                   => 'PER_ABSENCE_ATTENDANCES'
3596       ,p_attribute_category              => p_rec.attribute_category
3597       ,p_attribute1_name                 => 'ATTRIBUTE1'
3598       ,p_attribute1_value                => p_rec.attribute1
3599       ,p_attribute2_name                 => 'ATTRIBUTE2'
3600       ,p_attribute2_value                => p_rec.attribute2
3601       ,p_attribute3_name                 => 'ATTRIBUTE3'
3602       ,p_attribute3_value                => p_rec.attribute3
3603       ,p_attribute4_name                 => 'ATTRIBUTE4'
3604       ,p_attribute4_value                => p_rec.attribute4
3605       ,p_attribute5_name                 => 'ATTRIBUTE5'
3606       ,p_attribute5_value                => p_rec.attribute5
3607       ,p_attribute6_name                 => 'ATTRIBUTE6'
3608       ,p_attribute6_value                => p_rec.attribute6
3609       ,p_attribute7_name                 => 'ATTRIBUTE7'
3610       ,p_attribute7_value                => p_rec.attribute7
3611       ,p_attribute8_name                 => 'ATTRIBUTE8'
3612       ,p_attribute8_value                => p_rec.attribute8
3613       ,p_attribute9_name                 => 'ATTRIBUTE9'
3614       ,p_attribute9_value                => p_rec.attribute9
3615       ,p_attribute10_name                => 'ATTRIBUTE10'
3616       ,p_attribute10_value               => p_rec.attribute10
3617       ,p_attribute11_name                => 'ATTRIBUTE11'
3618       ,p_attribute11_value               => p_rec.attribute11
3619       ,p_attribute12_name                => 'ATTRIBUTE12'
3620       ,p_attribute12_value               => p_rec.attribute12
3621       ,p_attribute13_name                => 'ATTRIBUTE13'
3622       ,p_attribute13_value               => p_rec.attribute13
3623       ,p_attribute14_name                => 'ATTRIBUTE14'
3624       ,p_attribute14_value               => p_rec.attribute14
3625       ,p_attribute15_name                => 'ATTRIBUTE15'
3626       ,p_attribute15_value               => p_rec.attribute15
3627       ,p_attribute16_name                => 'ATTRIBUTE16'
3628       ,p_attribute16_value               => p_rec.attribute16
3629       ,p_attribute17_name                => 'ATTRIBUTE17'
3630       ,p_attribute17_value               => p_rec.attribute17
3631       ,p_attribute18_name                => 'ATTRIBUTE18'
3632       ,p_attribute18_value               => p_rec.attribute18
3633       ,p_attribute19_name                => 'ATTRIBUTE19'
3634       ,p_attribute19_value               => p_rec.attribute19
3635       ,p_attribute20_name                => 'ATTRIBUTE20'
3636       ,p_attribute20_value               => p_rec.attribute20
3637       );
3638   end if;
3639   --
3640   hr_utility.set_location(' Leaving:'||l_proc,20);
3641 end chk_df;
3642 --
3643 -- ----------------------------------------------------------------------------
3644 -- |-----------------------< chk_non_updateable_args >------------------------|
3645 -- ----------------------------------------------------------------------------
3646 -- {Start Of Comments}
3647 --
3648 -- Description:
3649 --   This procedure is used to ensure that non updateable attributes have
3650 --   not been updated. If an attribute has been updated an error is generated.
3651 --
3652 -- Pre Conditions:
3653 --   g_old_rec has been populated with details of the values currently in
3654 --   the database.
3655 --
3656 -- In Arguments:
3657 --   p_rec has been populated with the updated values the user would like the
3658 --   record set to.
3659 --
3660 -- Post Success:
3661 --   Processing continues if all the non updateable attributes have not
3662 --   changed.
3663 --
3664 -- Post Failure:
3665 --   An application error is raised if any of the non updatable attributes
3666 --   have been altered.
3667 --
3668 -- {End Of Comments}
3669 -- ----------------------------------------------------------------------------
3670 Procedure chk_non_updateable_args
3671   (p_effective_date               in date
3672   ,p_rec in per_abs_shd.g_rec_type
3673   ) IS
3674 --
3675   l_proc     varchar2(72) := g_package || 'chk_non_updateable_args';
3676   l_error    EXCEPTION;
3677   l_argument varchar2(30);
3678 --
3679 Begin
3680   --
3681   -- Only proceed with the validation if a row exists for the current
3682   -- record in the HR Schema.
3683   --
3684   IF NOT per_abs_shd.api_updating
3685       (p_absence_attendance_id                => p_rec.absence_attendance_id
3686       ,p_object_version_number                => p_rec.object_version_number
3687       ) THEN
3688      fnd_message.set_name('PER', 'HR_6153_ALL_PROCEDURE_FAIL');
3689      fnd_message.set_token('PROCEDURE ', l_proc);
3690      fnd_message.set_token('STEP ', '5');
3691      fnd_message.raise_error;
3692   END IF;
3693   --
3694   hr_utility.set_location(l_proc, 2);
3695   if nvl(p_rec.absence_attendance_id,hr_api.g_number) <>
3696      per_abs_shd.g_old_rec.absence_attendance_id then
3697      l_argument := 'absence_attendance_id';
3698      raise l_error;
3699   end if;
3700   --
3701   hr_utility.set_location(l_proc, 3);
3702   if nvl(p_rec.business_group_id, hr_api.g_number) <>
3703      per_abs_shd.g_old_rec.business_group_id then
3704      l_argument := 'business_group_id';
3705      raise l_error;
3706   end if;
3707   --
3708   hr_utility.set_location(l_proc, 4);
3709   if nvl(p_rec.person_id, hr_api.g_number) <>
3710      per_abs_shd.g_old_rec.person_id then
3711      l_argument := 'person_id';
3712      raise l_error;
3713   end if;
3714   --
3715   hr_utility.set_location(l_proc, 5);
3716   if nvl(p_rec.absence_attendance_type_id,hr_api.g_number) <>
3717      per_abs_shd.g_old_rec.absence_attendance_type_id then
3718      l_argument := 'absence_attendance_type_id';
3719      raise l_error;
3720   end if;
3721   --
3722   hr_utility.set_location(l_proc, 6);
3723   if nvl(p_rec.occurrence,hr_api.g_number) <>
3724      per_abs_shd.g_old_rec.occurrence then
3725      l_argument := 'occurrence';
3726      raise l_error;
3727   end if;
3728   --
3729   EXCEPTION
3730     WHEN l_error THEN
3731        hr_api.argument_changed_error
3732          (p_api_name => l_proc
3733          ,p_argument => l_argument);
3734     WHEN OTHERS THEN
3735        RAISE;
3736 End chk_non_updateable_args;
3737 --
3738 -- ----------------------------------------------------------------------------
3739 -- |---------------------------< insert_validate >----------------------------|
3740 -- ----------------------------------------------------------------------------
3741 Procedure insert_validate
3742   (p_effective_date               in  date
3743   ,p_rec                          in  per_abs_shd.g_rec_type
3744   ,p_dur_dys_less_warning         out nocopy boolean
3745   ,p_dur_hrs_less_warning         out nocopy boolean
3746   ,p_exceeds_pto_entit_warning    out nocopy boolean
3747   ,p_exceeds_run_total_warning    out nocopy boolean
3748   ,p_abs_overlap_warning          out nocopy boolean
3749   ,p_abs_day_after_warning        out nocopy boolean
3750   ,p_dur_overwritten_warning      out nocopy boolean
3751   ) is
3752 --
3753   l_proc  varchar2(72) := g_package||'insert_validate';
3754   l_effective_date date;  -- Added for bug 3371960
3755 
3756   ----Check the gender of the person in case of maternity leave bug# 6505054
3757 
3758   cursor c_absence_cat(p_absence_attendance_type_id in number) is
3759    select absence_category from per_absence_attendance_types
3760    where absence_attendance_type_id = p_absence_attendance_type_id;
3761 
3762   l_ssp_installed boolean;
3763   l_absence_category varchar2(30);
3764 
3765 --
3766 Begin
3767 
3768   hr_utility.set_location('Entering:'||l_proc, 5);
3769 
3770   --
3771   -- Assign the durations to the global variables.
3772   --
3773   per_abs_shd.g_absence_days  := p_rec.absence_days;
3774   per_abs_shd.g_absence_hours := p_rec.absence_hours;
3775 
3776   --
3777   -- Fix for bug 3371960 starts here. Use the l_effective_date
3778   -- in chk procedures.
3779   --
3780   l_effective_date := NVL(p_rec.date_start, p_effective_date);
3781   --
3782   -- Fix for bug 3371960 ends here.
3783   --
3784   -- Check the business group id.
3785   --
3786   hr_api.validate_bus_grp_id(p_rec.business_group_id);
3787 
3788   hr_utility.set_location(l_proc, 10);
3789 
3790   ----Check the gender of the person in case of maternity leave bug# 6505054
3791 
3792   open c_absence_cat(p_rec.absence_attendance_type_id);
3793    fetch c_absence_cat into l_absence_category;
3794   close c_absence_cat;
3795 
3796   l_ssp_installed := ssp_ssp_pkg.ssp_is_installed;
3797 
3798   if l_ssp_installed and l_absence_category = 'M' then
3799 
3800     ssp_mat_bus.validate_female_sex(p_rec.person_id);
3801 
3802   end if;
3803 
3804 -- end for bug# 6505054
3805 
3806   --
3807   -- Check person ID.
3808   --
3809   chk_person_id
3810     (p_absence_attendance_id      => p_rec.absence_attendance_id
3811     ,p_person_id                  => p_rec.person_id
3812     ,p_business_group_id          => p_rec.business_group_id
3813     ,p_object_version_number      => p_rec.object_version_number
3814     ,p_date_projected_start       => p_rec.date_projected_start
3815     ,p_date_projected_end         => p_rec.date_projected_end
3816     ,p_date_start                 => p_rec.date_start
3817     ,p_date_end                   => p_rec.date_end);
3818 
3819   --
3820   -- Check absence attendance type ID
3821   --
3822   chk_absence_attendance_type_id
3823     (p_absence_attendance_id      => p_rec.absence_attendance_id
3824     ,p_absence_attendance_type_id => p_rec.absence_attendance_type_id
3825     ,p_business_group_id          => p_rec.business_group_id
3826     ,p_object_version_number      => p_rec.object_version_number
3827     ,p_date_projected_start       => p_rec.date_projected_start
3828     ,p_date_projected_end         => p_rec.date_projected_end
3829     ,p_date_start                 => p_rec.date_start
3830     ,p_date_end                   => p_rec.date_end);
3831 
3832   --
3833   -- Check the absence reason ID.
3834   --
3835   chk_abs_attendance_reason_id
3836     (p_absence_attendance_id      => p_rec.absence_attendance_id
3837     ,p_absence_attendance_type_id => p_rec.absence_attendance_type_id
3838     ,p_abs_attendance_reason_id   => p_rec.abs_attendance_reason_id
3839     ,p_business_group_id          => p_rec.business_group_id
3840     ,p_object_version_number      => p_rec.object_version_number
3841     ,p_effective_date             => l_effective_date);
3842 
3843   --
3844   -- Check absence period.
3845   --
3846   -- Check the absence period (this includes all duration validation).
3847   -- The durations are in out parameters and are assigned to global
3848   -- variables.  This is because they will be over-written during
3849   -- pre insert / pre update if the Fast Formula Auto-Overwrite duration
3850   -- profile option is set to yes during pre_insert.
3851   --
3852   chk_absence_period
3853     (p_absence_attendance_id      => p_rec.absence_attendance_id
3854     ,p_absence_attendance_type_id => p_rec.absence_attendance_type_id
3855     ,p_business_group_id          => p_rec.business_group_id
3856     ,p_object_version_number      => p_rec.object_version_number
3857     ,p_effective_date             => l_effective_date
3858     ,p_person_id                  => p_rec.person_id
3859     ,p_date_projected_start       => p_rec.date_projected_start
3860     ,p_time_projected_start       => p_rec.time_projected_start
3861     ,p_date_projected_end         => p_rec.date_projected_end
3862     ,p_time_projected_end         => p_rec.time_projected_end
3863     ,p_date_start                 => p_rec.date_start
3864     ,p_time_start                 => p_rec.time_start
3865     ,p_date_end                   => p_rec.date_end
3866     ,p_time_end                   => p_rec.time_end
3867     ,p_ABS_INFORMATION_CATEGORY   =>p_rec.ABS_INFORMATION_CATEGORY
3868     ,p_ABS_INFORMATION1		=>p_rec.ABS_INFORMATION1
3869     ,p_ABS_INFORMATION2		=>p_rec.ABS_INFORMATION2
3870     ,p_ABS_INFORMATION3		=>p_rec.ABS_INFORMATION3
3871     ,p_ABS_INFORMATION4		=>p_rec.ABS_INFORMATION4
3872     ,p_ABS_INFORMATION5		=>p_rec.ABS_INFORMATION5
3873     ,p_ABS_INFORMATION6		=>p_rec.ABS_INFORMATION6
3874     ,p_absence_days               => per_abs_shd.g_absence_days
3875     ,p_absence_hours              => per_abs_shd.g_absence_hours
3876     ,p_dur_dys_less_warning       => p_dur_dys_less_warning
3877     ,p_dur_hrs_less_warning       => p_dur_hrs_less_warning
3878     ,p_exceeds_pto_entit_warning  => p_exceeds_pto_entit_warning
3879     ,p_exceeds_run_total_warning  => p_exceeds_run_total_warning
3880     ,p_abs_overlap_warning        => p_abs_overlap_warning
3881     ,p_abs_day_after_warning      => p_abs_day_after_warning
3882     ,p_dur_overwritten_warning    => p_dur_overwritten_warning);
3883 
3884   --
3885   -- Check the replacement person ID
3886   --
3887   chk_replacement_person_id
3888     (p_absence_attendance_id      => p_rec.absence_attendance_id
3889     ,p_replacement_person_id      => p_rec.replacement_person_id
3890     ,p_business_group_id          => p_rec.business_group_id
3891     ,p_object_version_number      => p_rec.object_version_number
3892     ,p_date_projected_start       => p_rec.date_projected_start
3893     ,p_date_projected_end         => p_rec.date_projected_end
3894     ,p_date_start                 => p_rec.date_start
3895     ,p_date_end                   => p_rec.date_end);
3896 
3897   --
3898   -- Check the authorising person ID
3899   --
3900   chk_authorising_person_id
3901     (p_absence_attendance_id      => p_rec.absence_attendance_id
3902     ,p_authorising_person_id      => p_rec.authorising_person_id
3903     ,p_business_group_id          => p_rec.business_group_id
3904     ,p_object_version_number      => p_rec.object_version_number
3905     ,p_date_projected_start       => p_rec.date_projected_start
3906     ,p_date_projected_end         => p_rec.date_projected_end
3907     ,p_date_start                 => p_rec.date_start
3908     ,p_date_end                   => p_rec.date_end);
3909 
3910 
3911   hr_utility.set_location(l_proc, 24);
3912   --
3913   per_abs_bus.chk_ddf(p_rec);
3914   --
3915   per_abs_bus.chk_df(p_rec);
3916   --
3917   hr_utility.set_location(' Leaving:'||l_proc, 10);
3918 End insert_validate;
3919 --
3920 -- ----------------------------------------------------------------------------
3921 -- |---------------------------< update_validate >----------------------------|
3922 -- ----------------------------------------------------------------------------
3923 Procedure update_validate
3924   (p_effective_date               in  date
3925   ,p_rec                          in  per_abs_shd.g_rec_type
3926   ,p_dur_dys_less_warning         out nocopy boolean
3927   ,p_dur_hrs_less_warning         out nocopy boolean
3928   ,p_exceeds_pto_entit_warning    out nocopy boolean
3929   ,p_exceeds_run_total_warning    out nocopy boolean
3930   ,p_abs_overlap_warning          out nocopy boolean
3931   ,p_abs_day_after_warning        out nocopy boolean
3932   ,p_dur_overwritten_warning      out nocopy boolean
3933   ) is
3934 --
3935   l_proc  varchar2(72) := g_package||'update_validate';
3936   l_effective_date date; -- Added for bug 3371960.
3937 --
3938 Begin
3939 
3940   hr_utility.set_location('Entering:'||l_proc, 5);
3941   --
3942   -- Fix for bug 3371960 starts here.
3943   -- Use l_effective_date in different chk proceudre.
3944   --
3945   l_effective_date := NVL(p_rec.date_start, p_effective_date);
3946   --
3947   -- Fix for bug 3371960 ends here.
3948   --
3949   -- Assign the durations to the global variables.
3950   --
3951   per_abs_shd.g_absence_days  := p_rec.absence_days;
3952   per_abs_shd.g_absence_hours := p_rec.absence_hours;
3953 
3954   hr_api.validate_bus_grp_id(p_rec.business_group_id);  -- Validate Bus Grp
3955   --
3956   chk_non_updateable_args
3957     (p_effective_date              => p_effective_date
3958       ,p_rec              => p_rec
3959     );
3960   --
3961   hr_utility.set_location(l_proc, 14);
3962 
3963   --
3964   -- Check person ID. This procedure is called during update_validate
3965   -- because the person must be valid for the entire absence period
3966   -- (which can be updated).
3967   --
3968   chk_person_id
3969     (p_absence_attendance_id      => p_rec.absence_attendance_id
3970     ,p_person_id                  => p_rec.person_id
3971     ,p_business_group_id          => p_rec.business_group_id
3972     ,p_object_version_number      => p_rec.object_version_number
3973     ,p_date_projected_start       => p_rec.date_projected_start
3974     ,p_date_projected_end         => p_rec.date_projected_end
3975     ,p_date_start                 => p_rec.date_start
3976     ,p_date_end                   => p_rec.date_end);
3977 
3978   --
3979   -- Check absence attendance type ID. This is called from
3980   -- update_validate because the absence type must be valid for
3981   -- the entire absence period (which can be updated).
3982   --
3983   chk_absence_attendance_type_id
3984     (p_absence_attendance_id      => p_rec.absence_attendance_id
3985     ,p_absence_attendance_type_id => p_rec.absence_attendance_type_id
3986     ,p_business_group_id          => p_rec.business_group_id
3987     ,p_object_version_number      => p_rec.object_version_number
3988     ,p_date_projected_start       => p_rec.date_projected_start
3989     ,p_date_projected_end         => p_rec.date_projected_end
3990     ,p_date_start                 => p_rec.date_start
3991     ,p_date_end                   => p_rec.date_end);
3992 
3993   --
3994   -- Check the absence reason ID.
3995   --
3996   chk_abs_attendance_reason_id
3997     (p_absence_attendance_id      => p_rec.absence_attendance_id
3998     ,p_absence_attendance_type_id => p_rec.absence_attendance_type_id
3999     ,p_abs_attendance_reason_id   => p_rec.abs_attendance_reason_id
4000     ,p_business_group_id          => p_rec.business_group_id
4001     ,p_object_version_number      => p_rec.object_version_number
4002     ,p_effective_date             => l_effective_date);
4003 
4004   --
4005   -- Check absence period.
4006   --
4007   -- Check the absence period (this includes all duration validation).
4008   -- The durations are in out parameters and are assigned to global
4009   -- variables.  This is because they will be over-written during
4010   -- pre insert / pre update if the Fast Formula Auto-Overwrite duration
4011   -- profile option is set to yes during pre-update.
4012   --
4013   chk_absence_period
4014     (p_absence_attendance_id      => p_rec.absence_attendance_id
4015     ,p_absence_attendance_type_id => p_rec.absence_attendance_type_id
4016     ,p_business_group_id          => p_rec.business_group_id
4017     ,p_object_version_number      => p_rec.object_version_number
4018     ,p_effective_date             => l_effective_date
4019     ,p_person_id                  => p_rec.person_id
4020     ,p_date_projected_start       => p_rec.date_projected_start
4021     ,p_time_projected_start       => p_rec.time_projected_start
4022     ,p_date_projected_end         => p_rec.date_projected_end
4023     ,p_time_projected_end         => p_rec.time_projected_end
4024     ,p_date_start                 => p_rec.date_start
4025     ,p_time_start                 => p_rec.time_start
4026     ,p_date_end                   => p_rec.date_end
4027     ,p_time_end                   => p_rec.time_end
4028     ,p_ABS_INFORMATION_CATEGORY   =>p_rec.ABS_INFORMATION_CATEGORY
4029     ,p_ABS_INFORMATION1		   =>p_rec.ABS_INFORMATION1
4030     ,p_ABS_INFORMATION2		=>p_rec.ABS_INFORMATION2
4031     ,p_ABS_INFORMATION3		=>p_rec.ABS_INFORMATION3
4032     ,p_ABS_INFORMATION4		=>p_rec.ABS_INFORMATION4
4033     ,p_ABS_INFORMATION5		=>p_rec.ABS_INFORMATION5
4034     ,p_ABS_INFORMATION6		=>p_rec.ABS_INFORMATION6
4035     ,p_absence_days               => per_abs_shd.g_absence_days
4036     ,p_absence_hours              => per_abs_shd.g_absence_hours
4037     ,p_dur_dys_less_warning       => p_dur_dys_less_warning
4038     ,p_dur_hrs_less_warning       => p_dur_hrs_less_warning
4039     ,p_exceeds_pto_entit_warning  => p_exceeds_pto_entit_warning
4040     ,p_exceeds_run_total_warning  => p_exceeds_run_total_warning
4041     ,p_abs_overlap_warning        => p_abs_overlap_warning
4042     ,p_abs_day_after_warning      => p_abs_day_after_warning
4043     ,p_dur_overwritten_warning    => p_dur_overwritten_warning);
4044 
4045 
4046   --
4047   -- Check the replacement person ID
4048   --
4049   chk_replacement_person_id
4050     (p_absence_attendance_id      => p_rec.absence_attendance_id
4051     ,p_replacement_person_id      => p_rec.replacement_person_id
4052     ,p_business_group_id          => p_rec.business_group_id
4053     ,p_object_version_number      => p_rec.object_version_number
4054     ,p_date_projected_start       => p_rec.date_projected_start
4055     ,p_date_projected_end         => p_rec.date_projected_end
4056     ,p_date_start                 => p_rec.date_start
4057     ,p_date_end                   => p_rec.date_end);
4058 
4059   --
4060   -- Check the authorising person ID
4061   --
4062   chk_authorising_person_id
4063     (p_absence_attendance_id      => p_rec.absence_attendance_id
4064     ,p_authorising_person_id      => p_rec.authorising_person_id
4065     ,p_business_group_id          => p_rec.business_group_id
4066     ,p_object_version_number      => p_rec.object_version_number
4067     ,p_date_projected_start       => p_rec.date_projected_start
4068     ,p_date_projected_end         => p_rec.date_projected_end
4069     ,p_date_start                 => p_rec.date_start
4070     ,p_date_end                   => p_rec.date_end);
4071 
4072 
4073   hr_utility.set_location(l_proc, 24);
4074   --
4075   per_abs_bus.chk_ddf(p_rec);
4076   --
4077   per_abs_bus.chk_df(p_rec);
4078   --
4079   hr_utility.set_location(' Leaving:'||l_proc, 10);
4080 End update_validate;
4081 --
4082 -- ----------------------------------------------------------------------------
4083 -- |---------------------------< delete_validate >----------------------------|
4084 -- ----------------------------------------------------------------------------
4085 Procedure delete_validate
4086   (p_rec                          in per_abs_shd.g_rec_type
4087   ) is
4088 --
4089   l_proc  varchar2(72) := g_package||'delete_validate';
4090 --
4091 Begin
4092   hr_utility.set_location('Entering:'||l_proc, 5);
4093   --
4094   -- Call all supporting business operations
4095   --
4096   hr_utility.set_location(' Leaving:'||l_proc, 10);
4097 End delete_validate;
4098 --
4099 end per_abs_bus;