1 package body SSP_PAB_PKG as
2 /*$Header: sppabapi.pkb 120.5.12010000.2 2009/07/27 13:56:00 npannamp ship $
3 +==============================================================================+
4 | Copyright (c) 1994 Oracle Corporation |
5 | Redwood Shores, California, USA |
6 | All rights reserved. |
7 +==============================================================================+
8 --
9 Name
10 Statutory Paternity Pay (Birth) Business Process
11 --
12 Purpose
13 To perform calculation of entitlement and payment for PAB purposes
14 --
15 History
16 17 Oct 02 2690305 A Blinko Created from SSP_SMP_PKG
17 10 Jan 03 A Blinko Amended latest_ppp_start_date
18 27 Jan 03 G Butler nocopy fix - added 2nd dummy variable to
19 average_earnings to act as placeholder
20 for OUT param from ssp_ern_ins
21 01 Feb 03 2774903 A Blinko Fixed check_death procedure
22 11 Feb 03 2772479 A Blinko Late Absence Notification stoppage no
23 no longer created
24 24 Oct 03 3208325 A Blinko Replaced hardcoded SATURDAY and
25 SUNDAY references
26 16 Mar 04 3509432 npershad Modified the call to create_stoppage
27 procedure to rectify misleading stoppage
28 date for 'Some work done' stoppage.
29 29 Mar 04 3516539 skhandwa Added condition in the cursor to fetch
30 termination date for latest assignment
31 07 Jun 04 3598838 A Blinko Now only first absence is recognised
32 12 Jul 04 3682122 A Blinko Changes for recalculating lump sum
33 updates
34 14 Mar 05 4226911 npershad Modified the cursor csr_no_of_absences in
35 procedure generate_payments to get a correct
36 count of absence records.
37 18 Oct 05 4670360 KThampan Amended parameter's order of function
38 LATEST_PPP_START_DATE
39 09 Feb 06 4891953 Kthampan Fixed performance bug.
40 23 Aug 06 5482199 KThampan Change from per_people_f and per_assignments_f
41 to per_all_people_f and per_all_assignments_f
42 19 Spe 06 5547703 KThampan Amend pab_control to call generate_payments
43 with insert-mode if absence is > 0 and
44 also change csr_check_if_existing_entries
45 not to reference from per_absence_attendances
46 table
47 26 Jul 09 8692219 npannamp Changed the To_Date function to
48 fnd_date.chardate_to_date function in
49 the cursor csr_existing_entries.
50 */
51 --------------------------------------------------------------------------------
52 g_package varchar2(33) := ' ssp_pab_pkg.'; -- Global package name
53 --
54 cursor csr_absence_details (p_maternity_id in number) is
55 --
56 -- Get details of the initial paternity leave for a paternity
57 --
58 select absence.absence_attendance_id,
59 absence.date_start,
60 nvl (absence.date_end, hr_general.end_of_time) date_end,
61 absence.date_notification,
62 absence.accept_late_notification_flag
63 from
64 per_absence_attendances ABSENCE
65 where absence.maternity_id = p_maternity_id
66 and absence.absence_attendance_id =
67 (select min(paa_tab.absence_attendance_id)
68 from per_absence_attendances paa_tab
69 where paa_tab.maternity_id = absence.maternity_id);
70 --
71 --------------------------------------------------------------------------------
72 cursor csr_personal_details (p_maternity_id in number) is
73 --
74 -- Get details of the paternal person
75 --
76 select maternity.person_id,
77 maternity.due_date,
78 ssp_pab_pkg.qualifying_week (due_date) QW,
79 ssp_pab_pkg.expected_week_of_confinement (due_date) EWC,
80 maternity.maternity_id,
81 maternity.actual_birth_date,
82 maternity.live_birth_flag,
83 maternity.start_date_with_new_employer,
84 maternity.MPP_start_date APP_start_date,
85 maternity.notification_of_birth_date,
86 maternity.start_date_maternity_allowance,
87 maternity.pay_SMP_as_lump_sum pay_PAB_as_lump_sum,
88 person.date_of_death,
89 service.date_start,
90 nvl (service.final_process_date, hr_general.end_of_time) FINAL_PROCESS_DATE
91 from ssp_maternities MATERNITY,
92 per_all_people_f PERSON,
93 per_periods_of_service SERVICE
94 where person.person_id = maternity.person_id
95 and person.person_id = service.person_id
96 and maternity.maternity_id = p_maternity_id
97 and service.date_start between person.effective_start_date
98 and person.effective_end_date
99 and service.date_start = (select max(serv.date_start)
100 from per_periods_of_service serv
101 where serv.person_id = person.person_id);
102 --------------------------------------------------------------------------------
103 person csr_personal_details%rowtype;
104 g_PAB_element csr_PAB_element_details%rowtype;
105 g_PAB_Correction_element csr_PAB_element_details%rowtype;
106 --------------------------------------------------------------------------------
107 l_sunday varchar2(100) := to_char(to_date('07/01/2001','DD/MM/YYYY'),'DAY');
108
109 function QUALIFYING_WEEK (p_due_date in date) return date is
110 --
111 -- Returns the date on which the QW starts
112 --
113 -- QW is the EWC minus the QW weeks from the PAB element
114 --
115 l_QW date;
116 l_PAB_element csr_PAB_element_details%rowtype;
117 --
118 begin
119 --
120 open csr_PAB_element_details (p_due_date,c_PAB_element_name);
121 fetch csr_PAB_element_details into l_PAB_element;
122 close csr_PAB_element_details;
123 --
124 l_QW := expected_week_of_confinement(p_due_date)
125 - l_PAB_element.qualifying_week;
126 --
127 return l_QW;
128 --
129 end QUALIFYING_WEEK;
130 --------------------------------------------------------------------------------
131 Function CONTINUOUS_EMPLOYMENT_DATE (p_due_date in date)
132 return date is
133 --
134 -- The continuous employment start date is the date on which the person must
135 -- have been employed (and continuously from then to the MW) in order to
136 -- qualify for SAP. It is the MW minus the continuous employment period
137 -- specified on the SAP element.
138 -- A woman must have started work on or before the last day of the
139 -- week which starts 182 days (26 weeks) before the last day of the MW. In
140 -- SAP weeks start on Sunday and end on Saturday.
141 --
142 l_PAB_element csr_PAB_element_details%rowtype;
143 l_Continuously_employed_since date;
144 l_saturday varchar2(100) := to_char(to_date('06/01/2001','DD/MM/YYYY'),'DAY');
145 --
146 begin
147 --
148 open csr_PAB_element_details (p_due_date,c_PAB_element_name);
149 fetch csr_PAB_element_details into l_PAB_element;
150 close csr_PAB_element_details;
151 --
152 l_Continuously_employed_since :=
153 next_day(next_day(
154 QUALIFYING_WEEK(p_due_date) ,l_saturday)
155 - (l_PAB_element.continuous_employment_period),l_saturday);
156 --
157 return l_Continuously_employed_since;
158 --
159 end continuous_employment_date;
160 --------------------------------------------------------------------------------
161 procedure get_PAB_correction_element (p_effective_date in date) is
162 --
163 l_proc varchar2(72) := g_package||'get_PAB_correction_element';
164 --
165 procedure check_parameters is
166 begin
167 --
168 hr_utility.trace (l_proc||' p_effective_date = '
169 ||to_char (p_effective_date));
170 --
171 hr_api.mandatory_arg_error (
172 p_api_name => l_proc,
173 p_argument => 'effective_date',
174 p_argument_value=> p_effective_date);
175 end check_parameters;
176 --
177 begin
178 --
179 hr_utility.set_location (l_proc,1);
180 --
181 check_parameters;
182 --
183 open csr_PAB_element_details (p_effective_date,c_PAB_corr_element_name);
184 fetch csr_PAB_element_details into g_PAB_Correction_element;
185 close csr_PAB_element_details;
186 --
187 hr_utility.set_location (l_proc,100);
188 --
189 end get_PAB_correction_element;
190 --------------------------------------------------------------------------------
191 procedure get_PAB_element (p_effective_date in date) is
192 --
193 l_proc varchar2(72) := g_package||'get_PAB_element';
194 --
195 procedure check_parameters is
196 begin
197 --
198 hr_utility.trace (l_proc||' p_effective_date = '
199 ||to_char (p_effective_date));
200 --
201 hr_api.mandatory_arg_error (
202 p_api_name => l_proc,
203 p_argument => 'effective_date',
204 p_argument_value=> p_effective_date);
205 end check_parameters;
206 --
207 begin
208 --
209 hr_utility.set_location (l_proc,1);
210 --
211 check_parameters;
212 --
213 open csr_PAB_element_details (p_effective_date,c_PAB_element_name);
214 fetch csr_PAB_element_details into g_PAB_element;
215 close csr_PAB_element_details;
216 --
217 hr_utility.set_location (l_proc,100);
218 --
219 end get_PAB_element;
220 --------------------------------------------------------------------------------
221 function EARLIEST_PPP_START_DATE (p_birth_date in date) return date is
222 --
223 -- The earliest PPP start date, under normal circumstances is the
224 -- child expected date minus
225 -- the number of weeks specified on the SAP element for earliest SAP start
226 --
227 l_earliest_PPP_start date;
228 l_PAB_element csr_PAB_element_details%rowtype;
229 --
230 begin
231 --
232 open csr_PAB_element_details (p_birth_date,c_PAB_element_name);
233 fetch csr_PAB_element_details into l_PAB_element;
234 close csr_PAB_element_details;
235 --
236 l_earliest_PPP_start := p_birth_date
237 - (l_PAB_element.earliest_start_of_PPP);
238 --
239 return l_earliest_PPP_start;
240 --
241 end earliest_PPP_start_date;
242 --------------------------------------------------------------------------------
243 function LATEST_PPP_START_DATE (p_birth_date in date,
244 p_ewc in date,
245 p_due_date in date) return date is
246 --
247 l_latest_PPP_start date;
248 l_PAB_element csr_PAB_element_details%rowtype;
249 --
250 begin
251 --
252 open csr_PAB_element_details (p_birth_date,c_PAB_element_name);
253 fetch csr_PAB_element_details into l_PAB_element;
254 close csr_PAB_element_details;
255 --
256 if p_birth_date < p_due_date then
257 l_latest_PPP_start := greatest(p_birth_date,p_ewc)
258 + (l_PAB_element.latest_end_of_PPP - 7);
259 else
260 l_latest_PPP_start := p_birth_date + (l_PAB_element.latest_end_of_PPP - 7);
261 end if;
262 --
263 return l_latest_PPP_start;
264 --
265 end latest_ppp_start_date;
266 --------------------------------------------------------------------------------
267 function expected_week_of_confinement (p_due_date in date) return date is
268 --
269 l_ewc date;
270 --
271 begin
272 --
273 l_ewc := (next_day(p_due_date,l_sunday)-7);
274 --
275 return l_ewc;
276 --
277 end expected_week_of_confinement;
278 --------------------------------------------------------------------------------
279 function MATERNITY_RECORD_EXISTS (p_person_id in number) return boolean is
280 --
281 cursor maternity_record is
282 select 1
283 from ssp_maternities
284 where person_id = p_person_id;
285 --
286 l_dummy number (1);
287 l_maternity_record_exists boolean;
288 --
289 begin
290 --
291 open maternity_record;
292 fetch maternity_record into l_dummy;
293 l_maternity_record_exists := maternity_record%found;
294 close maternity_record;
295 --
296 return l_maternity_record_exists;
297 --
298 end maternity_record_exists;
299 --------------------------------------------------------------------------------
300 function AVERAGE_EARNINGS return number is
301 --
302 l_average_earnings number := null;
303 l_effective_date date := null;
304 l_dummy number;
305 l_dummy2 number; -- nocopy fix, placeholder variable
306 l_user_entered varchar2(30) := 'N'; --DFoster 1304683
307 l_absence_category varchar2(30) := 'GB_PAT_BIRTH'; --DFoster 1304683
308 l_payment_periods number := null; --DFoster 1304683
309 l_proc varchar2(72) := g_package||'average_earnings';
310 --
311 cursor csr_average_earnings is
312 select average_earnings_amount
313 from ssp_earnings_calculations
314 where person_id = person.person_id
315 and effective_date = l_effective_date;
316 --
317 begin
318 --
319 hr_utility.set_location ('Entering '||l_proc,1);
320 --
321 l_effective_date := greatest(person.QW, person.date_start);
322 --
323 open csr_average_earnings;
324 fetch csr_average_earnings into l_average_earnings;
325 --
326 if csr_average_earnings%notfound
327 then
328 ssp_ern_ins.ins (p_earnings_calculations_id => l_dummy,
329 p_object_version_number => l_dummy2,
330 p_person_id => person.person_id,
331 p_effective_date => l_effective_date,
332 p_average_earnings_amount => l_average_earnings,
333 p_user_entered => l_user_entered, --DFoster 1304683
334 p_absence_category => l_absence_category, --DFoster 1304683
335 p_payment_periods => l_payment_periods); --DFoster 1304683
336 end if;
337 --
338 close csr_average_earnings;
339 --
340 hr_utility.set_location ('Leaving '||l_proc,10);
341 --
342 return l_average_earnings;
343 --
344 end average_earnings;
345 --------------------------------------------------------------------------------
346 function entitled_to_PAB (p_maternity_id in number) return boolean is
347 --
348 -- See header for description of this procedure.
349 --
350 no_prima_facia_entitlement exception;
351 invalid_absence_date exception;
352 l_work_start_date date := hr_general.end_of_time;
353 stoppage_end_date date := null;
354 no_of_absence_periods integer := 0;
355 l_proc varchar2(72) := g_package||'entitled_to_PAB';
356 l_keep_stoppages boolean default FALSE;
357 --
358 cursor csr_no_of_absences is
359 --
360 select count (*)
361 from per_absence_attendances
362 where person_id = person.person_id
363 and maternity_id = p_maternity_id
364 and absence_attendance_id =
365 (select min(paa_tab.absence_attendance_id)
366 from per_absence_attendances paa_tab
367 where paa_tab.maternity_id = p_maternity_id);
368 --
369 -- returns entries associated with a maternity_id.
370 cursor csr_check_if_existing_entries is
371 --
372 select /*+ ORDERED use_nl(paa,paaf,etype,entry) */
373 entry.element_entry_id,
374 entry.effective_start_date
375 from per_all_assignments_f PAAF,
376 pay_element_types_f ETYPE,
377 pay_element_entries_f ENTRY
378 where PAAF.person_id = person.person_id
379 and ETYPE.element_name = c_PAB_element_name
380 and ETYPE.legislation_code = 'GB'
381 and ENTRY.element_type_id = ETYPE.element_type_id
382 and ENTRY.creator_type = c_PAB_creator_type
383 and ENTRY.creator_id = p_maternity_id
384 and ENTRY.assignment_id = PAAF.assignment_id
385 and not exists (
386 --
387 -- Do not select entries which have already had reversal action
388 -- taken against them because they are effectively cancelled out.
389 --
390 select 1
391 from pay_element_entries_f ENTRY2
392 where entry.element_entry_id= entry2.target_entry_id
393 and entry.assignment_id = entry2.assignment_id)
394 --
395 and not exists (
396 --
397 -- Do not select reversal entries
398 --
399 select 1
400 from pay_element_links_f LINK,
401 pay_element_types_f TYPE
402 where link.element_link_id = entry.element_link_id
403 and entry.effective_start_date between link.effective_start_date and link.effective_end_date
404 and link.element_type_id = type.element_type_id
405 and link.effective_start_date between type.effective_start_date and type.effective_end_date
406 and type.element_name = c_PAB_corr_element_name);
407 --
408 l_existing_entries csr_check_if_existing_entries%rowtype;
409 --
410 procedure create_stoppage (
411 --
412 -- Create a stoppage of payment for PAB
413 --
414 p_reason in varchar2,
415 p_withhold_from in date,
416 p_withhold_to in date default null) is
417 --
418 l_proc varchar2(72) := g_package||'create_stoppage';
419 l_dummy number;
420 l_reason_id number;
421 --
422 procedure check_parameters is
423 --
424 begin
425 --
426 hr_utility.trace (l_proc||' p_reason = '||p_reason);
427 hr_utility.trace (l_proc||' withhold from '||to_char (p_withhold_from));
428 hr_utility.trace (l_proc||' withhold to '||to_char (p_withhold_to));
429 --
430 hr_api.mandatory_arg_error (
431 p_api_name => l_proc,
432 p_argument => 'reason',
433 p_argument_value=> p_reason);
434 --
435 hr_api.mandatory_arg_error (
436 p_api_name => l_proc,
437 p_argument => 'withhold_from',
438 p_argument_value=> p_withhold_from);
439 --
440 end check_parameters;
441 --
442 begin
443 --
444 hr_utility.set_location (l_proc,1);
445 --
446 check_parameters;
447 --
448 l_reason_id := ssp_smp_support_pkg.withholding_reason_id (
449 g_PAB_element.element_type_id,
450 p_reason);
451 --
452 if not ssp_smp_support_pkg.stoppage_overridden (
453 p_maternity_id => p_maternity_id,
454 p_reason_id => l_reason_id)
455 then
456 --
457 -- Only create the stoppage if there is not already a stoppage marked
458 -- as over--ridden. Thus, overriding a stoppage effectively blocks that
459 -- reason being used to withhold payment for this person.
460 --
461 ssp_stp_ins.ins (p_withhold_from => p_withhold_from,
462 p_withhold_to => p_withhold_to,
463 p_stoppage_id => l_dummy,
464 p_object_version_number => l_dummy,
465 p_maternity_id => p_maternity_id,
466 p_user_entered => 'N',
467 p_reason_id => l_reason_id);
468 else
469 hr_utility.trace (l_proc||' Stoppage is overridden');
470 end if;
471 --
472 hr_utility.set_location (l_proc,100);
473 --
474 end create_stoppage;
475 --
476 procedure remove_stoppages is
477 --
478 -- Remove old system, non-overridden stoppages
479 --
480 cursor csr_stoppages is
481 select stoppage_id
482 from ssp_stoppages
483 where user_entered <>'Y'
484 and override_stoppage <> 'Y'
485 and maternity_id = p_maternity_id;
486 --
487 l_dummy number;
488 l_proc varchar2 (72) := g_package||'remove_stoppages';
489 --
490 begin
491 --
492 hr_utility.set_location (l_proc,1);
493 --
494 for each_stoppage in csr_stoppages LOOP
495 ssp_stp_del.del (p_stoppage_id => each_stoppage.stoppage_id,
496 p_object_version_number => l_dummy);
497 end loop;
498 --
499 hr_utility.set_location (l_proc,100);
500 --
501 end remove_stoppages;
502 --
503 procedure check_employment_end is
504
505 cursor csr_termination_date is
506 select actual_termination_date
507 from per_periods_of_service
508 where person_id = person.person_id
509 -- 3516539 Added condition to obtain termination date for latest assignment
510 and period_of_service_id = (select max(period_of_service_id)
511 from per_periods_of_service ppos
512 where ppos.person_id = person.person_id);
513 --
514 l_termination_date date := null;
515 l_proc varchar2(72) := g_package||'check_employment_end';
516 --
517 begin
518 --
519 hr_utility.set_location (l_proc,1);
520 --
521 open csr_termination_date;
522 fetch csr_termination_date into l_termination_date;
523 close csr_termination_date;
524 --
525 if l_termination_date < person.actual_birth_date then
526 --
527 -- Stop all PAB payment for the Birth because the person left
528 -- before the PPP start date.
529 --
530 create_stoppage (p_withhold_from => person.actual_birth_date,
531 p_reason => 'Not employed on Birth Date');
532 end if;
533 --
534 hr_utility.set_location (l_proc,100);
535 --
536 end check_employment_end;
537 --
538 procedure check_continuity_rule is
539 --
540 -- Check that the person has the right amount of continuous service to
541 -- qualify for SAP
542 --
543 cursor period_of_service is
544 --
545 -- Check the period of service length up to the MW start date
546 --
547 select 1
548 from per_periods_of_service
549 where person_id = person.person_id
550 and date_start <= ssp_pab_pkg.continuous_employment_date(person.due_date)
551 and nvl (actual_termination_date, hr_general.end_of_time) >= person.QW;
552 --
553 l_dummy number (1);
554 l_proc varchar2 (72) := g_package||'check_continuity_rule';
555 --
556 begin
557 --
558 hr_utility.set_location (l_proc,1);
559 --
560 open period_of_service;
561 fetch period_of_service into l_dummy;
562 --
563 if period_of_service%notfound then
564 --
565 -- Stop all SAP payment for the Adoption because the person has not
566 -- been continuously employed for long enough.
567 --
568 create_stoppage (p_withhold_from => person.APP_start_date,
569 p_reason => 'Insufficient employment');
570 end if;
571 --
572 close period_of_service;
573 --
574 hr_utility.set_location (l_proc,100);
575 --
576 end check_continuity_rule;
577 --
578 procedure check_start_date is
579
580 l_proc varchar2 (72) := g_package||'check_start_date';
581 --
582 l_latest_PPP_start date;
583 l_PAB_element csr_PAB_element_details%rowtype;
584 --
585 begin
586 --
587 hr_utility.set_location (l_proc,1);
588 --
589 open csr_PAB_element_details (person.actual_birth_date,c_PAB_element_name);
590 fetch csr_PAB_element_details into l_PAB_element;
591 close csr_PAB_element_details;
592 --
593 if person.app_start_date > greatest(person.ewc,person.actual_birth_date)
594 + (l_PAB_element.latest_end_of_PPP - 14)
595 then
596
597 create_stoppage (p_withhold_from => person.APP_start_date + 7,
598 p_reason => 'Max PPP Period Exceeded');
599
600 end if;
601 --
602 hr_utility.set_location (l_proc,100);
603 --
604 end check_start_date;
605
606 procedure check_stillbirth is
607 --
608 -- Check the pregnancy condition for qualification for PAB
609 --
610 l_proc varchar2 (72) := g_package||'check_stillbirth';
611 --
612 begin
613 --
614 hr_utility.set_location (l_proc,1);
615 --
616 -- Woman must be still pregnant, have had a live birth, or have had a
617 -- stillbirth after the threshhold week to be eligible for PAB
618 --
619 if NOT (person.actual_birth_date is null
620 or person.live_birth_flag = 'Y'
621 or person.actual_birth_date > person.EWC
622 - g_PAB_element.stillbirth_threshold_week)
623 then
624 --
625 -- Stop SMP payment from the start of the week in which the absence
626 -- started.
627 --
628 create_stoppage (p_withhold_from => person.APP_start_date,
629 p_reason => 'Stillbirth');
630 end if;
631 --
632 hr_utility.set_location (l_proc,100);
633 --
634 end check_stillbirth;
635 --
636 procedure check_new_employer is
637 --
638 -- Check the person has not been employed by a new employer after the
639 -- child placement
640 --
641 l_proc varchar2 (72) := g_package||'check_new_employer';
642 --
643 begin
644 --
645 hr_utility.set_location (l_proc,1);
646 --
647 if person.start_date_with_new_employer >= person.actual_birth_date then
648 --
649 -- Stop SAP payment from the start of the week in which the person
650 -- started work for a new employer after the placement of her child.
651 --
652 create_stoppage (p_withhold_from => ssp_smp_support_pkg.start_of_week
653 (person.start_date_with_new_employer),
654 p_reason => 'Worked for another employer');
655 end if;
656 --
657 hr_utility.set_location (l_proc,100);
658 --
659 end check_new_employer;
660 --
661 procedure check_maternity_allowance is
662 --
663 -- SAP ceases when SMA starts.
664 --
665 l_proc varchar2 (72) := g_package||'check_maternity_allowance';
666 --
667 begin
668 --
669 hr_utility.set_location (l_proc,1);
670 --
671 if person.start_date_maternity_allowance is not null then
672 --
673 -- Stop SAP payment from the start of the week in which SMA was first
674 -- paid.
675 --
676 create_stoppage (p_withhold_from => ssp_smp_support_pkg.start_of_week
677 (person.start_date_maternity_allowance),
678 p_reason => 'Employee is receiving SMA');
679 end if;
680 --
681 hr_utility.set_location (l_proc,100);
682 --
683 end check_maternity_allowance;
684 --
685 procedure check_death is
686 --
687 -- PAB ceases after the death of the person.
688 --
689 l_proc varchar2 (72) := g_package||'check_death';
690 --
691 cursor csr_check_death is
692 select ppf.date_of_death
693 from per_all_people_f ppf
694 where ppf.person_id = person.person_id
695 and ppf.date_of_death is not null;
696 --
697 l_death_date date;
698 --
699 begin
700 --
701 hr_utility.set_location (l_proc,1);
702 --
703 -- PAB ceases on the Saturday following death
704 --
705 l_death_date := null;
706 --
707 open csr_check_death;
708 fetch csr_check_death into l_death_date;
709 close csr_check_death;
710 --
711 if l_death_date is not null then
712 create_stoppage (p_withhold_from => next_day (l_death_date,
713 l_sunday),
714 p_reason => 'Employee died');
715 end if;
716 --
717 hr_utility.set_location (l_proc,100);
718 --
719 end check_death;
720 --
721 procedure check_average_earnings is
722 --
723 -- The person must earn enough to qualify for SAP
724 --
725 l_proc varchar2 (72) := g_package||'check_average_earnings';
726 l_average_earnings number := average_earnings;
727 l_reason_for_no_earnings varchar2 (80) := null;
728 earnings_not_derived exception;
729 --
730 begin
731 --
732 hr_utility.set_location (l_proc,1);
733 --
734 if l_average_earnings = 0
735 then
736 --
737 -- If the average earnings figure returned is zero then check that
738 -- no error message was set. Error messages will be set for system-
739 -- generated average earnings when the earnings could not be derived
740 -- for some reason, but to allow this procedure to continue, no error
741 -- will be raised.
742 --
743 l_reason_for_no_earnings:=ssp_smp_support_pkg.average_earnings_error;
744 --
745 if l_reason_for_no_earnings is not null then
746 create_stoppage (p_withhold_from => person.aPP_start_date,
747 p_reason => l_reason_for_no_earnings);
748 --
749 raise earnings_not_derived;
750 end if;
751 end if;
752 --
753 if l_average_earnings
754 < ssp_smp_support_pkg.NI_Lower_Earnings_Limit (person.QW)
755 then
756 --
757 -- Stop SAP payment from the APP start date
758 --
759 create_stoppage (p_withhold_from => person.APP_start_date,
760 p_reason => 'Earnings too low');
761 end if;
762 --
763 hr_utility.set_location (l_proc,100);
764 --
765 exception
766 --
767 when earnings_not_derived then
768 --
769 -- Exit silently from this procedure
770 --
771 hr_utility.trace (l_proc||' Earnings not derived');
772 null;
773 --
774 end check_average_earnings;
775 --
776 procedure check_birth_confirmation is
777 --
778 -- Check that confirmation of birth was received in good time.
779 --
780 l_proc varchar2 (72) := g_package||'check_birth_confirmation';
781 --
782 begin
783 --
784 hr_utility.set_location (l_proc,1);
785 --
786 hr_utility.set_location (l_proc,100);
787 --
788 end check_birth_confirmation;
789 --
790 procedure check_parameters is
791 --
792 begin
793 --
794 hr_utility.trace (l_proc||' p_maternity_id = '
795 ||to_char (p_maternity_id));
796 --
797 hr_api.mandatory_arg_error (
798 p_api_name => l_proc,
799 p_argument => 'maternity_id',
800 p_argument_value=> p_maternity_id);
801 --
802 end check_parameters;
803 --
804 begin
805 --
806 hr_utility.set_location (l_proc,1);
807 --
808 check_parameters;
809 --
810 -- Get the details of the woman and her maternity.
811 --
812 open csr_personal_details (p_maternity_id);
813 fetch csr_personal_details into person;
814 --
815 if csr_personal_details%notfound
816 then
817 --
818 -- If no maternity record exists then there can be no entitlement to SAP
819 --
820 close csr_personal_details;
821 --
822 hr_utility.trace (l_proc||' Person has no maternity record - exiting');
823 --
824 raise no_prima_facia_entitlement;
825 end if;
826 --
827 close csr_personal_details;
828 --
829 if person.APP_start_date is null then
830 --
831 -- If the APP has not started then there is no entitlement to SAP.
832 --
833 hr_utility.trace (l_proc||' Person has no APP start date - exiting');
834 --
835 raise no_prima_facia_entitlement;
836 end if;
837 --
838 -- Count how many absences there are for the maternity.
839 --
840 open csr_no_of_absences;
841 fetch csr_no_of_absences into no_of_absence_periods;
842 close csr_no_of_absences;
843 --
844 if no_of_absence_periods = 0
845 then
846 --
847 -- check if entries exist despite there being no absence
848 --
849 open csr_check_if_existing_entries;
850 fetch csr_check_if_existing_entries into l_existing_entries;
851 --
852 if csr_check_if_existing_entries%NOTFOUND
853 then
854 hr_utility.trace (l_proc||' Person has not stopped work - exiting');
855 raise no_prima_facia_entitlement;
856 end if;
857 --
858 -- if entries are found then the absence has been deleted and entries remain
859 -- that must be dealt with
860 --
861 while csr_check_if_existing_entries%FOUND LOOP
862 fetch csr_check_if_existing_entries into l_existing_entries;
863 end loop;
864 --
865 close csr_check_if_existing_entries;
866 l_keep_stoppages := TRUE;
867 end if;
868 --
869 -- Having established a prima facia entitlement to SAP, perform checks which
870 -- may lead to creation of stoppages for particular periods.
871 --
872 hr_utility.set_location ('ssp_smp_pkg.entitled_to_PAB',2);
873 --
874 -- Get the SAP legislative parameters.
875 --
876 get_PAB_element (person.due_date);
877 --
878 -- Clear stoppages created by previous calculations of SAP but if an absence
879 -- is being deleted, then must keep stoppages so that when later comparison of
880 -- old_entry and hypothetical_entry is done then stoppages are still there.
881 --
882 if not l_keep_stoppages then
883 remove_stoppages;
884 end if;
885 --
886 for absence in csr_absence_details (p_maternity_id) LOOP
887 --
888 -- Check that sufficient notification of absence was given
889 --
890 -- if notification of absence was later than the allowed date
891 -- and there was no acceptable reason for the delay
892 -- or notification of absence was later than the extended allowable date
893 --
894 if (absence.date_notification > absence.date_start
895 - g_PAB_element.MPP_notice_requirement
896 and absence.accept_late_notification_flag = 'N')
897 or (absence.date_notification > person.actual_birth_date
898 + g_PAB_element.MPP_notice_requirement)
899 then
900 --
901 -- Stop SAP payment from the start of the week in which the absence
902 -- starts, to the end of the notice period
903 --
904 stoppage_end_date := g_PAB_element.MPP_notice_requirement
905 + absence.date_start - 1;
906 --
907 /* Bug 2772479 - Stoppage no longer required but may be reintroduced
908
909 create_stoppage (
910 p_withhold_from => ssp_smp_support_pkg.start_of_week
911 (absence.date_start),
912 p_withhold_to => ssp_smp_support_pkg.end_of_week (stoppage_end_date),
913 p_reason => 'Late absence notification');
914 */
915 end if;
916 --
917 hr_utility.set_location ('ssp_sap_pkg.entitled_to_SaP',3);
918 --
919 -- Check for any work done during the APP.
920 --
921 -- Check if this is the first absence period in the APP
922 -- and the absence starts after the APP start date
923 if csr_absence_details%rowcount = 1
924 and absence.date_start > person.APP_start_date
925 then
926 create_stoppage (p_reason => 'Some work was done',
927 p_withhold_from => person.APP_start_date,
928 p_withhold_to => ssp_smp_support_pkg.end_of_week
929 (absence.date_start -1));
930 end if;
931 --
932 -- If this is the last absence period in the MPP
933 -- and the absence period ends before the end of the MPP
934 --
935 if csr_absence_details%rowcount = no_of_absence_periods
936 and absence.date_end < (g_PAB_element.maximum_PPP_weeks * 7)
937 + person.APP_start_date
938 then
939
940
941 --Commented code for Bug Fix 3509432
942 /* create_stoppage (p_reason => 'Some work was done',
943 p_withhold_from => ssp_smp_support_pkg.start_of_week
944 (absence.date_end+1));*/
945
946 --Bug 3509432 start
947 --Only one week is paid, if absence is for > 1 week but < 2 weeks
948 if (absence.date_end - absence.date_start) + 1 > 7 and (absence.date_end - absence.date_start) + 1 < 14 then
949
950 create_stoppage (p_reason => 'Some work was done',
951 p_withhold_from => person.APP_start_date + 7);
952
953 --no weeks are paid,if absence < 1 week
954 elsif (absence.date_end - absence.date_start) + 1 < 7 then
955
956 create_stoppage (p_reason => 'Some work was done',
957 p_withhold_from => person.APP_start_date);
958
959 elsif (absence.date_end - absence.date_start) + 1 = 7 then
960
961 create_stoppage (p_reason => 'Some work was done',
962 p_withhold_from => person.APP_start_date + 7);
963
964 --no stoppage created if absence is equal to 2 weeks
965 elsif absence.date_start is not null and absence.date_end is not null then
966 if (absence.date_end - absence.date_start) + 1 = 14 then
967 null;
968 end if;
969 end if;
970
971 --Bug 3509432 End
972 elsif
973 -- there is a period of work between two absences
974 l_work_start_date < absence.date_start
975 and l_work_start_date < (g_PAB_element.maximum_PPP_weeks * 7)
976 + person.APP_start_date
977 then
978 create_stoppage (p_reason => 'Some work was done',
979 p_withhold_from => ssp_smp_support_pkg.start_of_week
980 (l_work_start_date),
981 p_withhold_to => ssp_smp_support_pkg.end_of_week
982 (absence.date_start -1));
983 --
984 if absence.date_end <> hr_general.end_of_time
985 then
986 l_work_start_date := absence.date_end + 1;
987 else
988 --
989 -- This is not the last absence in the maternity but it has no end date.
990 --
991 hr_utility.trace (l_proc||' ERROR: Invalid null absence end date');
992 --
993 raise invalid_absence_date;
994 end if;
995 end if;
996 end loop;
997 --
998 check_continuity_rule;
999 check_start_date;
1000 check_employment_end;
1001 check_stillbirth;
1002 check_new_employer;
1003 check_maternity_allowance;
1004 check_death;
1005 check_birth_confirmation;
1006 check_average_earnings;
1007 --
1008 -- If we get this far the person is entitled to SAP (though stoppages may apply)
1009 --
1010 return TRUE;
1011 --
1012 exception
1013 --
1014 when invalid_absence_date then
1015 fnd_message.set_name ('PAY', 'HR_6153_ALL_PROCEDURE_FAIL');
1016 fnd_message.set_token ('PROCEDURE','ssp_smp_pkg.entitled_to_PAB');
1017 fnd_message.set_token ('STEP','3');
1018 --
1019 when no_prima_facia_entitlement then
1020 --
1021 -- Exit silently; this will allow us to call this procedure with impunity
1022 -- from absences which are not maternity absences (e.g. via a row trigger)
1023 --
1024 return FALSE;
1025 --
1026 end entitled_to_PAB;
1027 --------------------------------------------------------------------------------
1028 procedure generate_payments(p_maternity_id in number,
1029 p_deleting in boolean default FALSE) is
1030 --
1031 type date_table is table of date index by binary_integer;
1032 type number_table is table of number index by binary_integer;
1033 type varchar_table is table of varchar2 (80) index by binary_integer;
1034 l_proc varchar2(72) := g_package||'generate_payments';
1035 --
1036 type PAB_entry is record (
1037 --
1038 element_entry_id number_table,
1039 element_link_id number_table,
1040 assignment_id number_table,
1041 effective_start_date date_table,
1042 effective_end_date date_table,
1043 amount number_table,
1044 rate varchar_table,
1045 week_commencing date_table,
1046 recoverable_amount number_table,
1047 stopped varchar_table,
1048 dealt_with varchar_table);
1049 --
1050 --
1051 -- A store for all the SAP entries that potentially may be
1052 -- granted to the person.
1053 --
1054 hypothetical_entry PAB_entry;
1055 --
1056 -- A tally of the number of weeks of the APP which are subject to stoppages.
1057 --
1058 l_stopped_weeks number := 0;
1059 --
1060 l_high_rate varchar2 (80) := null;
1061 l_low_rate varchar2 (80) := null;
1062 -- RT entries prob
1063 l_no_of_absence_periods integer := 0;
1064 --
1065 -- p_deleting passed into save_hypothetical_entries, so that logic can be
1066 -- dealt with for deleted absences.
1067 --
1068 procedure save_hypothetical_entries (p_deleting in boolean default false) is
1069 --
1070 -- Having generated the potential SAP entries, reconcile them with any
1071 -- previously granted entries for the same maternity.
1072 --
1073 cursor csr_existing_entries is
1074 --
1075 -- Get all entries and entry values for the Adoption
1076 --
1077 -- Decode the rate code to give the meaning using local variables
1078 -- populated earlier by Calculate_correct_SAP_rate
1079 -- these can then be passed directly into the hr_entry_api's and
1080 -- simplifies comparison with hypo entries
1081 --
1082 select entry.element_entry_id,
1083 entry.element_link_id,
1084 entry.assignment_id,
1085 entry.effective_start_date,
1086 entry.effective_end_date,
1087 -- if in future we get two different rates then a decode can be added here
1088 l_high_rate RATE,
1089 /* Bug Fix 8692219 begin
1090 to_date (ssp_smp_support_pkg.value
1091 (entry.element_entry_id,
1092 ssp_sap_pkg.c_week_commencing_name),
1093 'DD-MON-YYYY') WEEK_COMMENCING,
1094 */
1095 fnd_date.chardate_to_date(ssp_smp_support_pkg.value
1096 (entry.element_entry_id,
1097 ssp_sap_pkg.c_week_commencing_name)) WEEK_COMMENCING,
1098 -- Bug Fix 8692219 End
1099 to_number(ssp_smp_support_pkg.value (entry.element_entry_id,
1100 ssp_sap_pkg.c_amount_name)) AMOUNT,
1101 to_number(ssp_smp_support_pkg.value (entry.element_entry_id,
1102 ssp_sap_pkg.c_recoverable_amount_name)) RECOVERABLE_AMOUNT
1103 from pay_element_entries_f ENTRY,
1104 per_all_assignments_f asg
1105 where creator_type = c_PAB_creator_type
1106 and creator_id = p_maternity_id
1107 and asg.person_id = person.person_id
1108 and asg.assignment_id = entry.assignment_id
1109 and entry.effective_start_date between asg.effective_start_date
1110 and asg.effective_end_date
1111 and not exists (
1112 --
1113 -- Do not select entries which have already had reversal action taken
1114 -- against them because they are effectively cancelled out.
1115 --
1116 select 1
1117 from pay_element_entries_f ENTRY2
1118 where entry.element_entry_id= entry2.target_entry_id
1119 and entry.assignment_id = entry2.assignment_id)
1120 --
1121 and not exists (
1122 --
1123 -- Do not select reversal entries
1124 --
1125 select 1
1126 from pay_element_links_f LINK,
1127 pay_element_types_f TYPE
1128 where link.element_link_id = entry.element_link_id
1129 and entry.effective_start_date between link.effective_start_date
1130 and link.effective_end_date
1131 and link.element_type_id = type.element_type_id
1132 and link.effective_start_date between type.effective_start_date
1133 and type.effective_end_date
1134 and type.element_name = c_PAB_corr_element_name);
1135 --
1136 cursor csr_no_of_absences is
1137 --
1138 select count (*)
1139 from per_absence_attendances
1140 where person_id = person.person_id
1141 and maternity_id = p_maternity_id
1142 and absence_attendance_id =
1143 (select min(paa_tab.absence_attendance_id)
1144 from per_absence_attendances paa_tab
1145 where paa_tab.maternity_id = p_maternity_id); --Bug fix 4226911
1146
1147
1148 --
1149 l_ins_corr_ele boolean;
1150 l_dummy number;
1151 Entry_number integer;
1152 l_ern_calc_id number;
1153 l_ob_v_no number;
1154 l_new_ob_v_no number;
1155 l_proc varchar2 (72) := g_package||'save_hypothetical_entries';
1156 --
1157
1158
1159 -- This procedure was a private procedure in the function entitled_to_sap. I
1160 -- wanted to call it within this procedure (generate_payments) aswell, so
1161 -- instead of making it a public procedure I have copied the procedure to here.
1162 --
1163 procedure remove_stoppages is
1164 --
1165 -- Remove old system, non-overridden stoppages
1166 --
1167 cursor csr_stoppages is
1168 select stoppage_id
1169 from ssp_stoppages
1170 where user_entered <>'Y'
1171 and override_stoppage <> 'Y'
1172 and maternity_id = p_maternity_id;
1173 --
1174 l_dummy number;
1175 l_proc varchar2 (72) := g_package||'.remove_stoppages';
1176 --
1177 begin
1178 --
1179 hr_utility.set_location (l_proc,1);
1180 --
1181 for each_stoppage in csr_stoppages LOOP
1182 ssp_stp_del.del (p_stoppage_id => each_stoppage.stoppage_id,
1183 p_object_version_number => l_dummy);
1184
1185 end loop;
1186 --
1187 hr_utility.set_location (l_proc,100);
1188 --
1189 end remove_stoppages;
1190 --
1191 begin
1192 --
1193 hr_utility.set_location('Entering: '||l_proc,10);
1194 --
1195 get_PAB_correction_element (person.due_date);
1196 --
1197 -- Check each existing SaP entry in turn against all the potential new ones.
1198 --
1199 <<OLD_ENTRIES>>
1200 for old_entry in csr_existing_entries
1201 LOOP
1202 --First loop through the hypothetical entries to see if there is one
1203 --which covers the same week as the old entry and is not subject to
1204 --a stoppage. If there isn't one, invalidate the old entry.
1205 --Assume we don't need to correct the entry until we discover otherwise:
1206 --
1207 l_ins_corr_ele := FALSE;
1208 begin
1209 entry_number := 0;
1210 if p_deleting then
1211 raise no_data_found; -- enter exception handler
1212 end if;
1213 LOOP
1214 entry_number := entry_number +1;
1215 -- Exit the loop when we find a hypothetical entry covering the
1216 -- same week as the old entry, which is not subject to a stoppage.
1217 -- If no such match is found, then we will reach the end of the
1218 -- pl/sql table and attempt to read beyond the existing rows; this
1219 -- will cause us to enter the exception handler and indicate that
1220 -- no match was found.
1221 exit when ((old_entry.week_commencing
1222 = hypothetical_entry.week_commencing (entry_number)
1223 and not hypothetical_entry.stopped (entry_number) = 'TRUE'
1224 and ssp_smp_pkg.g_smp_update = 'N')
1225 or (old_entry.effective_start_date
1226 = hypothetical_entry.effective_start_date (entry_number)
1227 and old_entry.week_commencing
1228 = hypothetical_entry.week_commencing (entry_number)
1229 and not hypothetical_entry.stopped (entry_number) = 'TRUE'
1230 and ssp_smp_pkg.g_smp_update = 'Y'));
1231 end loop;
1232 hr_utility.trace (l_proc||' Old entry / Hypo entry time Match with values:');
1233 hr_utility.trace (l_proc||' Rate: ' ||old_entry.rate||' / '
1234 ||hypothetical_entry.rate (Entry_number));
1235 hr_utility.trace (l_proc||' Amount: '
1236 ||old_entry.amount||' / '
1237 ||hypothetical_entry.amount (entry_number));
1238 hr_utility.trace (l_proc||' Recoverable: '
1239 ||old_entry.recoverable_amount||' / '
1240 ||hypothetical_entry.recoverable_amount (entry_number));
1241 hr_utility.trace (l_proc||' Week Comm: '
1242 ||hypothetical_entry.week_commencing (entry_number) );
1243 --A hypo entry covers the same week as the old one
1244 if old_entry.rate = hypothetical_entry.rate (entry_number)
1245 and old_entry.amount = hypothetical_entry.amount(entry_number)
1246 and old_entry.recoverable_amount
1247 = hypothetical_entry.recoverable_amount (entry_number)
1248 then
1249 -- the hypo entry has the same values as the old one
1250 -- don't create a correction element.
1251 -- don't create a new entry
1252 hypothetical_entry.dealt_with (entry_number) := 'TRUE';
1253 hr_utility.trace (l_proc||' leave unchanged');
1254 else
1255 if ssp_smp_support_pkg.entry_already_processed
1256 (old_entry.element_entry_id)
1257 then
1258 l_ins_corr_ele := TRUE;
1259 hr_utility.trace (l_proc||' processed - correct it');
1260 else
1261 -- update old entry
1262 hr_utility.trace (l_proc||' unprocessed - update it');
1263 hr_entry_api.update_element_entry (
1264 p_dt_update_mode => 'CORRECTION',
1265 p_session_date => old_entry.effective_start_date,
1266 p_element_entry_id => old_entry.element_entry_id,
1267 p_input_value_id1 => g_PAB_element.rate_id,
1268 p_input_value_id2 => g_PAB_element.amount_id,
1269 p_input_value_id3 => g_PAB_element.recoverable_amount_id,
1270 p_entry_value1=> hypothetical_entry.rate (entry_number),
1271 p_entry_value2=> hypothetical_entry.amount(entry_number),
1272 p_entry_value3=>
1273 hypothetical_entry.recoverable_amount (entry_number));
1274 --
1275 --prevent insertion of new entry
1276 --
1277 hypothetical_entry.dealt_with (entry_number) := 'TRUE';
1278 end if;
1279 end if;
1280 exception
1281 when no_data_found then
1282 -- There was no new entry which exactly matched the old entry.
1283 -- or we are deleting.
1284 entry_number := null;
1285 hr_utility.trace (l_proc||' No Old entry - Hypo entry time Match');
1286 hr_utility.trace (l_proc||' or p_deleting is true');
1287 hr_utility.trace (l_proc||' Old entry values:');
1288 hr_utility.trace (l_proc||' Rate: '||old_entry.rate);
1289 hr_utility.trace (l_proc||' Amount: '||old_entry.amount);
1290 hr_utility.trace (l_proc||' Recoverable: '
1291 ||old_entry.recoverable_amount);
1292 if ssp_smp_support_pkg.entry_already_processed
1293 (old_entry.element_entry_id)
1294 then l_ins_corr_ele := TRUE;
1295 hr_utility.trace (l_proc||' Old entry already processed');
1296 else
1297 hr_utility.trace (l_proc||' Old entry NOT already processed');
1298 --Old entry not already processed so delete it
1299 hr_entry_api.delete_element_entry (
1300 p_dt_delete_mode => 'ZAP',
1301 p_session_date => old_entry.effective_start_date,
1302 p_element_entry_id => old_entry.element_entry_id);
1303 end if;
1304 end;
1305 if l_ins_corr_ele
1306 then
1307 -- Create a correction element to reverse the old entry. Then create a
1308 -- brand new entry with the correct values.
1309 --
1310 hr_utility.trace (l_proc ||
1311 ' Inserting CORRECTION entry for week commencing ' ||
1312 to_char (old_entry.week_commencing));
1313 hr_utility.trace (l_proc||' Old value / New value:');
1314 if entry_number is null then
1315 hr_utility.trace (l_proc||' Rate: '
1316 ||old_entry.rate||' / NA');
1317 hr_utility.trace (l_proc||' Amount: '
1318 ||old_entry.amount||' / NA');
1319 hr_utility.trace (l_proc||' Recoverable: '
1320 ||old_entry.recoverable_amount||' / NA');
1321 else
1322 hr_utility.trace (l_proc||' Rate: '
1323 ||old_entry.rate||' / '
1324 ||hypothetical_entry.rate (Entry_number));
1325 hr_utility.trace (l_proc||' Amount: '
1326 ||old_entry.amount||' / '
1327 ||hypothetical_entry.amount (entry_number));
1328 hr_utility.trace (l_proc||' Recoverable: '
1329 ||old_entry.recoverable_amount||' /'
1330 ||hypothetical_entry.recoverable_amount (entry_number));
1331 end if;
1332 --
1333 -- Determine the next available period in which to place the
1334 -- correction entry
1335 --
1336 ssp_smp_support_pkg.get_entry_details (
1337 p_date_earned => old_entry.week_commencing,
1338 p_last_process_date => person.final_process_date,
1339 p_person_id => person.person_id,
1340 p_element_type_id => g_PAB_Correction_element.element_type_id,
1341 p_element_link_id => old_entry.element_link_id,
1342 p_assignment_id => old_entry.assignment_id,
1343 p_effective_start_date => old_entry.effective_start_date,
1344 p_effective_end_date => old_entry.effective_end_date,
1345 p_pay_as_lump_sum => person.pay_PAB_as_lump_sum);
1346 --
1347 -- hr_entry_api's take the lookup meanings not the lookup codes.
1348 -- converted rate codes to meanings before calling the
1349 -- api. Later fix made old_entry (csr_existing_entries) return
1350 -- the meaning, so rate passed directly.
1351 --
1352 hr_entry_api.insert_element_entry (
1353 p_effective_start_date=> old_entry.effective_start_date,
1354 p_effective_end_date => old_entry.effective_end_date,
1355 p_element_entry_id => l_dummy,
1356 p_target_entry_id => old_entry.element_entry_id,
1357 p_assignment_id => old_entry.assignment_id,
1358 p_element_link_id => old_entry.element_link_id,
1359 p_creator_type => c_PAB_creator_type,
1360 p_creator_id => p_maternity_id,
1361 p_entry_type => c_PAB_entry_type,
1362 p_input_value_id1=> g_PAB_correction_element.rate_id,
1363 p_input_value_id2=> g_PAB_correction_element.week_commencing_id,
1364 p_input_value_id3=> g_PAB_correction_element.amount_id,
1365 p_input_value_id4=> g_PAB_correction_element.recoverable_amount_id,
1366 p_entry_value1=> old_entry.rate,
1367 -- p_entry_value2=> old_entry.week_commencing,
1368 p_entry_value2 => to_char(old_entry.week_commencing,'DD-MON-YYYY'),
1369 p_entry_value3=> old_entry.amount * -1,
1370 p_entry_value4=> old_entry.recoverable_amount * -1);
1371 --
1372 --New entry will be created by brand_new_entries loop if not p_deleting
1373 end if;
1374 --
1375 end loop old_entries;
1376 --
1377 -- Having been through all the existing entries, we now check that we
1378 -- have dealt with all the newly derived entries by inserting any which
1379 -- were not flagged as dealt with during the above actions.
1380 --
1381 hr_utility.set_location (l_proc,20);
1382 --
1383 <<BRAND_NEW_ENTRIES>>
1384 begin
1385 if p_deleting then
1386 hr_utility.trace('Deleting an absence so don''t insert entries');
1387 else
1388 for new_entry in 1..g_PAB_element.maximum_PPP_weeks LOOP
1389
1390 if (not hypothetical_entry.dealt_with (new_entry) = 'TRUE')
1391 and (not hypothetical_entry.stopped (new_entry) = 'TRUE')
1392 then
1393 hr_entry_api.insert_element_entry (
1394 p_effective_start_date =>
1395 hypothetical_entry.effective_start_date (new_entry),
1396 p_effective_end_date =>
1397 hypothetical_entry.effective_end_date (new_entry),
1398 p_element_entry_id => l_dummy,
1399 p_assignment_id => hypothetical_entry.assignment_id (new_entry),
1400 p_element_link_id => hypothetical_entry.element_link_id (new_entry),
1401 p_creator_type => c_PAB_creator_type,
1402 p_creator_id => p_maternity_id,
1403 p_entry_type => c_PAB_entry_type,
1404 p_input_value_id1 => g_PAB_element.rate_id,
1405 p_input_value_id2 => g_PAB_element.week_commencing_id,
1406 p_input_value_id3 => g_PAB_element.amount_id,
1407 p_input_value_id4 => g_PAB_element.recoverable_amount_id,
1408 p_entry_value1 => hypothetical_entry.rate (new_entry),
1409 -- p_entry_value2 => hypothetical_entry.week_commencing (new_entry),
1410 p_entry_value2 => to_char(hypothetical_entry.week_commencing(new_entry),'DD-MON-YYYY'),
1411 p_entry_value3 => hypothetical_entry.amount (new_entry),
1412 p_entry_value4 =>
1413 hypothetical_entry.recoverable_amount (new_entry));
1414 end if;
1415 end loop brand_new_entries;
1416 end if;
1417 exception
1418 when no_data_found then
1419 --
1420 -- We have run out of hypothetical entries to insert
1421 --
1422 null;
1423 --
1424 end;
1425 --
1426 -- Orphaned stoppages, associated with deleted absence can now be deleted
1427 -- This replaces cross product constraints that are no longer allowed.
1428 --
1429 open csr_no_of_absences;
1430 fetch csr_no_of_absences into l_no_of_absence_periods;
1431 close csr_no_of_absences;
1432 --
1433 if l_no_of_absence_periods = 0 then
1434 remove_stoppages;
1435 end if;
1436 --
1437 hr_utility.set_location(' Leaving: '||l_proc,100);
1438 --
1439 end save_hypothetical_entries;
1440 --
1441 procedure derive_PAB_week (p_week_number in integer) is
1442 --
1443 -- Derive the start and end dates of the week covered by the SAP
1444 -- payment. This is done by finding out how many weeks into the APP
1445 -- we are and finding the offset from the start date.
1446 --
1447 begin
1448 --
1449 hr_utility.set_location ('Entering: ssp_sap_pkg.derive_PAB_week',1);
1450 hr_utility.trace ('Entry number = '||to_char (p_week_number));
1451 --
1452 hypothetical_entry.week_commencing (p_week_number)
1453 := (person.APP_start_date + ((p_week_number -1) * 7));
1454 --
1455 hypothetical_entry.dealt_with (p_week_number) := 'FALSE';
1456 hypothetical_entry.stopped (p_week_number) := 'FALSE';
1457 hypothetical_entry.element_link_id (p_week_number) := null;
1458 hypothetical_entry.assignment_id (p_week_number) := null;
1459 --
1460 hr_utility.trace ('week_commencing = '
1461 ||to_char (hypothetical_entry.week_commencing (p_week_number)));
1462 --
1463 hr_utility.set_location ('Leaving : ssp_sap_pkg.derive_PAB_week',100);
1464 --
1465 end derive_PAB_week;
1466 --
1467 procedure Check_PAB_stoppages (p_week_number in integer) is
1468 --
1469 -- Find any SAP stoppage for the Adoption which overlaps a date range
1470 --
1471 employee_died varchar2 (30) := 'Employee died';
1472 --
1473 cursor csr_stoppages (p_start_date in date, p_end_date in date) is
1474 --
1475 -- Find any non-overridden stoppages
1476 --
1477 select 1
1478 from ssp_stoppages STP,
1479 ssp_withholding_reasons WRE
1480 where stp.override_stoppage <> 'Y'
1481 --
1482 -- and the stoppage ovelaps the period or the stoppage is for
1483 -- death and is prior to the period
1484 --
1485 and ((wre.reason <> employee_died
1486 and stp.withhold_from <= p_end_date
1487 and nvl (stp.withhold_to, hr_general.end_of_time)
1488 >= p_start_date)
1489 --
1490 or (wre.reason = employee_died
1491 and stp.withhold_from < p_start_date))
1492 --
1493 and stp.maternity_id = p_maternity_id
1494 and stp.reason_id = wre.reason_id;
1495 --
1496 l_dummy integer (1);
1497 --
1498 begin
1499 --
1500 hr_utility.set_location ('ssp_sap_pkg.Check_PAB_stoppages',1);
1501 --
1502 hypothetical_entry.stopped (p_week_number) := 'FALSE';
1503 --
1504 --
1505 open csr_stoppages (
1506 hypothetical_entry.week_commencing (p_week_number),
1507 ssp_smp_support_pkg.end_of_week
1508 (hypothetical_entry.week_commencing (p_week_number)));
1509
1510 fetch csr_stoppages into l_dummy;
1511 --
1512 if csr_stoppages%found
1513 then
1514 --
1515 -- There is an overlap between the SAP week and a stoppage so no SAP
1516 -- is payable.
1517 --
1518 hypothetical_entry.stopped (p_week_number) := 'TRUE';
1519 --
1520 hr_utility.trace ('Entry is STOPPED');
1521 --
1522 -- Keep a tally of the number of stopped weeks
1523 --
1524 l_stopped_weeks := l_stopped_weeks +1;
1525 end if;
1526 --
1527 close csr_stoppages;
1528 --
1529 hr_utility.set_location ('ssp_sap_pkg.Check_PAB_stoppages',10);
1530 --
1531 end Check_PAB_stoppages;
1532 --
1533 procedure Calculate_correct_PAB_rate (p_week_number in number) is
1534 --
1535 -- The entry API takes the lookup meanings so we must find
1536 -- the meanings rather than the codes for SAP rates.
1537 --
1538 cursor csr_rate_meaning (p_rate_band varchar2) is
1539 --
1540 select meaning
1541 from hr_lookups
1542 where lookup_type = 'SPP_RATES'
1543 and lookup_code = p_rate_band;
1544 --
1545 begin
1546 --
1547 hr_utility.set_location ('ssp_sap_pkg.Calculate_correct_PAB_rate',1);
1548 --
1549 if l_high_rate is null then
1550 --
1551 -- Get the meanings for the rate bands
1552 --
1553 -- Get the higher rate band
1554 --
1555 open csr_rate_meaning ('STD');
1556 fetch csr_rate_meaning into l_high_rate;
1557 close csr_rate_meaning;
1558
1559 end if;
1560 --
1561 /*
1562 if (p_week_number - l_stopped_weeks)
1563 <= g_SMP_element.period_at_higher_rate
1564 then
1565 hr_utility.set_location ('ssp_smp_pkg.Calculate_correct_SMP_rate',1);
1566 --
1567 -- We have not yet given the employee all their higher rate weeks
1568 --
1569 */
1570 hypothetical_entry.rate (p_week_number) := l_high_rate;
1571 /*
1572 else
1573 hypothetical_entry.rate (p_week_number) := l_low_rate;
1574 end if;
1575 */
1576 --
1577 hr_utility.trace ('PAB Rate = '
1578 ||hypothetical_entry.rate (p_week_number));
1579 --
1580 hr_utility.set_location ('ssp_sap_pkg.Calculate_correct_PAB_rate',10);
1581 --
1582 end Calculate_correct_PAB_rate;
1583 --
1584 procedure Calculate_PAB_amounts (p_week_number in integer, p_APP_start_date in date) is
1585 --
1586 begin
1587 --
1588 hr_utility.set_location('Entering: ssp_sAp_pkg.Calculate_SaP_amounts',1);
1589 --
1590 -- Get the SAP element for each week in case the SAP rate has changed
1591 --
1592 get_PAB_element (hypothetical_entry.week_commencing (p_week_number));
1593 --
1594 hypothetical_entry.amount (p_week_number)
1595 := least (round (
1596 (average_earnings * g_PAB_element.SPP_rate)
1597 + 0.0049,2),
1598 g_PAB_element.STANDARD_RATE);
1599 --
1600 hypothetical_entry.recoverable_amount (p_week_number)
1601 := round (hypothetical_entry.amount (p_week_number)
1602 * g_PAB_element.recovery_rate,2);
1603 --
1604 hr_utility.trace ('PAB amount = '
1605 ||to_char (hypothetical_entry.amount (p_week_number)));
1606 hr_utility.trace ('Recoverable amount = '
1607 ||to_char (hypothetical_entry.recoverable_amount (p_week_number)));
1608 --
1609 hr_utility.set_location('Leaving : ssp_sap_pkg.Calculate_PAB_amounts',100);
1610 --
1611 end calculate_PAB_amounts;
1612 --
1613 procedure check_parameters is
1614 begin
1615 hr_api.mandatory_arg_error (
1616 p_api_name => l_proc,
1617 p_argument => 'maternity_id',
1618 p_argument_value=> p_maternity_id);
1619 --
1620 end check_parameters;
1621 --
1622 begin
1623 --
1624 hr_utility.set_location ('ssp_sap_pkg.generate_payments',1);
1625 --
1626 check_parameters;
1627 --
1628 <<PAB_WEEKS>>
1629 --
1630 if person.APP_start_date is not null then
1631 for week_number in 1..g_PAB_element.maximum_PPP_weeks
1632 LOOP
1633 --
1634 -- Derive hypothetical entries ie those entries which would be applied for a
1635 -- completely new maternity. Store them internally because we must check
1636 -- previously created entries before applying the hypothetical entries to the
1637 -- database.
1638 --
1639 Derive_PAB_week (week_number);
1640 Check_PAB_stoppages (week_number);
1641 Calculate_correct_PAB_rate (week_number);
1642 Calculate_PAB_amounts (week_number, person.APP_start_date);
1643 --
1644 if (hypothetical_entry.stopped (week_number) = 'FALSE') then
1645 --
1646 -- Get the entry details unless the entry has been stopped (in which case
1647 -- we do not need the entry details and errors may occur if we call the
1648 -- procedure; eg the woman's assignment ends)
1649 --
1650 ssp_smp_support_pkg.get_entry_details (
1651 p_date_earned => hypothetical_entry.week_commencing
1652 (week_number),
1653 p_pay_as_lump_sum => person.pay_PAB_as_lump_sum,
1654 p_last_process_date => person.final_process_date,
1655 p_person_id => person.person_id,
1656 p_element_type_id => g_PAB_element.element_type_id,
1657 p_element_link_id => hypothetical_entry.element_link_id
1658 (week_number),
1659 p_assignment_id => hypothetical_entry.assignment_id
1660 (week_number),
1661 p_effective_start_date => hypothetical_entry.effective_start_date
1662 (week_number),
1663 p_effective_end_date => hypothetical_entry.effective_end_date
1664 (week_number));
1665 end if;
1666 end loop PAB_weeks;
1667 end if;
1668 --
1669 Save_hypothetical_entries(p_deleting);
1670 --
1671 end generate_payments;
1672 --
1673 --------------------------------------------------------------------------------
1674 procedure PAB_control (p_maternity_id in number,
1675 p_deleting in boolean default FALSE) is
1676 --
1677 -- p_deleting parameter added to deal with absences being deleted, without
1678 -- maternity being deleted.
1679 --
1680 cursor csr_maternity is
1681 --
1682 -- Find out if the maternity exists
1683 --
1684 select 1
1685 from ssp_maternities
1686 where maternity_id = p_maternity_id;
1687 --
1688 cursor csr_entries is
1689 --
1690 -- Get all element entries associated with a maternity
1691 --
1692 select /*+ ORDERED use_nl(paa,paaf,etype,entry) */
1693 entry.element_entry_id,
1694 entry.effective_start_date
1695 from per_absence_attendances PAA,
1696 per_all_assignments_f PAAF,
1697 pay_element_entries_f entry
1698 where PAA.maternity_id = p_maternity_id
1699 and PAAF.person_id = PAA.person_id
1700 and entry.creator_type = 'M'
1701 and entry.creator_id = p_maternity_id
1702 and entry.assignment_id = paaf.assignment_id;
1703 --
1704 cursor csr_count_absences is
1705 select count(*)
1706 from ssp_maternities mat,
1707 per_absence_attendances ab
1708 where mat.maternity_id = p_maternity_id
1709 and ab.person_id = mat.person_id
1710 and ab.maternity_id = mat.maternity_id;
1711 --
1712 l_count number;
1713 l_dummy number;
1714 l_proc varchar2 (72) := g_package||'PAB_control';
1715 --
1716 begin
1717 --
1718 hr_utility.set_location (l_proc,1);
1719 --
1720 open csr_maternity;
1721 fetch csr_maternity into l_dummy;
1722 --
1723 if csr_maternity%found then
1724 --
1725 -- Recalculate SAP
1726 --
1727 if entitled_to_PAB (p_maternity_id) then
1728 open csr_count_absences;
1729 fetch csr_count_absences into l_count;
1730 close csr_count_absences;
1731 if l_count > 0 then
1732 generate_payments (p_maternity_id, false);
1733 else
1734 generate_payments (p_maternity_id, p_deleting);
1735 end if;
1736 elsif p_deleting then
1737 -- not entitled but deleting absence then
1738 generate_payments (p_maternity_id, p_deleting);
1739 end if;
1740 else
1741 --
1742 -- The maternity may have been deleted. Remove any element entries associated
1743 -- with it (the absences, stoppages and medicals are handled by constraints).
1744 --
1745 for obsolete in csr_entries LOOP
1746 hr_utility.trace (l_proc||' Deleting element entry_id '||
1747 to_char (obsolete.element_entry_id));
1748 hr_utility.trace (l_proc||'-------------------------------------------');
1749 --
1750 hr_entry_api.delete_element_entry (
1751 p_dt_delete_mode => 'ZAP',
1752 p_session_date => obsolete.effective_start_date,
1753 p_element_entry_id => obsolete.element_entry_id);
1754 end loop;
1755 end if;
1756 --
1757 hr_utility.set_location (l_proc,100);
1758 --
1759 end PAB_control;
1760 --------------------------------------------------------------------------------
1761 end ssp_pab_pkg;