DBA Data[Home] [Help]

PACKAGE BODY: APPS.PER_GB_ABSENCE_RULES

Source


1 PACKAGE BODY per_gb_absence_rules AS
2 /* $Header: pegbabsr.pkb 120.16 2010/08/10 07:33:35 npannamp noship $ */
3 
4 
5 -------------------------------------------------------------------------------
6 -- CHECK_ABS_OVERLAP
7 ---------------------------------------------------------------------------------
8 -- Bug 6708992
9 -- Procedure to raise error if overlapping absences of same type are present
10 /*
11 -- Bug 7447080
12 -- The below procedure is commented as c_abs_overlap_another cursor errors for different NLS calendar settings.
13 -- The cursor is modified so that the to_date and to_char functions are removed and handled in for loop of the cursor.
14 PROCEDURE check_abs_overlap( p_person_id  IN NUMBER
15                                ,p_date_start IN DATE
16                                ,p_date_end   IN DATE
17                                ,p_time_start IN VARCHAR2
18                                ,p_time_end IN VARCHAR2
19                                ,p_absence_attendance_id IN NUMBER
20                                --,p_absence_attendance_type_id IN NUMBER) IS    --Absence category instead of Absence type 6888892
21                               ,p_absence_category IN VARCHAR2) IS
22 
23 -- 6888892 Changed this cursor, so that the check is based on Absence Categories
24      cursor c_abs_overlap_another is
25      select 1
26      from   per_absence_attendances abs, per_absence_attendance_types paat
27      where  paat.absence_category = p_absence_category
28      and    paat.absence_attendance_type_id = abs.absence_attendance_type_id
29      and    abs.person_id = p_person_id
30      and    (p_absence_attendance_id is null or
31              p_absence_attendance_id <> abs.absence_attendance_id)
32      and    abs.date_start is not null
33      and    p_date_start is not null
34      and   ((
35             to_date(to_char(abs.date_start,'YYYY-MM-DD')|| ' ' ||
36             nvl(abs.time_start,'00:00'),'YYYY-MM-DD HH24:MI:SS')
37             between
41             to_date(to_char(nvl(p_date_end,hr_api.g_eot),'YYYY-MM-DD')|| ' ' ||
38             to_date(to_char(p_date_start,'YYYY-MM-DD')|| ' ' ||
39             nvl(p_time_start,'00:00'),'YYYY-MM-DD HH24:MI:SS')
40             AND
42             nvl(p_time_end,'23:59'),'YYYY-MM-DD HH24:MI:SS'))
43           OR
44             (
45              to_date(to_char(p_date_start,'YYYY-MM-DD')|| ' ' ||
46              nvl(p_time_start,'00:00'),'YYYY-MM-DD HH24:MI:SS')
47             between
48             to_date(to_char(abs.date_start,'YYYY-MM-DD')|| ' ' ||
49             nvl(abs.time_start,'00:00'),'YYYY-MM-DD HH24:MI:SS')
50             AND
51             to_date(to_char(nvl(abs.date_end,hr_api.g_eot),'YYYY-MM-DD')|| ' ' ||
52             nvl(abs.time_end,'23:59'),'YYYY-MM-DD HH24:MI:SS')
53        )
54        );
55 
56        l_exists NUMBER ;
57 BEGIN
58        open c_abs_overlap_another;
59        fetch c_abs_overlap_another INTO l_exists;
60        if c_abs_overlap_another%found then
61             close c_abs_overlap_another;
62     		hr_utility.set_message(804,'SSP_35084_SIMILAR_ABS_OVERLAP');
63     		hr_utility.raise_error;
64        else
65 	        close c_abs_overlap_another;
66        end if ;
67 END check_abs_overlap;
68 */
69 PROCEDURE check_abs_overlap( p_person_id  IN NUMBER
70                                ,p_date_start IN DATE
71                                ,p_date_end   IN DATE
72                                ,p_time_start IN VARCHAR2
73                                ,p_time_end IN VARCHAR2
74                                ,p_absence_attendance_id IN NUMBER
75                                --,p_absence_attendance_type_id IN NUMBER) IS    --Absence category instead of Absence type 6888892
76                               ,p_absence_category IN VARCHAR2) IS
77 
78 cursor c_abs_overlap_another is
79 select nvl(abs.time_start,'00:00') start_time, nvl(abs.time_end,'23:59') end_time
80 from   per_absence_attendances abs, per_absence_attendance_types paat
81 where  paat.absence_category = p_absence_category
82 and    paat.absence_attendance_type_id = abs.absence_attendance_type_id
83 and    abs.person_id = p_person_id
84 and    (p_absence_attendance_id is null or
85      p_absence_attendance_id <> abs.absence_attendance_id)
86 and    abs.date_start is not null
87 and    p_date_start is not null
88 and   (abs.date_start between p_date_start AND nvl(p_date_end,hr_api.g_eot)
89        OR
90     p_date_start between abs.date_start and nvl(abs.date_end,hr_api.g_eot) )
91 order by 1;
92 
93 b_over_lap boolean := false;
94 
95 begin
96 hr_utility.trace('Entering check_abs_overlap ');
97 hr_utility.trace('check_abs_overlap p_person_id:'||p_person_id);
98 hr_utility.trace('check_abs_overlap p_date_start:'||p_date_start);
99 hr_utility.trace('check_abs_overlap p_date_end:'||p_date_end);
100 hr_utility.trace('check_abs_overlap p_time_start:'||nvl(p_time_start,'NULL'));
101 hr_utility.trace('check_abs_overlap p_time_end:'||nvl(p_time_end,'NULL'));
102 hr_utility.trace('check_abs_overlap p_absence_attendance_id:'||p_absence_attendance_id);
103 hr_utility.trace('check_abs_overlap hr_api.g_eot:'||hr_api.g_eot);
104 
105 for i in c_abs_overlap_another
106 loop
107 hr_utility.trace('check_abs_overlap i.end_time:'||i.end_time);
108 if nvl(p_time_start,'00:00') <= i.end_time then
109 	b_over_lap := true;
110 	exit;
111 end if;
112 end loop;
113 
114 if b_over_lap then
115 	hr_utility.trace('check_abs_overlap Overlapping Exists');
116 	hr_utility.set_message(804,'SSP_35084_SIMILAR_ABS_OVERLAP');
117 	hr_utility.raise_error;
118 else
119     hr_utility.trace('check_abs_overlap No Overlap');
120 end if;
121 hr_utility.trace('check_abs_overlap  Completed.');
122 exception
123 when others then
124 hr_utility.trace('check_abs_overlap  Exception:'||sqlerrm);
125 raise;
126 end check_abs_overlap;
127 --
128 --
129 
130 PROCEDURE sickness_date_update
131   (p_absence_attendance_id        IN    NUMBER
132   ) IS
133 --
134 l_proc VARCHAR2(30) ;
135 --
136 CURSOR get_abs_category IS
137 SELECT paat.absence_category
138 FROM   per_absence_attendance_types paat,
139        per_absence_attendances paa
140 WHERE  paa.absence_attendance_id = p_absence_attendance_id
141 AND    paa.absence_attendance_type_id = paat.absence_attendance_type_id;
142 --
143 l_abs_category per_absence_attendance_types.absence_category%TYPE;
144 --
145 BEGIN
146   --
147   -- Added for GSI Bug 5472781
148   --
149   IF hr_utility.chk_product_install('Oracle Human Resources', 'GB') THEN
150    --
151    l_proc := 'PER_GB_ABSENCE_RULES';
152 
153    hr_utility.set_location('Entering:'|| l_proc, 10);
154    hr_utility.trace(l_proc||': Opening get_abs_category'||
155                       ', p_absence_attendance_id='||p_absence_attendance_id);
156    --
157    -- Get absence_category
158    --
159    OPEN get_abs_category;
160    FETCH get_abs_category INTO l_abs_category;
161    CLOSE get_abs_category;
162    --
163    hr_utility.trace(l_proc||': Closed get_abs_category'||
164                       ', l_abs_category='||l_abs_category);
165    --
166 --7157943 when this procedure is called from after delete hook l_abs_category will be NULL
167    --IF l_abs_category = 'S' THEN
168     IF nvl(l_abs_category,'S') = 'S' THEN
169       -- call recalculate_SSP_and_SMP to create/update stoppages and/or element entries.
170 
171       ssp_smp_support_pkg.recalculate_SSP_and_SMP(p_deleting=>FALSE);
172 
176  --
173    END IF;
174    --
175  END IF;
177  hr_utility.set_location('Leaving:'|| l_proc, 200);
178  --
179 END sickness_date_update;
180 --
181 
182 -------------------------------------------------------------------------------
183 -- VALIDATE_ABS_CREATE
184 -------------------------------------------------------------------------------
185 PROCEDURE validate_abs_create(p_business_group_id            IN NUMBER
186                              ,p_person_id                    IN NUMBER
187 			                 ,p_date_start                   IN DATE
188 			                 ,p_date_end                     IN DATE -- Bug 6708992
189                              ,p_time_start IN VARCHAR2     -- Bug 6708992
190                              ,p_time_end IN VARCHAR2       -- Bug 6708992
191 			                 ,p_absence_attendance_type_id   IN NUMBER
192                             ) IS
193 
194     CURSOR get_abs_category IS
195     SELECT paat.absence_category
196     FROM   per_absence_attendance_types paat
197     WHERE  paat.absence_attendance_type_id = p_absence_attendance_type_id
198     AND    paat.business_group_id = p_business_group_id;
199 
200     CURSOR csr_absences
201     IS
202     SELECT 1
203     FROM   per_absence_attendances PAA
204     WHERE  PAA.person_id           = p_person_id
205     and    PAA.business_group_id   = p_business_group_id
206     AND    PAA.sickness_start_date is not null
207     AND    p_date_start          <  (select max(ABS.sickness_start_date)
208                                      from per_absence_attendances ABS
209 		                     where ABS.business_group_id   = p_business_group_id
210 		                     and   ABS.person_id           = p_person_id);
211 
212     l_absence       NUMBER;
213     l_abs_category per_absence_attendance_types.absence_category%TYPE;
214 
215 BEGIN
216   --
217   -- Added for GSI Bug 5472781
218   --
219   hr_utility.trace(' Entering PER_GB_ABSENCE_RULES.VALIDATE_ABS_CREATE ');
220   IF hr_utility.chk_product_install('Oracle Human Resources', 'GB') THEN
221    --
222    -- Get absence_category
223    --
224    OPEN get_abs_category;
225    FETCH get_abs_category INTO l_abs_category;
226    CLOSE get_abs_category;
227    --
228    --
229    IF l_abs_category = 'S' THEN
230 
231         OPEN csr_absences;
232         FETCH csr_absences INTO l_absence;
233         if  csr_absences%found then
234 	        close csr_absences;
235 		hr_utility.set_message(804,'SSP_35037_PIW_BROKEN');
236 		hr_utility.raise_error;
237         else
238 	        close csr_absences;
239         end if;
240     END IF;
241 
242   -- Bug 6708992
243   -- Raise error if overlapping absences of same type are present
244   -- Bug 6888892 begin
245   -- To check only in case below mentioned absence categories also
246   -- changed the check to be based on Absence Category
247   if l_abs_category in ('S','M','GB_ADO','GB_PAT_BIRTH','GB_PAT_ADO') then
248   check_abs_overlap( p_person_id, p_date_start, p_date_end
249                     ,p_time_start, p_time_end, null
250                     --,p_absence_attendance_type_id) ;
251                     ,l_abs_category);
252   end if;
253  -- Bug 6888892 begin
254 
255   END IF;
256   hr_utility.trace(' Leaving PER_GB_ABSENCE_RULES.VALIDATE_ABS_CREATE ');
257 END validate_abs_create;
258 
259 -------------------------------------------------------------------------------
260 -- VALIDATE_ABS_UPDATE
261 -------------------------------------------------------------------------------
262 PROCEDURE validate_abs_update(p_date_start            IN DATE,
263                               p_date_end              IN DATE,
264                               p_time_start IN VARCHAR2,  -- Bug 6708992
265                               p_time_end IN VARCHAR2,    -- Bug 6708992
266                               p_sickness_start_date in date, -- Bug 9864927
267                               p_sickness_end_date in date,   -- Bug 9864927
268                               p_absence_attendance_id IN NUMBER) IS
269 
270     cursor csr_abs_details is
271     select absence_attendance_type_id,
272            business_group_id,
273            person_id,
274            sickness_start_date,
275            sickness_end_date
276 --7287548 begin
277 	,date_start,time_start,date_end,time_end
278 --7287548 End
279     from   per_absence_attendances
280     where  absence_attendance_id = p_absence_attendance_id;
281 
282     CURSOR get_abs_category(p_abs_type_id number,
283                             p_bus_group   number) IS
284     SELECT paat.absence_category
285     FROM   per_absence_attendance_types paat
286     WHERE  paat.absence_attendance_type_id = p_abs_type_id
287     AND    paat.business_group_id = p_bus_group;
288 
289     CURSOR csr_absences(p_person_id number,
290                         p_business_group_id number,
291                         p_start     date)IS
292     SELECT 1
293     FROM   per_absence_attendances PAA
294     WHERE  PAA.person_id           = p_person_id
295     and    PAA.business_group_id   = p_business_group_id
296     AND    PAA.sickness_start_date is not null
297     AND    PAA.sickness_start_date > p_start
298     AND    PAA.absence_attendance_id <> p_absence_attendance_id;
299 
300     l_absence            number;
301     l_business_group_id  number;
302     l_person_id          number;
303     l_abs_type_id        number;
304     l_param_start        date;
305     l_current_start      date;
306     l_current_end        date;
310 l_time_start   varchar2(5);
307     l_abs_category per_absence_attendance_types.absence_category%TYPE;
308 --7287548 begin
309 l_date_start   date;
311 l_date_end	   date;
312 l_time_end     varchar2(5);
313 v_date_start   date;
314 v_time_start   varchar2(5);
315 v_date_end	   date;
316 v_time_end     varchar2(5);
317 --7287548 End
318 
319 BEGIN
320   --
321   hr_utility.trace(' Entering PER_GB_ABSENCE_RULES.VALIDATE_ABS_UPDATE ');
322   hr_utility.trace(' p_date_start '||p_date_start  );
323   hr_utility.trace(' p_date_end '|| p_date_end );
324   hr_utility.trace(' p_time_start '||p_time_start);
325   hr_utility.trace(' p_time_end '|| p_time_end);
326   hr_utility.trace(' p_absence_attendance_id '||p_absence_attendance_id);
327  /* Commented the debugging message with to_date function.
328   hr_utility.trace('  From date '|| to_date(to_char(p_date_start,'YYYY-MM-DD')|| ' ' ||nvl(p_time_start,'00:00'),'YYYY-MM-DD HH24:MI:SS'));
329   hr_utility.trace(' to date '   || to_date(to_char(nvl(p_date_end,hr_api.g_eot),'YYYY-MM-DD')|| ' ' ||nvl(p_time_end,'23:59'),'YYYY-MM-DD HH24:MI:SS'));
330 */
331   -- Added for GSI Bug 5472781
332   --
333   IF hr_utility.chk_product_install('Oracle Human Resources', 'GB') THEN
334    -- Get absence details
335    hr_utility.trace(' before opening cursor csr_abs_details');
336    open csr_abs_details;
337    fetch csr_abs_details into l_abs_type_id,
338                               l_business_group_id,
339                               l_person_id,
340                               l_current_start,
341                               l_current_end
342 				--7287548 begin
343 					,l_date_start
344 					,l_time_start
345 					,l_date_end
346 					,l_time_end;
347 				--7287548 End
348    close csr_abs_details;
349    --
350    hr_utility.trace(' after closing cursor csr_abs_details');
351 
352    -- Check if default date is passed in for start/end date
353    -- logic
354    -- if not updating start or end date then skip
355    -- if not updating start or end date, but date is pass in then skip
356    -- if updating start/end and exists a future absence then error
357    if trunc(p_date_start) = trunc(hr_api.g_date) and
358       trunc(p_date_end) = trunc(hr_api.g_date) then
359       -- not updating sickness start/end date so skip
360       hr_utility.trace('Satisified IF');
361       null;
362    else
363       hr_utility.trace('Satisfied ELSE');
364       /* Bug Fix 9864927 Start
365          Scenario: Absence Start/End date need not be same as Sickness Start/End Date.
366                    For ex., Absence End date can be one day more than the Sickness End Date.
367                    So below condition modified.
368       if trunc(l_current_start) = trunc(p_date_start) and
369          trunc(l_current_end) = trunc(p_date_end) then
370          -- not updating sickness start/end date so skip */
371 
372       if (
373           (trunc(l_current_start) = trunc(p_sickness_start_date) and
374          trunc(l_current_end) = trunc(p_sickness_end_date))
375          and
376           (trunc(l_date_start) = trunc(p_date_start) and
377          trunc(l_date_end) = trunc(p_date_end))
378          ) then
379          -- not updating sickness start/end date so skip
380          /* Bug Fix 9864927 End */
381          hr_utility.trace(' not updating sickness start/end date so skip ');
382          null;
383       else
384          -- going to update start or end date, check for future absence
385          -- Get absence_category
386          --
387          hr_utility.trace(' going to update start or end date, check for future absence ');
388 
389          OPEN get_abs_category(l_abs_type_id, l_business_group_id);
390          FETCH get_abs_category INTO l_abs_category;
391          CLOSE get_abs_category;
392          --
393          --
394          hr_utility.trace(' after fetching abs category '||l_abs_category);
395 
396          IF l_abs_category = 'S' THEN
397             hr_utility.trace(' for sickness S');
398             if trunc(p_date_start) = trunc(hr_api.g_date) then
399                l_param_start := trunc(l_current_start);
400             else
401                l_param_start := trunc(p_date_start);
402             end if;
403             hr_utility.trace(' before csr_absences open');
404             OPEN csr_absences(l_person_id, l_business_group_id,l_param_start);
405             FETCH csr_absences INTO l_absence;
406             if  csr_absences%found then
407                 close csr_absences;
408                 hr_utility.set_message(804,'SSP_35037_PIW_BROKEN');
409                 hr_utility.raise_error;
410             else
411                 hr_utility.trace('csr_absences not found');
412                 close csr_absences;
413             end if;
414          END IF;
415       end if;
416     end if;
417 
418 --7287548 begin
419  If (p_date_start = hr_api.g_date) then
420 hr_utility.trace(' p_date_start value is defaulted '||p_date_start||' Repl by'||l_date_start);
421     v_date_start := l_date_start;
422  else
423     v_date_start := p_date_start;
424  End If;
425 
426  If (p_date_end = hr_api.g_date) then
427 hr_utility.trace(' p_date_end value is defaulted '||p_date_end||' Repl by'||l_date_end);
428     v_date_end := l_date_end;
429  else
430     v_date_end := p_date_end;
431  End If;
432 
433  If (p_time_start = hr_api.g_varchar2) then
434 hr_utility.trace(' p_time_start value is defaulted '||p_time_start||' Repl by'||l_time_start);
435     v_time_start := l_time_start;
436  else
437     v_time_start := p_time_start;
438  End If;
439 
440  If (p_time_end = hr_api.g_varchar2) then
444     v_time_end := p_time_end;
441 hr_utility.trace(' p_time_end value is defaulted '||p_time_end||' Repl by'||l_time_end);
442     v_time_end := l_time_end;
443  else
445  End If;
446 
447 --7287548 end
448 
449 
450     -- Bug 6708992
451     -- Raise error if overlapping absences of same type are present
452   -- Bug 6888892 begin
453   -- To check only in case below mentioned absence categories also
454   -- changed the check to be based on Absence Category
455     if l_abs_category in ('S','M','GB_ADO','GB_PAT_BIRTH','GB_PAT_ADO') then
456     hr_utility.trace(' calling check_abs_overlap');
457     check_abs_overlap( l_person_id, v_date_start, v_date_end
458                     ,v_time_start, v_time_end, p_absence_attendance_id
459                    -- ,l_abs_type_id) ;
460                     ,l_abs_category);
461     hr_utility.trace(' After check_abs_overlap ');
462     end if;
463   -- Bug 6888892 begin
464 
465   END IF;
466 hr_utility.trace('Leaving  validate_abs_update ');
467 END validate_abs_update;
468 
469 -------------------------------------------------------------------------------
470 -- VALIDATE_ABS_DELETE
471 -------------------------------------------------------------------------------
472 PROCEDURE validate_abs_delete(p_absence_attendance_id   IN NUMBER
473                             ) IS
474 
475 
476 
477 CURSOR get_abs_category IS
478 SELECT paat.absence_category
479 FROM   per_absence_attendance_types paat,
480        per_absence_attendances paa
481 WHERE  paa.absence_attendance_id = p_absence_attendance_id
482 AND    paa.absence_attendance_type_id = paat.absence_attendance_type_id;
483 
484 
485     CURSOR csr_absences IS
486     SELECT 1
487     FROM   per_absence_attendances PAA
488     WHERE  PAA.absence_attendance_id  = p_absence_attendance_id
489     AND    PAA.sickness_start_date is not null
490     AND    PAA.sickness_start_date <   (select max(ABS.sickness_start_date)
491                                         from per_absence_attendances ABS
492 				        where ABS.person_id =PAA.person_id);
493 
494     l_absence       NUMBER;
495     l_abs_category per_absence_attendance_types.absence_category%TYPE;
496 
497     --
498 BEGIN
499   --
500   -- Added for GSI Bug 5472781
501   --
502   hr_utility.trace(' Entering PER_GB_ABSENCE_RULES.VALIDATE_ABS_DELETE ');
503   IF hr_utility.chk_product_install('Oracle Human Resources', 'GB') THEN
504      --
505      -- Get absence_category
506      --
507      hr_utility.trace('PER_GB_ABSENCE_RULES.VALIDATE_ABS_DELETE : Fetching absence category');
508      OPEN get_abs_category;
509      FETCH get_abs_category INTO l_abs_category;
510      CLOSE get_abs_category;
511      hr_utility.trace('PER_GB_ABSENCE_RULES.VALIDATE_ABS_DELETE : absence category :'||l_abs_category);
512 
513    IF l_abs_category = 'S' THEN
514         OPEN csr_absences;
515         FETCH csr_absences INTO l_absence;
516         if  csr_absences%found then
517 	        close csr_absences;
518 		hr_utility.set_message(804,'SSP_35037_PIW_BROKEN');
519 		hr_utility.raise_error;
520         else
521 	    close csr_absences;
522        end if;
523   END IF;
524  END IF;
525  hr_utility.trace(' Leaving PER_GB_ABSENCE_RULES.VALIDATE_ABS_DELETE ');
526 END validate_abs_delete;
527 --
528 END per_gb_absence_rules;