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