1 package body py_rollback_pkg AS
2 /* $Header: pyrolbak.pkb 120.38.12020000.4 2013/03/26 07:03:41 apudiped ship $ */
3 /*------------- Payroll and Assignment Action Details ----------------*/
4 type rollback_rec is record
5 (
6 -- Payroll Action Level Details.
7 pact_id pay_payroll_actions.payroll_action_id%type,
8 action_name hr_lookups.meaning%type,
9 action_type pay_payroll_actions.action_type%type,
10 action_status pay_payroll_actions.action_status%type,
11 sequenced_flag boolean,
12 action_date date,
13 action_start_date date,
14 current_date date, -- holds sysdate.
15 payroll_name pay_all_payrolls_f.payroll_name%type,
16 bg_name hr_organization_units.name%type,
17 bg_id hr_organization_units.business_group_id%type,
18 independent_periods_flag pay_legislation_rules.rule_mode%type,
19 date_earned date,
20 purge_phase pay_payroll_actions.purge_phase%type,
21 object_type pay_assignment_actions.object_type%type,
22 retro_definition_id pay_payroll_actions.retro_definition_id%type,
23 batch_id pay_payroll_actions.batch_id%type,
24 --
25 -- Assignment Action Level Details.
26 assact_id pay_assignment_actions.assignment_action_id%type,
27 assignment_id per_all_assignments_f.assignment_id%type,
28 full_name per_all_people_f.full_name%type,
29 assignment_number per_all_assignments_f.assignment_number%type,
30 payroll_id pay_all_payrolls_f.payroll_id%type,
31 --
32 -- Other information.
33 legislation_code varchar2(2),
34 rollback_mode varchar2(20), -- 'ROLLBACK', 'RETRY', 'BACKPAY'.
35 rollback_level varchar2(1), -- 'A' (assact) or 'P' (pact).
36 leave_row boolean, -- i.e. leave_base_table_row.
37 all_or_nothing boolean,
38 multi_thread boolean,
39 grp_multi_thread boolean,
40 dml_mode varchar2(10), -- 'NONE', 'PARTIAL, 'FULL'.
41 max_errors_allowed number,
42 max_single_undo number,
43 limit_dml boolean,
44 retro_purge pay_action_parameters.parameter_value%type,
45 single_bal_table pay_action_parameters.parameter_value%type,
46 set_date_earned pay_action_parameters.parameter_value%type,
47 sub_ledger_acc pay_action_parameters.parameter_value%type
48 );
49 --
50 -- Data structure to hold information on next range.
51 type range_rec is record
52 (
53 chunk_number number,
54 starting_person number,
55 ending_person number
56 );
57 --
58 g_error_count number;
59 g_debug boolean := hr_utility.debug_enabled;
60 --
61 -- cache variables
62 mtgl_mode pay_action_parameters.parameter_value%type;
63 mtgl_mode_cached boolean := false;
64 --
65 -- The End of Time.
66 c_eot constant date := to_date('31/12/4712', 'DD/MM/YYYY');
67 --
68 --
69 /*
70 * Get the value of the specified legislation_rule.
71 * If no value is set on the database, it obtains
72 * the relevant default value.
73 */
74 function legislation_rule(p_leg_code in varchar2,
75 p_rule_name in varchar2)
76 return varchar2 is
77 l_rule_value pay_legislation_rules.rule_mode%type;
78 begin
79 --
80 begin
81 --
82 select rule_mode
83 into l_rule_value
84 from pay_legislation_rules
85 where legislation_code = p_leg_code
86 and rule_type = p_rule_name;
87 --
88 exception
89 when no_data_found then
90 --
91 /*Bug 10212578 */
92 if (p_rule_name = 'RETRO_DELETE') then
93 if substr(fnd_release.release_name,1,2) = '12' and substr(fnd_release.release_name,4,1) >= '2' then
94 l_rule_value := 'N';
95 else
96 l_rule_value := 'Y';
97 end if;
98 else
99 l_rule_value := null;
100 end if;
101 end;
102 --
103 return l_rule_value;
104 --
105 end legislation_rule;
106 --
107 /*
108 * Get the value of the specified action parameter.
109 * If no value is set on the database, it obtains
110 * the relevant default value.
111 */
112 function action_parameter(p_param_name in varchar2)
113 return varchar2 is
114 l_name pay_action_parameters.parameter_name%type;
115 param_value pay_action_parameters.parameter_value%type;
116 c_indent constant varchar2(40) := 'py_rollback_pkg.action_parameter';
117 l_found boolean;
118 begin
119 -- Attempt to find value of the parameter
120 -- in the action parameter table.
121 pay_core_utils.get_action_parameter(p_param_name, param_value, l_found );
122
123 if l_found=FALSE then
124 if(replace(p_param_name,' ','_') = 'CHUNK_SIZE') then
125 param_value := 20;
126 elsif(replace(p_param_name,' ','_') = 'MAX_SINGLE_UNDO') then
127 param_value := 50;
128 elsif(replace(p_param_name,' ','_') = 'MAX_ERRORS_ALLOWED') then
129 -- If we can't get the max errors allowed, we
130 -- default to chunk_size - make recursive call
131 -- to get this value.
132 param_value := action_parameter('CHUNK_SIZE');
133 elsif(replace(p_param_name,' ','_') = 'SET_DATE_EARNED') then
134 param_value := 'N';
135 end if;
136 end if;
137 --
138 return(param_value);
139 --
140 end action_parameter;
141 --
142 procedure remove_pact_payment(p_pactid in number)
143 is
144 cursor get_payment(p_pact in number)
145 is
146 select pre_payment_id
147 from pay_pre_payments
148 where payroll_action_id = p_pact;
149 begin
150 --
151 for payrec in get_payment(p_pactid) loop
152 --
153 update pay_contributing_payments
154 set pre_payment_id = null
155 where pre_payment_id = payrec.pre_payment_id;
156 delete from pay_pre_payments
157 where pre_payment_id = payrec.pre_payment_id;
158 --
159 end loop;
160 --
161 end remove_pact_payment;
162 --
163 procedure remove_action_information(
164 p_action_context_id in number,
165 p_action_context_type in varchar2 default 'AAP')
166 is
167 c_indent constant varchar2(100) := 'py_rollback_pkg.remove_action_information';
168 --
169 cursor actionitems (cp_action_context_id in number,
170 cp_action_context_type in varchar2) is
171 select action_information_id
172 from pay_action_information
173 where action_context_id = cp_action_context_id
174 and action_context_type = cp_action_context_type;
175 --
176 begin
177 for actionrec in actionitems(p_action_context_id,
178 p_action_context_type) loop
179
180 /* delete Action Information */
181 delete from pay_action_information
182 where action_information_id = actionrec.action_information_id;
183
184 end loop;
185 end remove_action_information;
186
187
188 procedure remove_archive_items(p_info in rollback_rec,
189 p_source_id in number,
190 p_archive_type in varchar2 default 'AAP')
191 is
192 c_indent constant varchar2(40) := 'py_rollback_pkg.remove_archive_items';
193 --
194 cursor architems (p_source number, p_archive_type varchar2) is
195 select archive_item_id
196 from ff_archive_items
197 where context1 = p_source
198 and nvl(archive_type, 'AAP') = p_archive_type;
199 --
200 begin
201 --
202 for arcrec in architems(p_source_id, p_archive_type) loop
203 --
204 -- delete archive item contexts.
205 delete from ff_archive_item_contexts
206 where archive_item_id = arcrec.archive_item_id;
207 --
208 -- delete the archive items.
209 delete from ff_archive_items
210 where archive_item_id = arcrec.archive_item_id;
211 end loop;
212 end;
213 --
214 procedure remove_file_details(p_info in rollback_rec,
215 p_source_id in number,
216 p_source_type in varchar2 default 'PAA')
217 is
218 c_indent constant varchar2(40) := 'py_rollback_pkg.remove_file_details';
219 --
220 begin
221 --
222 delete from pay_file_details
223 where source_id = p_source_id
224 and source_type = p_source_type;
225 --
226 end;
227 --
228 /*
229 * Procedure to remove all retropay elements and element
230 * values for the specified assignment action.
231 */
232 procedure remove_retro_ee(p_assact_id in number) is
233 c_indent varchar2(40);
234 cursor ceev is
235 select pee.element_entry_id
236 from pay_element_entries_f pee,
237 pay_assignment_actions paa
238 where paa.assignment_action_id = p_assact_id
239 and pee.assignment_id = paa.assignment_id
240 and pee.creator_id = paa.assignment_action_id
241 and pee.creator_type = 'P';
242 begin
243 if g_debug then
244 c_indent := 'py_rollback_pkg.remove_retro_ee';
245 hr_utility.set_location(c_indent,10);
246 end if;
247 --
248 /* Delete the entry values before the element entry */
249 for ceevrec in ceev loop
250 delete from pay_element_entry_values_f pev
251 where element_entry_id = ceevrec.element_entry_id;
252 --
253 delete from pay_element_entries_f
254 where creator_id = p_assact_id
255 and creator_type = 'P'
256 and element_entry_id = ceevrec.element_entry_id;
257 end loop;
258 --
259 if g_debug then
260 hr_utility.set_location(c_indent,20);
261 end if;
262 end remove_retro_ee;
263 --
264 /*
265 * Procedure to remove all Advance pay elements and element
266 * values for the specified assignment action.
267 */
268 procedure remove_adv_ee(p_assact_id in number) is
269 c_indent varchar2(40);
270 cursor aeev is
271 select pee.element_entry_id
272 from pay_element_entries_f pee,
273 pay_assignment_actions paa
274 where paa.assignment_action_id = p_assact_id
275 and pee.assignment_id = paa.assignment_id
276 and pee.creator_id = paa.assignment_action_id
277 and pee.creator_type = 'D';
278 begin
279 if g_debug then
280 c_indent := 'py_rollback_pkg.remove_adv_ee';
281 hr_utility.set_location(c_indent,10);
282 end if;
283 --
284 /* Delete the entry values before the element entry */
285 for aeevrec in aeev loop
286 delete from pay_element_entry_values_f pev
287 where element_entry_id = aeevrec.element_entry_id;
288 --
289 delete from pay_element_entries_f
290 where creator_id = p_assact_id
291 and creator_type = 'D'
292 and element_entry_id = aeevrec.element_entry_id;
293 end loop;
294 --
295 if g_debug then
296 hr_utility.set_location(c_indent,20);
297 end if;
298 end remove_adv_ee;
299 --
300 -- Procedure to remove advance pay by element entries.
301 --
302 procedure remove_advpayele_ee(p_assact_id in number) is
303 c_indent varchar2(40);
304 cursor aeev is
305 select pee.element_entry_id
306 from pay_element_entries_f pee,
307 pay_assignment_actions paa
308 where paa.assignment_action_id = p_assact_id
309 and pee.assignment_id = paa.assignment_id
310 and pee.creator_id = paa.assignment_action_id
311 and pee.creator_type in ('AD', 'AE','D');
312 begin
313 if g_debug then
314 c_indent := 'py_rollback_pkg.remove_advpayele_ee';
315 hr_utility.set_location(c_indent,10);
316 end if;
317 --
318 /* Delete the entry values before the element entry */
319 for aeevrec in aeev loop
320 delete from pay_element_entry_values_f pev
321 where element_entry_id = aeevrec.element_entry_id;
322 --
323 delete from pay_element_entries_f
324 where creator_id = p_assact_id
325 and creator_type in ('AD', 'AE','D')
326 and element_entry_id = aeevrec.element_entry_id;
327 end loop;
328 --
329 if g_debug then
330 hr_utility.set_location(c_indent,20);
331 end if;
332 end remove_advpayele_ee;
333 --
334 -- Procedure to remove retropay by action entries.
335 procedure remove_retroact_ee(p_assact_id in number) is
336 c_indent varchar2(40);
337 cursor raeev is
338 select pee.element_entry_id
339 from pay_element_entries_f pee,
340 pay_assignment_actions paa
341 where paa.assignment_action_id = p_assact_id
342 and pee.assignment_id = paa.assignment_id
343 and pee.creator_id = paa.assignment_action_id
344 and pee.creator_type = 'R';
345 begin
346 if g_debug then
347 c_indent := 'py_rollback_pkg.remove_retroact_ee';
348 hr_utility.set_location(c_indent,10);
349 end if;
350 --
351 /* Delete the entry values before the element entry */
352 for raeevrec in raeev loop
353 delete from pay_element_entry_values_f pev
354 where element_entry_id = raeevrec.element_entry_id;
355 --
356 delete from pay_element_entries_f
357 where creator_id = p_assact_id
358 and creator_type = 'R'
359 and element_entry_id = raeevrec.element_entry_id;
360 end loop;
361 --
362 if g_debug then
363 hr_utility.set_location(c_indent,20);
364 end if;
365 end remove_retroact_ee;
366 --
367 -- Procedure to remove retropay by element_entries.
368 procedure remove_retroele_ee(p_assact_id in number,
369 p_rollback_mode in varchar2) is
370 c_indent varchar2(40);
371 cursor remove_eev is
372 select pee.element_entry_id
373 from pay_element_entries_f pee,
374 pay_assignment_actions paa
375 where paa.assignment_action_id = p_assact_id
376 and pee.creator_id = paa.assignment_action_id
377 and pee.creator_type in ('RR', 'EE', 'NR', 'PR') ;
378 --
379 l_reprocess_date date;
380 --
381 cursor min_reprocess_date is
382 select min(pre.reprocess_date)
383 from pay_retro_entries pre,
384 pay_retro_assignments pra
385 where pre.retro_assignment_id = pra.retro_assignment_id
386 and pra.retro_assignment_action_id = p_assact_id;
387 --
388 begin
389 if g_debug then
390 c_indent := 'py_rollback_pkg.remove_retroele_ee';
391 hr_utility.set_location(c_indent,10);
392 end if;
393 --
394 /* Delete the entry values before the element entry */
395 for eev_rec in remove_eev loop
396 delete from pay_element_entry_values_f pev
397 where element_entry_id = eev_rec.element_entry_id;
398 --
399 delete from pay_entry_process_details
400 where element_entry_id = eev_rec.element_entry_id;
401 --
402 delete from pay_element_entries_f
403 where creator_id = p_assact_id
404 and creator_type in ('RR', 'EE', 'NR', 'PR')
405 and element_entry_id = eev_rec.element_entry_id;
406 end loop;
407 --
408 hr_utility.set_location(c_indent,20);
409 -- Finally reset the pay_retro_assignment_table if needed
410 if (p_rollback_mode <> 'RETRY') then
411 --
412 pay_retro_pkg.merge_retro_assignments(p_assact_id);
413 --
414 hr_utility.set_location(c_indent,30);
415 -- Remove or reset row on pay_recorded_requests
416 --
417 hr_utility.set_location(c_indent,40);
418 pay_retro_pkg.reset_recorded_request(p_assact_id);
419 hr_utility.set_location(c_indent,50);
420 --
421 -- Remove the asg act id, and in case merge has new earlier entries
422 -- also change the reprocess_date
423 open min_reprocess_date;
424 fetch min_reprocess_date into l_reprocess_date;
425 close min_reprocess_date;
426 --
427 update pay_retro_assignments ra
428 set ra.retro_assignment_action_id = null,
429 ra.reprocess_date = nvl(l_reprocess_date,ra.reprocess_date)
430 where ra.retro_assignment_action_id = p_assact_id;
431
432 end if;
433 --
434 if g_debug then
435 hr_utility.set_location(c_indent,20);
436 end if;
437 --
438 end remove_retroele_ee;
439 --
440 /*
441 * Procedure to delete entries from gl_interface tables.
442 */
443 procedure remove_gl_entries(p_info in rollback_rec) is
444 c_indent varchar2(40);
445 l_source_name gl_interface.user_je_source_name%type;
446 --
447 begin
448 if g_debug then
449 c_indent := 'py_rollback_pkg.remove_gl_entries';
450 hr_utility.set_location(c_indent, 10);
451 end if;
452 --
453 if mtgl_mode_cached = FALSE then
454 if g_debug then
455 hr_utility.set_location(c_indent, 20);
456 end if;
457 begin
458 select upper(parameter_value)
459 into mtgl_mode
460 from pay_action_parameters
461 where parameter_name = 'TRANSGL_THREAD';
462 exception
463 when others then
464 mtgl_mode := 'Y';
465 end;
466 --
467 if g_debug then
468 hr_utility.set_location(c_indent, 30);
469 end if;
470 -- Remove transfer table rows once only
471 -- first of all get source_name
472 select user_je_source_name
473 into l_source_name
474 from gl_je_sources
475 where je_source_name = 'Payroll';
476 --
477 if g_debug then
478 hr_utility.set_location(c_indent, 35);
479 end if;
480 delete from gl_interface gl
481 where gl.reference21 = to_char(p_info.pact_id)
482 and gl.user_je_source_name = l_source_name;
483 --
484 mtgl_mode_cached := TRUE;
485 end if;
486 --
487 if mtgl_mode <> 'N' then
488 -- Remove intermediate transfer table rows
489 -- for multi-threaded transfer to General Ledger only
490 if g_debug then
491 hr_utility.set_location(c_indent, 40);
492 end if;
493 delete from pay_gl_interface pgl
494 where pgl.assignment_action_id = p_info.assact_id;
495 end if;
496 --
497 end remove_gl_entries;
498 --
499 /*
500 * Procedure to reset the prenote date for magnetic tape
501 * rollback.
502 */
503 procedure reset_prenote(p_assact_id in number) is
504 cursor get_accnts_to_reset(asgact in number) is
505 select pea.external_account_id
506 from pay_external_accounts pea,
507 pay_payment_types ppt,
508 pay_personal_payment_methods_f ppm,
509 pay_org_payment_methods_f opm,
510 pay_pre_payments ppp,
511 pay_payroll_actions ppa,
512 pay_assignment_actions paa
513 where paa.assignment_action_id = asgact
514 and paa.payroll_action_id = ppa.payroll_action_id
515 and paa.pre_payment_id = ppp.pre_payment_id
516 and ppp.org_payment_method_id = opm.org_payment_method_id
517 and ppp.personal_payment_method_id = ppm.personal_payment_method_id
518 and opm.payment_type_id = ppt.payment_type_id
519 and ppt.pre_validation_required = 'Y'
520 and ppt.validation_value = ppp.value
521 and ppm.external_account_id = pea.external_account_id
522 and ppa.effective_date between ppm.effective_start_date
523 and ppm.effective_end_date
524 and ppa.effective_date between opm.effective_start_date
525 and opm.effective_end_date;
526 begin
527 for eacrec in get_accnts_to_reset(p_assact_id) loop
528 update pay_external_accounts
529 set prenote_date = null
530 where external_account_id = eacrec.external_account_id
531 and prenote_date is not null;
532 end loop;
533 end reset_prenote;
534 --
535 /*
536 * Procedure to remove all run results and run result
537 * values for the specified assignment action.
538 */
539 procedure remove_run_results(p_info in rollback_rec) is
540 c_indent varchar2(40);
541 purge_rr boolean;
542 cursor crrv is
543 select prr.run_result_id
544 from pay_run_results prr
545 where prr.assignment_action_id = p_info.assact_id;
546 begin
547 -- Delete any run results and values created by
548 -- this action. There is no cascade trigger on
549 -- run results, so we are forced to do both.
550 -- We use a cursor loop here to avoid a full table
551 -- scan that occurs when you attempt to use a single
552 -- delete statement.
553 -- Tight loop, so the set_location call set outside it.
554 if g_debug then
555 c_indent := 'py_rollback_pkg.remove_run_results';
556 hr_utility.set_location(c_indent,10);
557 end if;
558 --
559 purge_rr := TRUE;
560 if (p_info.rollback_mode = 'BACKPAY'
561 and p_info.retro_purge = 'N') then
562 --
563 purge_rr := FALSE;
564 --
565 end if;
566 --
567 if (purge_rr = TRUE) then
568 for crrvrec in crrv loop
569 delete from pay_run_result_values rrv
570 where rrv.run_result_id = crrvrec.run_result_id;
571 end loop;
572 --
573 if g_debug then
574 hr_utility.set_location(c_indent,30);
575 end if;
576 delete from pay_run_results RR
577 where RR.assignment_action_id = p_info.assact_id;
578 --
579 else
580 --
581 if g_debug then
582 hr_utility.set_location(c_indent,40);
583 end if;
584 -- It must be a backpay.
585 update pay_run_results RR
586 set RR.status = 'B'
587 where RR.assignment_action_id = p_info.assact_id;
588 end if;
589 end remove_run_results;
590 --
591 /*
592 * Procedure to remove all action contexts.
593 */
594 procedure remove_action_contexts(p_assact_id in number) is
595 c_indent varchar2(40);
596 begin
597 if g_debug then
598 c_indent := 'py_rollback_pkg.remove_action_contexts';
599 hr_utility.set_location(c_indent,10);
600 end if;
601 --
602 delete from pay_action_contexts
603 where assignment_action_id = p_assact_id;
604 --
605 if g_debug then
606 hr_utility.set_location(c_indent,30);
607 end if;
608 end remove_action_contexts;
609 --
610 /*
611 * Deletes all latest balances and associated balance
612 * context values for the specified assignment action id.
613 * balances are only removed if a prev balance does not exist,
614 * other wise the prev blance is assigned to the latest balance
615 *
616 * Deletes all latest balances if the action before rolled back is a
617 * balance adjustment or a balance initialisation. This is because as
618 * these are 'special' types of sequenced actions, their results may
619 * have fed the balances without the latest balances being owned by them.
620 */
621
622 procedure remove_balances(p_info in rollback_rec) is
623 c_indent varchar2(40);
624 cursor baplb(l_person_id number) is
625 --
626 select /*+ INDEX(plb PAY_PERSON_LATEST_BALANCES_N3)*/
627 plb.latest_balance_id,
628 plb.prev_balance_value,
629 plb.prev_assignment_action_id,
630 plb.expired_value,
631 plb.expired_assignment_action_id,
632 plb.assignment_action_id
633 from pay_person_latest_balances plb,
634 pay_defined_balances pdb,
635 pay_balance_feeds_f pbf,
636 pay_run_result_values rrv,
637 pay_run_results prr
638 where prr.assignment_action_id = p_info.assact_id
639 and rrv.run_result_id = prr.run_result_id
640 and rrv.result_value is not null
641 and pbf.input_value_id = rrv.input_value_id
642 and pdb.balance_type_id = pbf.balance_type_id
643 and plb.defined_balance_id = pdb.defined_balance_id
644 and plb.person_id = l_person_id
645 and p_info.action_date between pbf.effective_start_date
646 and pbf.effective_end_date;
647 --
648 cursor baalb is
649 select /*+ INDEX(alb PAY_ASSIGNMENT_LATEST_BALA_N3)*/
650 alb.latest_balance_id,
651 alb.prev_balance_value,
652 alb.prev_assignment_action_id,
653 alb.expired_value,
654 alb.expired_assignment_action_id,
655 alb.assignment_action_id
656 from pay_assignment_latest_balances alb,
657 pay_defined_balances pdb,
658 pay_balance_feeds_f pbf,
659 pay_run_result_values rrv,
660 pay_run_results prr
661 where prr.assignment_action_id = p_info.assact_id
662 and rrv.run_result_id = prr.run_result_id
663 and rrv.result_value is not null
664 and pbf.input_value_id = rrv.input_value_id
665 and pdb.balance_type_id = pbf.balance_type_id
666 and alb.defined_balance_id = pdb.defined_balance_id
667 and alb.assignment_id = p_info.assignment_id
668 and p_info.action_date between pbf.effective_start_date
669 and pbf.effective_end_date;
670 --
671 cursor balb (l_person_id number)is
672 select
673 lb.latest_balance_id,
674 lb.prev_balance_value,
675 lb.prev_assignment_action_id,
676 lb.prev_expiry_date,
677 lb.expired_value,
678 lb.expired_assignment_action_id,
679 lb.assignment_action_id
680 from pay_latest_balances lb,
681 pay_defined_balances pdb,
682 pay_balance_feeds_f pbf,
683 pay_run_result_values rrv,
684 pay_run_results prr
685 where prr.assignment_action_id = p_info.assact_id
686 and rrv.run_result_id = prr.run_result_id
687 and rrv.result_value is not null
688 and pbf.input_value_id = rrv.input_value_id
689 and pdb.balance_type_id = pbf.balance_type_id
690 and lb.defined_balance_id = pdb.defined_balance_id
691 and lb.person_id = l_person_id
692 and ( lb.assignment_id = p_info.assignment_id
693 or lb.assignment_id is null)
694 and ( lb.process_group_id = (select distinct pog.parent_object_group_id
695 from pay_object_groups pog
696 where pog.source_id = p_info.assignment_id
697 and pog.source_type = 'PAF')
698 or lb.process_group_id is null)
699 and p_info.action_date between pbf.effective_start_date
700 and pbf.effective_end_date;
701 --
702 cursor cplb is
703 select plb.latest_balance_id,
704 plb.prev_balance_value,
705 plb.prev_assignment_action_id,
706 plb.expired_value,
707 plb.expired_assignment_action_id
708 from pay_person_latest_balances plb
709 where plb.assignment_action_id = p_info.assact_id;
710 --
711 cursor calb is
712 select alb.latest_balance_id,
713 alb.prev_balance_value,
714 alb.prev_assignment_action_id,
715 alb.expired_value,
716 alb.expired_assignment_action_id
717 from pay_assignment_latest_balances alb
718 where alb.assignment_action_id = p_info.assact_id;
719 --
720 cursor clb is
721 select lb.latest_balance_id,
722 lb.prev_balance_value,
723 lb.prev_assignment_action_id,
724 lb.prev_expiry_date,
725 lb.expired_value,
726 lb.expired_assignment_action_id
727 from pay_latest_balances lb
728 where lb.assignment_action_id = p_info.assact_id;
729 --
730 l_person_id per_all_assignments_f.person_id%TYPE;
731
732 begin
733 -- Remove latest balances and associated context values.
734 -- Delete cascade not used because a) efficiency and
735 -- b) must delete for both rollback and mark for retry.
736 -- Cursor loops used to avoid full table access of
737 -- the balance context table.
738
739 if g_debug then
740 c_indent := 'py_rollback_pkg.remove_balances';
741 hr_utility.set_location(c_indent,10);
742 end if;
743 if (p_info.action_type in ('B', 'I', 'V')) then
744 -- treat balance adjustment as a special case : we should
745 -- delete all latest balances for an assignment if its having
746 -- a balance adjustment being rolled back (because its very
747 -- difficult to work out which if any of the latest, previous
748 -- or expired balances were fed by the balance adjustment)
749 -- And Reversals now too!
750
751 select person_id
752 into l_person_id
753 from per_all_assignments_f
754 where assignment_id = p_info.assignment_id
755 and p_info.action_date between
756 effective_start_date and effective_end_date;
757
758 if g_debug then
759 hr_utility.set_location(c_indent,15);
760 end if;
761
762 if (p_info.single_bal_table <> 'Y') then
763
764 for bplbrec in baplb(l_person_id) loop
765 if bplbrec.assignment_action_id = p_info.assact_id then
766 if bplbrec.prev_balance_value=-9999
767 or bplbrec.prev_balance_value is NULL
768 or bplbrec.prev_assignment_action_id is NULL
769 then
770 delete from pay_balance_context_values bcv
771 where bcv.latest_balance_id = bplbrec.latest_balance_id;
772
773 delete from pay_person_latest_balances plb
774 where plb.latest_balance_id = bplbrec.latest_balance_id;
775 else
776 if bplbrec.prev_assignment_action_id = bplbrec.expired_assignment_action_id
777 then
778 update pay_person_latest_balances
779 set expired_assignment_action_id = -9999,
780 expired_value = -9999
781 where pay_person_latest_balances.latest_balance_id =
782 bplbrec.latest_balance_id;
783 end if;
784 update pay_person_latest_balances
785 set assignment_action_id = bplbrec.prev_assignment_action_id,
786 value = bplbrec.prev_balance_value,
787 prev_assignment_action_id = -9999,
788 prev_balance_value = -9999
789 where pay_person_latest_balances.latest_balance_id =
790 bplbrec.latest_balance_id;
791 end if;
792 else
793 delete from pay_balance_context_values bcv
794 where bcv.latest_balance_id = bplbrec.latest_balance_id;
795
796 delete from pay_person_latest_balances plb
797 where plb.latest_balance_id = bplbrec.latest_balance_id;
798 end if;
799 end loop;
800
801 for balbrec in baalb loop
802 if balbrec.assignment_action_id = p_info.assact_id then
803 if balbrec.prev_balance_value=-9999
804 or balbrec.prev_balance_value is NULL
805 or balbrec.prev_assignment_action_id is NULL
806 then
807 delete from pay_balance_context_values bcv
808 where bcv.latest_balance_id = balbrec.latest_balance_id;
809
810 delete from pay_assignment_latest_balances alb
811 where alb.latest_balance_id = balbrec.latest_balance_id;
812 else
813 if balbrec.prev_assignment_action_id = balbrec.expired_assignment_action_id
814 then
815 update pay_assignment_latest_balances
816 set expired_assignment_action_id = -9999,
817 expired_value = -9999
818 where pay_assignment_latest_balances.latest_balance_id =
819 balbrec.latest_balance_id;
820 end if;
821 update pay_assignment_latest_balances
822 set assignment_action_id = balbrec.prev_assignment_action_id,
823 value = balbrec.prev_balance_value,
824 prev_assignment_action_id = -9999,
825 prev_balance_value = -9999
826 where pay_assignment_latest_balances.latest_balance_id =
827 balbrec.latest_balance_id;
828 end if;
829 else
830 delete from pay_balance_context_values bcv
831 where bcv.latest_balance_id = balbrec.latest_balance_id;
832
833 delete from pay_assignment_latest_balances alb
834 where alb.latest_balance_id = balbrec.latest_balance_id;
835 end if;
836 end loop;
837
838 else /* single_bal_table */
839
840 for blbrec in balb(l_person_id) loop
841 if blbrec.assignment_action_id = p_info.assact_id then
842 if blbrec.prev_balance_value=-9999
843 or blbrec.prev_balance_value is NULL
844 or blbrec.prev_assignment_action_id is NULL
845 then
846 delete from pay_latest_balances lb
847 where lb.latest_balance_id = blbrec.latest_balance_id;
848 else
849 if blbrec.prev_assignment_action_id = blbrec.expired_assignment_action_id
850 then
851 update pay_latest_balances
852 set expired_assignment_action_id = -9999,
853 expired_value = -9999,
854 expired_date = null
855 where pay_latest_balances.latest_balance_id =
856 blbrec.latest_balance_id;
857 end if;
858 update pay_latest_balances
859 set assignment_action_id = blbrec.prev_assignment_action_id,
860 value = blbrec.prev_balance_value,
861 expiry_date = blbrec.prev_expiry_date,
862 prev_assignment_action_id = -9999,
863 prev_balance_value = -9999,
864 prev_expiry_date = null
865 where pay_latest_balances.latest_balance_id =
866 blbrec.latest_balance_id;
867 end if;
868 else
869 delete from pay_latest_balances alb
870 where alb.latest_balance_id = blbrec.latest_balance_id;
871 end if;
872 end loop;
873
874 end if; /* single_bal_table */
875
876 else
877 if g_debug then
878 hr_utility.set_location(c_indent,90);
879 end if;
880
881 if (p_info.single_bal_table <> 'Y') then
882
883 for calbrec in calb loop
884 if (calbrec.prev_balance_value=-9999
885 or calbrec.prev_balance_value is NULL
886 or calbrec.prev_assignment_action_id is NULL)
887 then
888 begin
889 delete from pay_balance_context_values bcv
890 where bcv.latest_balance_id = calbrec.latest_balance_id;
891 delete from pay_assignment_latest_balances alb
892 where alb.latest_balance_id=calbrec.latest_balance_id;
893 end;
894 else
895 begin
896 if calbrec.prev_assignment_action_id=calbrec.expired_assignment_action_id
897 then
898 update pay_assignment_latest_balances
899 set expired_assignment_action_id=-9999,
900 expired_value=-9999
901 where pay_assignment_latest_balances.latest_balance_id =
902 calbrec.latest_balance_id;
903 end if;
904 update pay_assignment_latest_balances
905 set assignment_action_id=calbrec.prev_assignment_action_id,
906 value=calbrec.prev_balance_value,
907 prev_assignment_action_id=-9999,
908 prev_balance_value=-9999
909 where pay_assignment_latest_balances.latest_balance_id =
910 calbrec.latest_balance_id;
911 end;
912 end if;
913 end loop;
914
915
916 if g_debug then
917 hr_utility.set_location(c_indent,100);
918 end if;
919 for cplbrec in cplb loop
920 if (cplbrec.prev_balance_value=-9999 or
921 cplbrec.prev_balance_value is NULL or
922 cplbrec.prev_assignment_action_id is NULL)
923 then
924 begin
925 delete from pay_balance_context_values bcv
926 where bcv.latest_balance_id = cplbrec.latest_balance_id;
927 delete from pay_person_latest_balances plb
928 where plb.latest_balance_id=cplbrec.latest_balance_id;
929 end;
930 else
931 begin
932 if cplbrec.prev_assignment_action_id=cplbrec.expired_assignment_action_id
933 then
934 update pay_person_latest_balances
935 set expired_assignment_action_id=-9999,
936 expired_value=-9999
937 where pay_person_latest_balances.latest_balance_id =
938 cplbrec.latest_balance_id;
939 end if;
940 update pay_person_latest_balances
941 set assignment_action_id=cplbrec.prev_assignment_action_id,
942 value=cplbrec.prev_balance_value,
943 prev_assignment_action_id=-9999,
944 prev_balance_value=-9999
945 where pay_person_latest_balances.latest_balance_id =
946 cplbrec.latest_balance_id;
947 end;
948 end if;
949 end loop;
950
951 else /* single_bal_table */
952
953 for clbrec in clb loop
954 if (clbrec.prev_balance_value=-9999
955 or clbrec.prev_balance_value is NULL
956 or clbrec.prev_assignment_action_id is NULL)
957 then
958 begin
959 delete from pay_latest_balances lb
960 where lb.latest_balance_id=clbrec.latest_balance_id;
961 end;
962 else
963 begin
964 if clbrec.prev_assignment_action_id=clbrec.expired_assignment_action_id
965 then
966 update pay_latest_balances
967 set expired_assignment_action_id=-9999,
968 expired_value=-9999,
969 expired_date = null
970 where pay_latest_balances.latest_balance_id =
971 clbrec.latest_balance_id;
972 end if;
973 update pay_latest_balances
974 set assignment_action_id=clbrec.prev_assignment_action_id,
975 value=clbrec.prev_balance_value,
976 expiry_date = clbrec.prev_expiry_date,
977 prev_assignment_action_id=-9999,
978 prev_balance_value=-9999,
979 prev_expiry_date = null
980 where pay_latest_balances.latest_balance_id =
981 clbrec.latest_balance_id;
982 end;
983 end if;
984 end loop;
985
986 end if; /* single_bal_table */
987 end if;
988
989 end remove_balances;
990 --
991 /*
992 * Delete all entries and entry values that were inserted
993 * by a balance adjustment.
994 * It is only called for a balance adjustment action.
995 */
996 procedure undo_bal_adjust(p_action_date in date, p_assact_id in number) is
997 -- Batch balance adjustment can have many adjustments
998 -- for an assignment action.
999 cursor c1 is
1000 select pee.element_entry_id
1001 from pay_element_entries_f pee,
1002 pay_assignment_actions paa
1003 where paa.assignment_action_id = p_assact_id
1004 and pee.assignment_id = paa.assignment_id
1005 and pee.creator_id = paa.assignment_action_id
1006 and pee.creator_type = 'B' -- (B)alance Adjustment
1007 and p_action_date between
1008 pee.effective_start_date and pee.effective_end_date;
1009 begin
1010 if g_debug then
1011 hr_utility.set_location('undo_bal_adjust', 60);
1012 end if;
1013 for c1rec in c1 loop
1014 -- Now, we attempt to delete the entry values.
1015 delete from pay_element_entry_values_f pev
1016 where pev.element_entry_id = c1rec.element_entry_id
1017 and p_action_date between
1018 pev.effective_start_date and pev.effective_end_date;
1019 --
1020 -- Now we attempt to delete the element entry row.
1021 -- Note, if this procedure is called from the balance
1022 -- adjustment form, the form may be attempting to delete
1023 -- this row. However, this could be called from the
1024 -- actions form, in which case we do need to do the delete.
1025 delete from pay_element_entries_f pee
1026 where pee.element_entry_id = c1rec.element_entry_id
1027 and p_action_date between
1028 pee.effective_start_date and pee.effective_end_date;
1029 end loop;
1030 if g_debug then
1031 hr_utility.set_location('undo_bal_adjust', 70);
1032 end if;
1033 --
1034 end undo_bal_adjust;
1035 --
1036 /*
1037 * Delete all messages (from pay_message_lines) as specified
1038 * by the source_type. in other words:
1039 * P : payroll_action_id
1040 * A : assignment_action_id
1041 */
1042 procedure remove_messages(p_info in rollback_rec, p_source_type in varchar2) is
1043 begin
1044 delete from pay_message_lines pml
1045 where pml.source_type = p_source_type
1046 and pml.source_id =
1047 decode(p_source_type,
1048 'P', p_info.pact_id,
1049 'A', p_info.assact_id);
1050 end remove_messages;
1051 --
1052 /*
1053 * Procedure to get information about the payroll action
1054 * this information is required for both payroll action
1055 * and assignment action rollback.
1056 * Note - it does perform a couple of validation
1057 * checks at the payroll action level and so might fail.
1058 */
1059 procedure get_pact_info(p_info in out nocopy rollback_rec)
1060 is
1061 c_indent varchar2(40);
1062 begin
1063 --
1064 -- get payroll action level information
1065 if g_debug then
1066 c_indent := 'py_rollback_pkg.get_pact_info';
1067 hr_utility.set_location(c_indent, 10);
1068 end if;
1069 select pac.business_group_id,
1070 pac.effective_date,
1071 pac.start_date,
1072 hrl.meaning,
1073 pac.action_type,
1074 pac.action_status,
1075 trunc(sysdate),
1076 pay.payroll_name,
1077 grp.name,
1078 grp.legislation_code,
1079 pac.date_earned,
1080 pac.purge_phase,
1081 pac.retro_definition_id,
1082 pac.batch_id,
1083 decode(pac.action_type, 'T',
1084 nvl(pay_core_utils.get_parameter('SLA_MODE',
1085 pac.legislative_parameters),
1086 'N'),
1087 'N')
1088 into p_info.bg_id,
1089 p_info.action_date,
1090 p_info.action_start_date,
1091 p_info.action_name,
1092 p_info.action_type,
1093 p_info.action_status,
1094 p_info.current_date,
1095 p_info.payroll_name,
1096 p_info.bg_name,
1097 p_info.legislation_code,
1098 p_info.date_earned,
1099 p_info.purge_phase,
1100 p_info.retro_definition_id,
1101 p_info.batch_id,
1102 p_info.sub_ledger_acc
1103 from pay_payroll_actions pac,
1104 pay_all_payrolls_f pay,
1105 per_business_groups_perf grp,
1106 hr_lookups hrl
1107 where pac.payroll_action_id = p_info.pact_id
1108 and hrl.lookup_code = pac.action_type
1109 and hrl.lookup_type = 'ACTION_TYPE'
1110 and grp.business_group_id = pac.business_group_id + 0
1111 and pay.payroll_id (+) = pac.payroll_id
1112 and pac.effective_date between
1113 pay.effective_start_date (+) and pay.effective_end_date (+);
1114 if g_debug then
1115 hr_utility.trace('action type is ' || p_info.action_type );
1116 end if;
1117 --
1118 --
1119 -- legislation information.
1120 p_info.independent_periods_flag := upper( hr_leg_rule.get_independent_periods(p_info.bg_id));
1121
1122 --
1123 -- Treat Retropays as special case as always Time Independent if not Group level
1124 --
1125 if (p_info.action_type in ('G', 'L', 'O') and
1126 p_info.independent_periods_flag = 'N') then
1127 p_info.independent_periods_flag := 'Y';
1128 end if;
1129 --
1130 -- see if this type of action is sequenced or not
1131 declare
1132 dummy number;
1133 begin
1134 p_info.sequenced_flag := TRUE;
1135 --
1136 select null
1137 into dummy
1138 from pay_action_classifications CLASS
1139 where CLASS.action_type = p_info.action_type
1140 and CLASS.classification_name = 'SEQUENCED';
1141 if g_debug then
1142 hr_utility.trace('this action type IS sequenced');
1143 end if;
1144 exception
1145 when no_data_found then
1146 p_info.sequenced_flag := FALSE;
1147 if g_debug then
1148 hr_utility.trace('this action type NOT sequenced');
1149 end if;
1150 end;
1151 --
1152 /* get the object Types for this payroll_action */
1153 begin
1154 select /*+ INDEX(paa PAY_ASSIGNMENT_ACTIONS_N50)*/
1155 decode (ppa.action_type,
1156 'X', paa.object_type,
1157 decode(paa.object_type,
1158 'PAF', null,
1159 paa.object_type))
1160 into p_info.object_type
1161 from pay_assignment_actions paa,
1162 pay_payroll_actions ppa
1163 where paa.payroll_action_id = p_info.pact_id
1164 and p_info.pact_id = ppa.payroll_action_id
1165 and paa.source_action_id is null
1166 and rownum = 1;
1167 exception
1168 when no_data_found then
1169 p_info.object_type := null;
1170 end;
1171 end get_pact_info;
1172 --
1173 --
1174 /*
1175 * Insert a message indicating a rollback has occurred. This
1176 * is used for both assignment and payroll action rollback.
1177 */
1178 procedure ins_rollback_message(p_info in rollback_rec, p_level in varchar2) is
1179 c_indent varchar2(40);
1180 l_line_text pay_message_lines.line_text%type;
1181 l_line_sequence number;
1182 l_payroll_id number;
1183 l_source_id number;
1184 l_source_type pay_message_lines.source_type%type;
1185 l_action_name hr_lookups.meaning%type;
1186 begin
1187 g_debug := hr_utility.debug_enabled;
1188 if g_debug then
1189 c_indent := 'py_rollback_pkg.ins_rollback_message';
1190 hr_utility.set_location(c_indent, 10);
1191 end if;
1192 -- Set up a message for either rollback at assignment or
1193 -- payroll action level.
1194 if(p_level = 'A') then
1195 hr_utility.set_message (801, 'HR_ACTION_ASACT_ROLLOK');
1196 hr_utility.set_message_token('ASG_NUMBER',p_info.assignment_number);
1197 hr_utility.set_message_token('FULL_NAME',p_info.full_name);
1198 hr_utility.set_message_token
1199 ('SYSDATE',fnd_date.date_to_canonical(p_info.current_date));
1200 --
1201 -- Message will insert at payroll action level.
1202 l_source_id := p_info.pact_id;
1203 l_source_type := 'P';
1204 --
1205 else
1206 -- Rollback level is 'P'.
1207 --
1208 -- For Magnetic Transfer, the action name must be taken
1209 -- from the Payment Type Name (i.e. BACS, NACHA etc).
1210 if(p_info.action_type = 'M') then
1211 if g_debug then
1212 hr_utility.set_location(c_indent, 90);
1213 end if;
1214 select ppt.payment_type_name
1215 into l_action_name
1216 from pay_payroll_actions pac,
1217 pay_payment_types ppt
1218 where pac.payroll_action_id = p_info.pact_id
1219 and ppt.payment_type_id = pac.payment_type_id;
1220 else
1221 l_action_name := p_info.action_name;
1222 end if;
1223 --
1224 -- The message we set up depends on whether or not the
1225 -- Payroll Action is restricted or unrestricted.
1226 if(p_info.payroll_name is null) then
1227 hr_utility.set_message(801,'HR_ACTION_PACT_ROLLNOPAY');
1228 else
1229 hr_utility.set_message(801,'HR_ACTION_PACT_ROLLPAY');
1230 hr_utility.set_message_token('PAYROLL_NAME', p_info.payroll_name);
1231 end if;
1232 --
1233 -- Common message tokens.
1234 hr_utility.set_message_token('ACTION_TYPE',l_action_name);
1235 hr_utility.set_message_token('BG_NAME',p_info.bg_name);
1236 hr_utility.set_message_token('SYSDATE',
1237 fnd_date.date_to_canonical(p_info.current_date));
1238 --
1239 -- Message will insert at business group level.
1240 l_source_id := p_info.bg_id;
1241 l_source_type := 'B';
1242 end if; --- rollback level.
1243 --
1244 -- Get text of message we have set up.
1245 l_line_text := substrb(hr_utility.get_message, 1, 240);
1246 --
1247 -- Write message into message lines table.
1248 if g_debug then
1249 hr_utility.set_location(c_indent, 10);
1250 end if;
1251 insert into pay_message_lines (
1252 line_sequence,
1253 payroll_id,
1254 message_level,
1255 source_id,
1256 source_type,
1257 line_text)
1258 values (pay_message_lines_s.nextval,
1259 l_payroll_id,
1260 'I', -- information.
1261 l_source_id,
1262 l_source_type,
1263 l_line_text);
1264 --
1265 end ins_rollback_message;
1266 --
1267 /*---------------------- ins_rollback_message ---------------------------*/
1268 /*
1269 * overloaded procedure to insert a rollback message on successful
1270 * completion of the rolling back of a payroll action. This must
1271 * be callable externally, since the rollback process needs to be
1272 * able to insert this message, independently of the plsql.
1273 */
1274 procedure ins_rollback_message(p_payroll_action_id in number) is
1275 info rollback_rec;
1276 begin
1277 info.pact_id := p_payroll_action_id;
1278 get_pact_info(info); -- payroll action information.
1279 ins_rollback_message(info, 'P'); -- the message itself.
1280 end ins_rollback_message;
1281 --
1282 /*------------------------ undo_stop_update -----------------------------*/
1283 /*
1284 * This procedure is called when we have detected the need to undo the
1285 * effect of a stop or update recurring entry formula result rule.
1286 * Note that, due to the complexity of calculating entry end dates, we
1287 * call the existing routine, but trap error messages that are
1288 * inappropriate for our application.
1289 */
1290 procedure undo_stop_update(
1291 p_ee_id in number,
1292 p_mult in varchar,
1293 p_date in date,
1294 p_mode in varchar2) is
1295 --
1296 -- Local variables.
1297 effstart date;
1298 effend date;
1299 val_start date;
1300 val_end date;
1301 next_end date;
1302 max_end date;
1303 orig_ee_id number;
1304 prev_asgact_id number;
1305 asg_id number;
1306 el_id number;
1307 c_indent varchar2(40);
1308 begin
1309 -- Select some information about the entry we are operating on.
1310 if g_debug then
1311 c_indent := 'py_rollback_pkg.undo_stop_update';
1312 hr_utility.set_location(c_indent, 10);
1313 end if;
1314 select pee.effective_start_date,
1315 pee.effective_end_date,
1316 pee.original_entry_id,
1317 pee.assignment_id,
1318 pee.element_link_id
1319 into effstart, effend, orig_ee_id, asg_id, el_id
1320 from pay_element_entries_f pee
1321 where pee.element_entry_id = p_ee_id
1322 and p_date between
1323 pee.effective_start_date and pee.effective_end_date;
1324 --
1325 -- Do nothing if the entry end date is end of time.
1326 if(effend = c_eot) then
1327 return;
1328 end if;
1329 --
1330 -- For undo update, we have to get next effective start date.
1331 if(p_mode = 'DELETE_NEXT_CHANGE') then
1332 begin
1333 if g_debug then
1334 hr_utility.set_location(c_indent, 20);
1335 end if;
1336 select min(ee.effective_end_date)
1337 into next_end
1338 from pay_element_entries_f ee
1339 where ee.element_entry_id = p_ee_id
1340 and ee.effective_start_date > effend;
1341 exception
1342 when no_data_found then null;
1343 end;
1344 --
1345 val_start := effend + 1;
1346 --
1347 if next_end is null then
1348 val_end := c_eot;
1349 else
1350 val_end := next_end;
1351 end if;
1352 elsif(p_mode = 'FUTURE_CHANGE') then
1353 val_start := effend + 1;
1354 val_end := c_eot;
1355 end if;
1356 --
1357 -- For either mode, we need to obtain the date to which
1358 -- we may legally extend the entry.
1359 declare
1360 message varchar2(200);
1361 applid varchar2(200);
1362 begin
1363 max_end := hr_entry.recurring_entry_end_date (
1364 asg_id, el_id, p_date, 'Y', p_mult, p_ee_id, orig_ee_id);
1365 exception
1366 -- Several error messages can be raised from this procedure.
1367 -- We wish to trap a number of them, as they should be ignored
1368 -- for our purposes.
1369 when hr_utility.hr_error then
1370 hr_utility.get_message_details(message,applid);
1371 --
1372 if(message in ('HR_7699_ELE_ENTRY_REC_EXISTS',
1373 'HR_7700_ELE_ENTRY_REC_EXISTS',
1374 'HR_6281_ELE_ENTRY_DT_DEL_LINK',
1375 'HR_6283_ELE_ENTRY_DT_ELE_DEL',
1376 'HR_6284_ELE_ENTRY_DT_ASG_DEL')
1377 ) then
1378 -- We cannot extend the entry.
1379 if g_debug then
1380 hr_utility.set_location(c_indent, 25);
1381 end if;
1382 if(p_mode = 'DELETE_NEXT_CHANGE') then
1383 update pay_element_entries_f ee
1384 set updating_action_id=NULL
1385 ,updating_action_type =NULL
1386 where ee.element_entry_id = p_ee_id
1387 and ee.effective_start_date = val_start;
1388 elsif(p_mode = 'FUTURE_CHANGE') then
1389 update pay_element_entries_f ee
1390 set updating_action_id=NULL
1391 ,updating_action_type =NULL
1392 where ee.element_entry_id = p_ee_id
1393 and ee.effective_start_date = effstart;
1394 end if;
1395 return;
1396 else
1397 -- Should fail if it is anything else.
1398 raise;
1399 end if;
1400 end;
1401 --
1402 -- Process the delete of element entries.
1403 if(p_mode = 'DELETE_NEXT_CHANGE') then
1404 hr_utility.set_location(c_indent, 40);
1405 delete from pay_element_entries_f ee
1406 where ee.element_entry_id = p_ee_id
1407 and ee.effective_start_date = val_start;
1408 --
1409 hr_utility.set_location(c_indent, 45);
1410 delete from pay_element_entry_values_f eev
1411 where eev.element_entry_id = p_ee_id
1412 and eev.effective_start_date = val_start;
1413 --
1414 hr_utility.set_location(c_indent, 50);
1415 update pay_element_entries_f ee
1416 set ee.effective_end_date = next_end
1417 where ee.element_entry_id = p_ee_id
1418 and ee.effective_start_date = effstart;
1419 --
1420 hr_utility.set_location(c_indent, 55);
1421 update pay_element_entry_values_f eev
1422 set eev.effective_end_date = next_end
1423 where eev.element_entry_id = p_ee_id
1424 and eev.effective_start_date = effstart;
1425 --
1426 elsif(p_mode = 'FUTURE_CHANGE') then
1427 --
1428 hr_utility.set_location(c_indent, 60);
1429 delete from pay_element_entries_f ee
1430 where ee.element_entry_id = p_ee_id
1431 and ee.effective_start_date > effstart;
1432 --
1433 hr_utility.set_location(c_indent, 65);
1434 delete from pay_element_entry_values_f eev
1435 where eev.element_entry_id = p_ee_id
1436 and eev.effective_start_date > effstart;
1437 --
1438 hr_utility.set_location(c_indent, 70);
1439 update pay_element_entries_f ee
1440 set ee.effective_end_date = max_end,
1441 ee.updating_action_id=NULL,
1442 ee.updating_action_type=NULL
1443 where ee.element_entry_id = p_ee_id
1444 and ee.effective_start_date = effstart;
1445 /*BUG#6200530*/
1446 /*check for the additional assignment id (in case of an STOP RECURRING after an UPDATE RECURRING)*/
1447 select ee.prev_upd_action_id
1448 into prev_asgact_id
1449 from pay_element_entries_f ee
1450 where ee.element_entry_id = p_ee_id
1451 and ee.effective_start_date = effstart;
1452 /*If it is the case then update the updating_action_id with the asg_action_id of the previous UPDATE RECURRING operation*/
1453 if(prev_asgact_id is not null) then
1454 update pay_element_entries_f ee
1455 set ee.updating_action_id=prev_asgact_id,
1456 ee.prev_upd_action_id=NULL,
1457 ee.updating_action_type='U'
1458 where ee.element_entry_id = p_ee_id
1459 and ee.effective_start_date = effstart;
1460 end if;
1461 /*End of BUG#6200530*/
1462 --
1463 hr_utility.set_location(c_indent, 75);
1464 update pay_element_entry_values_f eev
1465 set eev.effective_end_date = max_end
1466 where eev.element_entry_id = p_ee_id
1467 and eev.effective_start_date = effstart;
1468 end if;
1469 --
1470 end undo_stop_update;
1471 --
1472 /*
1473 * This procedure attempts to reverse the effects of stop and/or
1474 * update formula result rules. Due to the implementation of
1475 * this functionality, the undo is non-deterministic, i.e. we
1476 * cannot guarantee to return the database to the exact state
1477 * it was in before the Payroll Run or QuickPay was processed.
1478 */
1479 procedure proc_entry_dml(p_info in rollback_rec) is
1480 -- This cursor returns candidates for possible undo
1481 -- of stop ree frr. i.e. recurring entries that have
1482 -- an effective_end_date that is same as runs date earned.
1483 cursor stp is
1484 select pet.multiple_entries_allowed_flag,
1485 pee.element_entry_id,pee.updating_action_type
1486 from pay_element_types_f pet,
1487 pay_element_links_f pel,
1488 pay_element_entries_f pee
1489 where pee.assignment_id = p_info.assignment_id
1490 and pee.entry_type = 'E'
1491 and pel.element_link_id = pee.element_link_id
1492 and p_info.action_date between
1493 pel.effective_start_date and pel.effective_end_date
1494 and pet.element_type_id = pel.element_type_id
1495 and p_info.action_date between
1496 pet.effective_start_date and pet.effective_end_date
1497 and pet.processing_type = 'R'
1498 and pee.updating_action_id = p_info.assact_id
1499 and ((pee.effective_end_date = p_info.date_earned
1500 and pee.effective_start_date <> p_info.action_date
1501 and pee.updating_action_type is NULL
1502 and p_info.date_earned between
1503 pee.effective_start_date and pee.effective_end_date)
1504 or(pee.updating_action_type='S'));
1505
1506 --
1507 -- This cursor returns candidates for undo update ree frr.
1508 -- i.e. entries that have been updated on the date of the
1509 -- Payroll Run, by the updating assignment action.
1510 cursor upd is
1511 select pet.multiple_entries_allowed_flag,
1512 pee.element_entry_id
1513 from pay_element_types_f pet,
1514 pay_element_links_f pel,
1515 pay_element_entries_f pee
1516 where pee.assignment_id = p_info.assignment_id
1517 and pee.entry_type = 'E'
1518 and ((pee.effective_start_date = p_info.action_date
1519 and pee.updating_action_type is NULL)
1520 or pee.updating_action_type='U')
1521 and pee.updating_action_id = p_info.assact_id
1522 and pel.element_link_id = pee.element_link_id
1523 and p_info.action_date between
1524 pel.effective_start_date and pel.effective_end_date
1525 and pet.element_type_id = pel.element_type_id
1526 and p_info.action_date between
1527 pet.effective_start_date and pet.effective_end_date
1528 and pet.processing_type = 'R';
1529 --
1530 c_indent varchar2(40);
1531 v_max_date date; -- maximum entry end date
1532 begin
1533 if g_debug then
1534 c_indent := 'py_rollback_pkg.proc_entry_dml';
1535 hr_utility.set_location(c_indent,90);
1536 end if;
1537 -- Begin by processing for stop entry dml.
1538 for stprec in stp loop
1539
1540 if (stprec.updating_action_type is NULL)
1541 then
1542 -- We may have a stopped entry, but we need to
1543 -- see if this really is the case.
1544 if g_debug then
1545 hr_utility.set_location(c_indent,90);
1546 end if;
1547 select max(pee.effective_end_date)
1548 into v_max_date
1549 from pay_element_entries_f pee
1550 where pee.element_entry_id = stprec.element_entry_id;
1551 else
1552 v_max_date := p_info.date_earned;
1553 end if;
1554 --
1555 if(v_max_date = p_info.date_earned) then
1556 -- Assume entry has been chopped by the run.
1557 -- Call procedure to actually perform undo.
1558 undo_stop_update (stprec.element_entry_id,
1559 stprec.multiple_entries_allowed_flag,
1560 p_info.date_earned, 'FUTURE_CHANGE');
1561 end if;
1562 end loop;
1563 --
1564 -- Process for update entry dml.
1565 for updrec in upd loop
1566 -- Since it is not possible to use the Payroll Run to
1567 -- perform a correction on an entry, we know there
1568 -- should be an entry record existing on the date
1569 -- before the run. This is important, since it is
1570 -- required by the procedure that follows.
1571 undo_stop_update (updrec.element_entry_id,
1572 updrec.multiple_entries_allowed_flag,
1573 (p_info.action_date - 1), 'DELETE_NEXT_CHANGE');
1574 end loop;
1575 end proc_entry_dml;
1576 --
1577 --
1578 /*
1579 * Following the main work of rolling back or marking an
1580 * assignment action for retry, the assignment action
1581 * row itself (the 'base table' row) may need updating or
1582 * deleting. (Depends on the wishes of the client). In
1583 * addition, we may need to remove interlock rows.
1584 */
1585 procedure act_base_table_dml(p_info in rollback_rec) is
1586 c_indent constant varchar2(40) := 'py_rollback_pkg.act_base_table_dml';
1587 begin
1588 -- see if we want to alter the assignment action itself (we wouldn't
1589 -- if we were being called from a form).
1590 -- However, if we are called from the payroll action level,
1591 -- we must process the assignment action row.
1592 if(not p_info.leave_row or p_info.rollback_level = 'P') then
1593 if(p_info.rollback_mode) = 'RETRY' then
1594 if g_debug then
1595 hr_utility.set_location(c_indent, 10);
1596 end if;
1597 --
1598 update pay_assignment_actions
1599 set action_status = 'M'
1600 where source_action_id = p_info.assact_id;
1601 --
1602 update pay_assignment_actions
1603 set action_status = 'M'
1604 where assignment_action_id = p_info.assact_id;
1605 --
1606 elsif(p_info.rollback_mode) = 'BACKPAY' then
1607 if g_debug then
1608 hr_utility.set_location(c_indent, 20);
1609 end if;
1610 --
1611 update pay_assignment_actions
1612 set action_status = 'B'
1613 where source_action_id = p_info.assact_id;
1614 --
1615 update pay_assignment_actions
1616 set action_status = 'B'
1617 where assignment_action_id = p_info.assact_id;
1618 --
1619 elsif(p_info.rollback_mode) = 'ROLLBACK' then
1620 -- there may be pay_action_interlock rows.
1621 -- which are locking other assignment actions.
1622 if g_debug then
1623 hr_utility.set_location(c_indent, 30);
1624 end if;
1625 delete from pay_action_interlocks lck
1626 where lck.locking_action_id = p_info.assact_id;
1627 --
1628 remove_archive_items(p_info, p_info.assact_id, 'AAC');
1629 remove_action_information(p_info.assact_id, 'AAC');
1630 --
1631 delete from pay_assignment_actions
1632 where source_action_id = p_info.assact_id;
1633 --
1634 delete from pay_assignment_actions
1635 where assignment_action_id = p_info.assact_id;
1636 end if;
1637 else
1638 -- In the case of rolling back (from the form), we
1639 -- still need to delete interlock rows. Of course,
1640 -- in this case we do not delete the action.
1641 if(p_info.rollback_mode = 'ROLLBACK') then
1642 --
1643 remove_archive_items(p_info, p_info.assact_id, 'AAC');
1644 remove_action_information(p_info.assact_id, 'AAC');
1645 --
1646 delete from pay_assignment_actions
1647 where source_action_id = p_info.assact_id;
1648 --
1649 delete from pay_action_interlocks lck
1650 where lck.locking_action_id = p_info.assact_id;
1651 --
1652 end if;
1653 end if;
1654 end act_base_table_dml;
1655 --
1656 /*---------------------- do_assact_rollback -------------------------------*/
1657 /*
1658 NAME
1659 do_assact_rollback - Perform dml to rollback assignment action.
1660 DESCRIPTION
1661 performs rollback/mark for retry dml for assignment action.
1662 NOTES
1663 This internal routine is central to the rollback process. It does
1664 the actual work of rolling back/marking for retry an assignment
1665 action. The routine makes no checks for validity of the action.
1666 --
1667 There are nested procedures to perform many of the specific
1668 actions required. This is in an attempt to keep the logic
1669 more understandable.
1670 */
1671 procedure do_assact_rollback(p_info in rollback_rec) is
1672 c_indent varchar2(40);
1673 chld_info rollback_rec;
1674 purge_child boolean;
1675 --
1676 v_prj_flg_yes_count number;
1677 v_prj_flg_no_count number;
1678 v_prj_flg_x_count number;
1679 v_return_status varchar2(40);
1680 v_person_id per_all_people_f.person_id%TYPE;
1681 v_time_period_id per_time_periods.time_period_id%TYPE;
1682 --
1683 cursor chdact (p_asgact_id in number) is
1684 select paa_chd.assignment_action_id
1685 from pay_assignment_actions paa_chd
1686 where paa_chd.source_action_id = p_asgact_id
1687 order by paa_chd.action_sequence desc;
1688 --
1689 cursor get_person_id (p_assignment_id in per_all_people_f.person_id%TYPE, p_effective_date in date) is
1690 select PERSON_ID
1691 from per_all_assignments_f paaf
1692 where paaf.assignment_id = p_assignment_id
1693 and p_effective_date between paaf.effective_start_date and paaf.effective_end_date;
1694 --
1695 cursor get_time_period_id (p_payroll_id in pay_payrolls_f.payroll_id%TYPE, p_effective_date in date) is
1696 select time_period_id
1697 from per_time_periods ptp
1698 where ptp.payroll_id = p_payroll_id
1699 and p_effective_date between ptp.start_date and ptp.end_date;
1700 --
1701 begin
1702 --
1703 if g_debug then
1704 c_indent := 'py_rollback_pkg.do_assact_rollback';
1705 hr_utility.set_location(c_indent, 10);
1706 hr_utility.set_location('p_info.assact_id'||p_info.assact_id,11);
1707 hr_utility.set_location('p_info.action_date'||p_info.action_date,12);
1708 hr_utility.set_location('p_info.pact_id'||p_info.pact_id,13);
1709 end if;
1710 --
1711 -- Firstly remove any child actions.
1712 chld_info := p_info;
1713 for chdrec in chdact (p_info.assact_id) loop
1714 chld_info.assact_id := chdrec.assignment_action_id;
1715 do_assact_rollback(chld_info);
1716 --
1717 -- Remove child assignment actions if needed.
1718 purge_child := TRUE;
1719 --
1720 if (p_info.rollback_mode = 'BACKPAY'
1721 and p_info.retro_purge = 'N') then
1722 purge_child := FALSE;
1723 end if;
1724 --
1725 -- If its an Enhanced retropay by Ele and using the
1726 -- process group level interlocking then do not
1727 -- remove the child actions.
1728 if (p_info.retro_definition_id is not null
1729 and p_info.independent_periods_flag = 'G') then
1730 purge_child := FALSE;
1731 end if;
1732 --
1733 if (purge_child = TRUE) then
1734 delete from pay_action_interlocks
1735 where locking_action_id = chld_info.assact_id;
1736 if g_debug then
1737 hr_utility.set_location('About to remove assg actions' , 11);
1738 end if;
1739 delete from pay_assignment_actions
1740 where assignment_action_id = chld_info.assact_id;
1741 end if;
1742 end loop;
1743 --
1744 -- Perform actions that are specific to sequenced actions.
1745 -- In other words, remove the rows that are only inserted
1746 -- by these types of actions.
1747 --
1748 if(p_info.sequenced_flag) then
1749 --
1750 -- if the assignment being rolled back contributes to a group run balance
1751 -- need to remove the contributing amount from the group run balance.
1752 --
1753 if (p_info.rollback_mode <> 'BACKPAY') then
1754 pay_balance_pkg.remove_asg_contribs(p_info.pact_id
1755 ,p_info.assact_id
1756 ,p_info.grp_multi_thread);
1757 --
1758 -- now delete assignment level run balances
1759 --
1760 delete from pay_run_balances
1761 where assignment_action_id = p_info.assact_id;
1762 else
1763 --
1764 -- now update assignment level run balances
1765 --
1766 update pay_run_balances
1767 set balance_value = 0
1768 where assignment_action_id = p_info.assact_id;
1769 end if;
1770 --
1771 remove_balances(p_info); -- latest balances.
1772 remove_run_results(p_info); -- run results and values.
1773 remove_action_contexts(p_info.assact_id); -- action contexts
1774 end if;
1775 --
1776 -- Delete specific types of rows for certain action types.
1777 if((p_info.action_type = 'B' and p_info.rollback_mode = 'ROLLBACK') OR
1778 (p_info.action_type = 'I' )) then
1779 --
1780 -- OK here's the scoop. If we are in rollback mode
1781 -- then remove the element entries for bal adjust
1782 --
1783 -- Otherwise we must be in Retry mode, hence only remove the
1784 -- Entries if it is a formula based balance adjustment.
1785 --
1786 -- entries/values for bal adjust.
1787 if (p_info.rollback_mode = 'ROLLBACK' or p_info.action_type = 'I') then
1788 undo_bal_adjust(p_info.action_date, p_info.assact_id);
1789 else
1790 declare
1791 l_et_id pay_payroll_actions.element_type_id%type;
1792 begin
1793 --
1794 select ppa.element_type_id
1795 into l_et_id
1796 from pay_assignment_actions paa,
1797 pay_payroll_actions ppa
1798 where ppa.payroll_action_id = paa.payroll_action_id
1799 and paa.assignment_action_id = p_info.assact_id;
1800 --
1801 if (l_et_id is not null) then
1802 undo_bal_adjust(p_info.action_date, p_info.assact_id);
1803 end if;
1804 --
1805 end;
1806 end if;
1807 --
1808 elsif(p_info.action_type in ('R', 'Q')) then
1809 proc_entry_dml(p_info); -- stop/update ree frr.
1810 --
1811 elsif(p_info.action_type in ('P', 'U')) then
1812 -- Remove pre-payment rows.
1813 -- Note, this causes cascade delete of pay_coin_anal_elements.
1814 if g_debug then
1815 hr_utility.set_location('Error abt to occur', 13);
1816 end if;
1817 delete from pay_pre_payments ppp
1818 where ppp.assignment_action_id = p_info.assact_id;
1819 --
1820 elsif(p_info.action_type in ('C', 'S', 'EC')) then
1821 -- Remove costing rows.
1822 if g_debug then
1823 hr_utility.set_location(c_indent, 20);
1824 end if;
1825 --Bug 11708644, PAYROLL/PROJECTS INTEGRATION changes FOR 12.2 starts here
1826 -- Check for transfered_to_prj flag.
1827 SELECT count(DECODE(transfered_to_prj,'Y','YES',NULL)) AS prj_flg_yes_count,
1828 count(DECODE(transfered_to_prj,'N','No',NULL)) AS prj_flg_no_count,
1829 count(DECODE(transfered_to_prj,'X','X',NULL)) AS prj_flg_x_count
1830 INTO v_prj_flg_yes_count,v_prj_flg_no_count,v_prj_flg_x_count
1831 from pay_costs pc
1832 where pc.assignment_action_id = p_info.assact_id;
1833 --
1834 if(v_prj_flg_yes_count <> 0) then
1835 hr_utility.set_message(801, 'PAY_449895_STP_RETRY_RLBK_COST');
1836 hr_utility.set_message_token('ASGN_ID', p_info.assignment_number);
1837 hr_utility.raise_error;
1838 elsif(v_prj_flg_no_count <> 0 OR v_prj_flg_x_count <> 0) then
1839 --
1840 if g_debug then
1841 hr_utility.set_location(c_indent, 21);
1842 end if;
1843 --
1844 -- First get personid, time_period_id, these are needed by projects
1845 open get_person_id(p_info.assignment_id,p_info.action_date);
1846 fetch get_person_id into v_person_id;
1847 close get_person_id;
1848 --
1849 open get_time_period_id(p_info.payroll_id,p_info.action_date);
1850 fetch get_time_period_id into v_time_period_id;
1851 close get_time_period_id;
1852 --
1853 -- Now call the projects audit API
1854 PA_PAY_UTIL.update_pa_audit (
1855 P_PAYROLL_ACTION_ID => p_info.pact_id,
1856 P_PAYROLL_ID => p_info.payroll_id,
1857 P_TIME_PERIOD_ID => v_time_period_id,
1858 P_PERSON_ID => v_person_id,
1859 P_ASSIGNMENT_ID => p_info.assignment_id,
1860 X_RETURN_STATUS => v_return_status
1861 );
1862 if g_debug then
1863 hr_utility.trace('Return status of projects audit API: ' || v_return_status);
1864 end if;
1865 -- Perform actual rollback
1866 delete from pay_costs pc
1867 where pc.assignment_action_id = p_info.assact_id;
1868 --
1869 ELSE
1870 --
1871 if g_debug then
1872 hr_utility.set_location(c_indent, 22);
1873 end if;
1874 -- Perform only rollback
1875 delete from pay_costs pc
1876 where pc.assignment_action_id = p_info.assact_id;
1877 --
1878 end if;
1879 if g_debug then
1880 hr_utility.set_location(c_indent, 25);
1881 end if;
1882 --Bug 11708644, PAYROLL/PROJECTS INTEGRATION changes FOR 12.2 end here
1883 --
1884 elsif(p_info.action_type = 'CP') then
1885 -- Remove costing rows.
1886 delete from pay_payment_costs ppc
1887 where ppc.assignment_action_id = p_info.assact_id;
1888 --
1889 elsif(p_info.action_type = 'T') then
1890 -- Remove intermediate transfer table rows.
1891 if (p_info.sub_ledger_acc = 'N') then
1892 remove_gl_entries(p_info);
1893 else
1894 pay_sla_pkg.delete_event(p_info.assact_id);
1895 end if;
1896 --
1897 elsif(p_info.action_type = 'M') then
1898 -- Reset prenote date if this is a dummy payment i.e. payment value
1899 -- of zero.
1900 reset_prenote(p_info.assact_id);
1901 remove_archive_items(p_info, p_info.assact_id, 'AAP');
1902 remove_file_details(p_info, p_info.assact_id, 'PAA');
1903 --
1904 elsif(p_info.action_type = 'PP') then
1905 remove_archive_items(p_info, p_info.assact_id, 'AAP');
1906 remove_file_details(p_info, p_info.assact_id, 'PAA');
1907 --
1908 elsif(p_info.action_type = 'O') then
1909 -- Remove Retropay rows.
1910 remove_retro_ee(p_info.assact_id);
1911 --
1912 elsif(p_info.action_type = 'F') then
1913 -- Remove Advance pay rows.
1914 remove_adv_ee(p_info.assact_id);
1915 --
1916 elsif(p_info.action_type = 'X') then
1917 --Remove Archive Items
1918 remove_archive_items(p_info, p_info.assact_id, 'AAP');
1919 remove_action_information(p_info.assact_id, 'AAP');
1920 remove_file_details(p_info, p_info.assact_id, 'PAA');
1921 --
1922 elsif(p_info.action_type = 'G') then
1923 -- Remove Retropay by Action rows
1924 remove_retroact_ee(p_info.assact_id);
1925 --
1926 elsif(p_info.action_type = 'L') then
1927 -- Remove Retropay by Element rows
1928 remove_retroele_ee(p_info.assact_id, p_info.rollback_mode);
1929 --
1930 -- The following logic in now moved within the above procedure.
1931 --
1932 -- -- Finally reset the pay_retro_assignment_table if needed
1933 -- if (p_info.rollback_mode <> 'RETRY') then
1934 --
1935 -- pay_retro_pkg.merge_retro_assignments(p_info.assact_id);
1936 --
1937 -- -- Remove the asg act id, and in case merge has new earlier entries
1938 -- -- also change the reprocess_date
1939 -- update pay_retro_assignments ra
1940 -- set ra.retro_assignment_action_id = null,
1941 -- ra.reprocess_date = nvl( (
1942 -- select min(effective_date)
1943 -- from pay_retro_entries re
1944 -- where re.retro_assignment_id = ra.retro_assignment_id )
1945 -- ,ra.reprocess_date)
1946 -- where ra.retro_assignment_action_id = p_info.assact_id;
1947 --
1948 -- end if;
1949 --
1950 elsif(p_info.action_type = 'W') then
1951 -- Remove Advance Pay by Element rows
1952 remove_advpayele_ee(p_info.assact_id);
1953 --
1954 elsif(p_info.action_type = 'Z') then
1955 -- Remove the purge rollup balance rows.
1956 delete from pay_purge_rollup_balances rub
1957 where rub.assignment_action_id = p_info.assact_id;
1958 elsif(p_info.action_type = 'BEE') then
1959 -- Remove Batch Element Entry rows
1960 pay_mix_rollback_pkg.undo_mix_asg(p_info.assact_id);
1961 elsif(p_info.action_type = 'PRU') then
1962 -- Remove Rolled up payments
1963 delete from pay_contributing_payments
1964 where assignment_action_id = p_info.assact_id;
1965 end if;
1966 --
1967 -- Delete messages for the assignment action.
1968 remove_messages(p_info, 'A');
1969 --
1970 -- Rollback specific code.
1971 if(p_info.rollback_mode = 'ROLLBACK') then
1972 -- Insert message indicating rollback of assignment action.
1973 -- Only insert message if action is not an initial
1974 -- balance adjustment.
1975 if (p_info.action_type <> 'I') then
1976 ins_rollback_message(p_info, 'A');
1977 end if;
1978 --
1979 -- When we are rolling back QuickPay, we need to
1980 -- remove the QuickPay Inclusions.
1981 if(p_info.action_type = 'Q') then
1982 if g_debug then
1983 hr_utility.set_location(c_indent, 30);
1984 end if;
1985 --
1986 -- Enhancement 3368211
1987 --
1988 -- Delete from both PAY_QUICKPAY_INCLUSIONS and PAY_QUICKPAY_EXCLUSIONS.
1989 --
1990 -- There is a chance the assignment action id exists in both tables if
1991 -- the assignment action was created before the QuickPay Exclusions
1992 -- data model was in use.
1993 --
1994 delete from pay_quickpay_exclusions exc
1995 where exc.assignment_action_id = p_info.assact_id;
1996 --
1997 delete from pay_quickpay_inclusions inc
1998 where inc.assignment_action_id = p_info.assact_id;
1999 --
2000 end if;
2001 end if;
2002 --
2003 -- Following main processing, may need to do some
2004 -- work on the assignment action row itself.
2005 act_base_table_dml(p_info);
2006 --
2007 --
2008 end do_assact_rollback;
2009 --
2010 /*
2011 * Internal procedure : called for an individual assignment
2012 * action to validate that a rollback or mark for retry is
2013 * legal. Note, it does not guarantee that the rollback
2014 * will succeed, as this does not perform any dml.
2015 *
2016 * Assumes that val_pact_rollback has already been called
2017 * to obtain payroll action level information.
2018 */
2019 procedure val_assact_rollback(p_info in out nocopy rollback_rec)
2020 is
2021 l_action_sequence pay_assignment_actions.action_sequence%type;
2022 l_action_status pay_assignment_actions.action_status%type;
2023 l_person_id per_all_people_f.person_id%type;
2024 l_sec_status pay_assignment_actions.secondary_status%type;
2025 c_indent varchar2(40);
2026 begin
2027 -- Obtain information about this assignment action which we will
2028 -- need later on.
2029 -- Some of this is required for messages.
2030 if g_debug then
2031 c_indent := 'py_rollback_pkg.val_assact_rollback';
2032 hr_utility.trace('assact_id : ' || p_info.assact_id);
2033 end if;
2034 --
2035 -- OK We need to run different statements for different types
2036 -- of processes
2037 --
2038 hr_utility.set_location(c_indent, 10);
2039 if ((p_info.action_type = 'L'
2040 and p_info.object_type = 'POG')
2041 or p_info.object_type is not null
2042 ) then
2043 --
2044 if (p_info.action_type = 'L') then
2045 --
2046 hr_utility.set_location(c_indent, 20);
2047 -- OK this is a retropay that using the Object Group
2048 -- actions
2049 select null,
2050 ACT.action_sequence,
2051 ACT.action_status,
2052 ACT.secondary_status,
2053 null,
2054 PEO.person_id,
2055 substr(PEO.full_name,1,80),
2056 null
2057 into p_info.assignment_id,
2058 l_action_sequence,
2059 l_action_status,
2060 l_sec_status,
2061 p_info.payroll_id,
2062 l_person_id,
2063 p_info.full_name,
2064 p_info.assignment_number
2065 from
2066 per_all_people_f PEO,
2067 pay_object_groups POG_PER,
2068 pay_assignment_actions ACT
2069 where ACT.assignment_action_id = p_info.assact_id
2070 and ACT.source_action_id is null
2071 and ACT.object_id = POG_PER.object_group_id
2072 and POG_PER.source_id = PEO.person_id
2073 and p_info.action_date between
2074 PEO.effective_start_date and PEO.effective_end_date;
2075 else
2076 --
2077 hr_utility.set_location(c_indent, 30);
2078 -- OK its some sort of object action
2079 select null,
2080 ACT.action_sequence,
2081 ACT.action_status,
2082 ACT.secondary_status,
2083 null,
2084 null,
2085 null,
2086 null
2087 into p_info.assignment_id,
2088 l_action_sequence,
2089 l_action_status,
2090 l_sec_status,
2091 p_info.payroll_id,
2092 l_person_id,
2093 p_info.full_name,
2094 p_info.assignment_number
2095 from pay_assignment_actions ACT
2096 where ACT.assignment_action_id = p_info.assact_id;
2097 --
2098 end if;
2099 --
2100 else
2101 --
2102 hr_utility.set_location(c_indent, 40);
2103 -- It's a normal action
2104 --
2105 select ACT.assignment_id,
2106 ACT.action_sequence,
2107 ACT.action_status,
2108 ACT.secondary_status,
2109 ASS.payroll_id,
2110 PEO.person_id,
2111 substr(PEO.full_name,1,80),
2112 ASS.assignment_number
2113 into p_info.assignment_id,
2114 l_action_sequence,
2115 l_action_status,
2116 l_sec_status,
2117 p_info.payroll_id,
2118 l_person_id,
2119 p_info.full_name,
2120 p_info.assignment_number
2121 from per_all_assignments_f ASS,
2122 per_all_people_f PEO,
2123 pay_assignment_actions ACT
2124 where ACT.assignment_action_id = p_info.assact_id
2125 and ASS.assignment_id = ACT.assignment_id
2126 and PEO.person_id = ASS.person_id
2127 and ((p_info.action_type = 'X'
2128 and ASS.effective_start_date = (select max(ASS2.effective_start_date)
2129 from per_all_assignments_f ASS2
2130 where ASS2.assignment_id = ASS.assignment_id)
2131 and PEO.effective_start_date = (select max(PEO2.effective_start_date)
2132 from per_all_people_f PEO2
2133 where PEO2.person_id = PEO.person_id)
2134 )
2135 or
2136 ((p_info.action_type = 'Z' or p_info.action_type = 'PRU')
2137 and ASS.effective_start_date = (select max(ASS2.effective_start_date)
2138 from per_all_assignments_f ASS2
2139 where ASS2.assignment_id = ASS.assignment_id
2140 and ASS2.effective_start_date <= p_info.action_date)
2141 and PEO.effective_start_date = (select max(PEO2.effective_start_date)
2142 from per_all_people_f PEO2
2143 where PEO2.person_id = PEO.person_id
2144 and PEO2.effective_start_date <= p_info.action_date)
2145 )
2146 or
2147 (p_info.action_type = 'BEE'
2148 and ASS.effective_start_date = (select max(ASS2.effective_start_date)
2149 from per_all_assignments_f ASS2,
2150 pay_batch_lines pbl
2151 where ASS2.assignment_id = ASS.assignment_id
2152 and pbl.batch_id (+) = p_info.batch_id
2153 and pbl.assignment_id (+) = ASS.assignment_id
2154 and pbl.effective_Date (+) between ASS2.effective_start_date
2155 and ASS2.effective_end_date)
2156 and PEO.effective_start_date = (select max(PEO2.effective_start_date)
2157 from per_all_people_f PEO2,
2158 pay_batch_lines pbl
2159 where PEO2.person_id = PEO.person_id
2160 and PEO2.person_id = ASS.person_id
2161 and pbl.batch_id (+) = p_info.batch_id
2162 and pbl.assignment_id (+) = ASS.assignment_id
2163 and pbl.effective_Date (+) between PEO2.effective_start_date
2164 and PEO2.effective_end_date)
2165 )
2166 or
2167 (p_info.action_type not in ('BEE','Z','X', 'PRU')
2168 and p_info.action_date between
2169 ASS.effective_start_date and ASS.effective_end_date
2170 and p_info.action_date between
2171 PEO.effective_start_date and PEO.effective_end_date));
2172 end if;
2173 --
2174 hr_utility.set_location(c_indent, 50);
2175 --
2176 -- for Purge, we simply wish to confirm that we are not
2177 -- attempting to rollback an assignment action that has
2178 -- a 'C' secondary status. If everything ok, we simpy
2179 -- exit this procedure.
2180 if(p_info.action_type = 'Z') then
2181 if(l_sec_status = 'C') then
2182 hr_utility.set_message(801, 'PAY_289118_PUR_NACT_ROLLBACK');
2183 hr_utility.raise_error;
2184 end if;
2185 --
2186 if g_debug then
2187 hr_utility.trace('Purge act : exit');
2188 end if;
2189 return;
2190 end if;
2191 --
2192 -- can only retry if already complete
2193 if(p_info.rollback_mode = 'RETRY' and l_action_status not in ('C', 'S'))
2194 then
2195 hr_utility.set_message (801, 'HR_7506_ACTION_RET_NOT_COMP');
2196 hr_utility.set_message_token ('ASG_NO', p_info.assignment_number);
2197 hr_utility.raise_error;
2198 end if;
2199 --
2200 --
2201 --
2202 -- If rolling back or retrying, we need to know if assignments
2203 -- can be considered in isolation (as prescribed by the
2204 -- independent time periods flag for this legislation). Assignments
2205 -- with no Payroll are independent.
2206 --
2207 -- Operation is disallowed if this is a sequenced action AND there
2208 -- exists any sequenced actions in the future. Also disallowed
2209 -- if any child action exists (e.g can't rollback a run if already
2210 -- costed).
2211 -- Note - exception is if are attempting to roll back Reversal or
2212 -- Balance Adjustment actions, where we do not bother to perform
2213 -- the future actions check.
2214 --
2215 declare
2216 dummy number;
2217 begin
2218 -- For either legislation, examine the assignment action
2219 -- to see if it is locked by another action. Peform
2220 -- slightly different checks for RETRY and ROLLBACK
2221 -- modes. See comments below.
2222 if(p_info.rollback_mode = 'RETRY')
2223 then
2224 -- Case for RETRY mode.
2225 -- Check that the assignment action we are attempting to
2226 -- mark for retry is not locked by an assignment action
2227 -- that has an action_status that is not mark for retry.
2228 --
2229 -- Bug 1923535. If the locking action is a Payments Process and has
2230 -- been 'Marked for Retry' then the locked action cannot be
2231 -- 'Marked for Retry'.
2232 --
2233 if g_debug then
2234 hr_utility.set_location(c_indent, 20);
2235 end if;
2236 select null
2237 into dummy
2238 from dual
2239 where not exists (
2240 select null
2241 from pay_action_interlocks int,
2242 pay_assignment_actions act
2243 where int.locked_action_id = p_info.assact_id
2244 and act.assignment_action_id = int.locking_action_id
2245 and ((exists
2246 (select null
2247 from pay_payroll_actions pac
2248 where pac.payroll_action_id = act.payroll_action_id
2249 and action_type in ('A','H','M', 'PP', 'PRU')
2250 and act.action_status = 'M'
2251 )
2252 )
2253 or act.action_status <> 'M'
2254 ));
2255 else
2256 -- Case for ROLLBACK mode.
2257 -- Check that the assignment action we are attempting to
2258 -- roll back is not locked by an assignment action.
2259 if g_debug then
2260 hr_utility.set_location(c_indent, 30);
2261 hr_utility.trace('Case for ROLLBACK mode');
2262 hr_utility.trace('before checking for interlocking in action interlocks');
2263 end if;
2264 select null
2265 into dummy
2266 from dual
2267 where not exists (
2268 select null
2269 from pay_action_interlocks int
2270 where int.locked_action_id = p_info.assact_id);
2271 end if;
2272 --
2273 -- Now, the following checks are only applicable to sequenced
2274 -- actions, excluding Balance Adjustment and Reversal. These
2275 -- are special cases.
2276 if (p_info.sequenced_flag and
2277 (p_info.action_type <> 'B' and p_info.action_type <> 'I'
2278 and p_info.action_type <> 'V'))
2279 then
2280 -- Check the legislation case.
2281 if(p_info.independent_periods_flag = 'Y')
2282 then
2283 -- Check for other actions on this ASSIGNMENT
2284 -- Perform different checks for RETRY or ROLLBACK.
2285 -- We deal with both 'RETRY' and 'ROLLBACK' (BACKPAY) cases.
2286 --
2287 -- For RETRY:
2288 -- disallow mark for retry assignment action if there are
2289 -- future SEQUENCED assignment actions for the assignment
2290 -- that are not marked for retry. (Nested mark for retry).
2291 --
2292 -- For ROLLBACK (and BACKPAY):
2293 -- disallow rollback assignment action if there are
2294 -- future SEQUENCED assignment actions for the assignment.
2295 if g_debug then
2296 hr_utility.trace('The p_info.independent_periods_flag is Y');
2297 hr_utility.set_location(c_indent, 40);
2298 end if;
2299 --
2300 if (p_info.rollback_mode = 'RETRY')
2301 then
2302 select null into dummy
2303 from dual
2304 where not exists
2305 (select null
2306 from pay_assignment_actions ACT,
2307 pay_payroll_actions PACT,
2308 pay_action_classifications CLASS
2309 where ACT.assignment_id = p_info.assignment_id
2310 and ACT.action_sequence > l_action_sequence
2311 and ACT.action_status in ('C', 'S')
2312 and ACT.payroll_action_id = PACT.payroll_action_id
2313 and PACT.action_type = CLASS.action_type
2314 and CLASS.classification_name = 'SEQUENCED');
2315 else
2316 select null into dummy
2317 from dual
2318 where not exists
2319 (select null
2320 from pay_assignment_actions ACT,
2321 pay_payroll_actions PACT,
2322 pay_action_classifications CLASS
2323 where ACT.assignment_id = p_info.assignment_id
2324 and ACT.action_sequence > l_action_sequence
2325 and ACT.action_status in ('C', 'S','M')
2326 and ACT.payroll_action_id = PACT.payroll_action_id
2327 and PACT.action_type = CLASS.action_type
2328 and CLASS.classification_name = 'SEQUENCED'
2329 and NVL(PACT.legislative_parameters,'TEST') <> 'PAY_SIM');
2330 end if;
2331 --
2332 elsif (p_info.independent_periods_flag = 'G') then
2333 hr_utility.trace('The p_info.independent_periods_flag is G');
2334 --
2335 -- There are 2 Types of processes here. They are
2336 -- either processing at the assignment level but
2337 -- doing Group interlocking or are processing
2338 -- at the group level
2339 --
2340 if (p_info.object_type is not null
2341 and p_info.object_type = 'POG') then
2342 if (p_info.rollback_mode = 'RETRY')
2343 then
2344 select null into dummy
2345 from dual
2346 where not exists
2347 (select null
2348 from pay_action_classifications CLASS,
2349 pay_payroll_actions PACT,
2350 pay_assignment_actions ACT,
2351 pay_object_groups POG_ASG,
2352 pay_object_groups POG_PER,
2353 pay_assignment_actions PAA_RET
2354 where PAA_RET.assignment_action_id = p_info.assact_id
2355 and POG_PER.object_group_id = PAA_RET.object_id
2356 and POG_PER.source_type = 'PPF'
2357 and POG_ASG.parent_object_group_id = POG_PER.object_group_id
2358 and POG_ASG.source_type = 'PAF'
2359 and POG_ASG.source_id = ACT.assignment_id
2360 and ACT.action_sequence > l_action_sequence
2361 and ACT.action_status in ('C', 'S')
2362 and ACT.payroll_action_id = PACT.payroll_action_id
2363 and PACT.action_type = CLASS.action_type
2364 and CLASS.classification_name = 'SEQUENCED');
2365 else
2366 select null into dummy
2367 from dual
2368 where not exists
2369 (select null
2370 from pay_action_classifications CLASS,
2371 pay_payroll_actions PACT,
2372 pay_assignment_actions ACT,
2373 pay_object_groups POG_ASG,
2374 pay_object_groups POG_PER,
2375 pay_assignment_actions PAA_RET
2376 where PAA_RET.assignment_action_id = p_info.assact_id
2377 and POG_PER.object_group_id = PAA_RET.object_id
2378 and POG_PER.source_type = 'PPF'
2379 and POG_ASG.parent_object_group_id = POG_PER.object_group_id
2380 and POG_ASG.source_type = 'PAF'
2381 and POG_ASG.source_id = ACT.assignment_id
2382 and ACT.action_sequence > l_action_sequence
2383 and ACT.action_status in ('C', 'S', 'M')
2384 and ACT.payroll_action_id = PACT.payroll_action_id
2385 and PACT.action_type = CLASS.action_type
2386 and CLASS.classification_name = 'SEQUENCED'
2387 and NVL(PACT.legislative_parameters,'TEST') <> 'PAY_SIM');
2388 end if;
2389 else
2390 if (p_info.rollback_mode = 'RETRY')
2391 then
2392
2393 select null into dummy
2394 from dual
2395 where not exists
2396 (select null
2397 from pay_action_classifications CLASS,
2398 pay_payroll_actions PACT,
2399 pay_assignment_actions ACT,
2400 pay_object_groups POG_ASG,
2401 pay_object_groups POG_ASG2
2402 where POG_ASG.source_type = 'PAF'
2403 and POG_ASG2.source_type = 'PAF'
2404 and POG_ASG.source_id = p_info.assignment_id
2405 and POG_ASG.parent_object_group_id = POG_ASG2.parent_object_group_id
2406 and POG_ASG2.source_id = ACT.assignment_id
2407 and ACT.action_sequence > l_action_sequence
2408 and ACT.action_status in ('C', 'S')
2409 and ACT.payroll_action_id = PACT.payroll_action_id
2410 and PACT.action_type = CLASS.action_type
2411 and CLASS.classification_name = 'SEQUENCED');
2412 else
2413 select null into dummy
2414 from dual
2415 where not exists
2416 (select null
2417 from pay_action_classifications CLASS,
2418 pay_payroll_actions PACT,
2419 pay_assignment_actions ACT,
2420 pay_object_groups POG_ASG,
2421 pay_object_groups POG_ASG2
2422 where POG_ASG.source_type = 'PAF'
2423 and POG_ASG2.source_type = 'PAF'
2424 and POG_ASG.source_id = p_info.assignment_id
2425 and POG_ASG.parent_object_group_id = POG_ASG2.parent_object_group_id
2426 and POG_ASG2.source_id = ACT.assignment_id
2427 and ACT.action_sequence > l_action_sequence
2428 and ACT.action_status in ('C', 'S', 'M')
2429 and ACT.payroll_action_id = PACT.payroll_action_id
2430 and PACT.action_type = CLASS.action_type
2431 and CLASS.classification_name = 'SEQUENCED'
2432 and NVL(PACT.legislative_parameters,'TEST') <> 'PAY_SIM');
2433 end if;
2434 end if;
2435 --
2436 else
2437 -- check for other actions on this PERSON.
2438 if g_debug then
2439 hr_utility.set_location(c_indent, 50);
2440 hr_utility.trace('case where p_info.independent_periods_flag is N');
2441 end if;
2442 --
2443 --
2444 if (p_info.rollback_mode = 'RETRY')
2445 then
2446 select null into dummy
2447 from dual
2448 where not exists
2449 (select null
2450 from pay_action_classifications CLASS,
2451 pay_payroll_actions PACT,
2452 pay_assignment_actions ACT,
2453 per_all_assignments_f ASS,
2454 per_periods_of_service POS
2455 where POS.person_id = l_person_id
2456 and ASS.period_of_service_id = POS.period_of_service_id
2457 and ACT.assignment_id = ASS.assignment_id
2458 and ACT.action_sequence > l_action_sequence
2459 and ACT.action_status in ('C', 'S')
2460 and ACT.payroll_action_id = PACT.payroll_action_id
2461 and PACT.action_type = CLASS.action_type
2462 and CLASS.classification_name = 'SEQUENCED');
2463 else
2464 select null into dummy
2465 from dual
2466 where not exists
2467 (select null
2468 from pay_action_classifications CLASS,
2469 pay_payroll_actions PACT,
2470 pay_assignment_actions ACT,
2471 per_all_assignments_f ASS,
2472 per_periods_of_service POS
2473 where POS.person_id = l_person_id
2474 and ASS.period_of_service_id = POS.period_of_service_id
2475 and ACT.assignment_id = ASS.assignment_id
2476 and ACT.action_sequence > l_action_sequence
2477 and ACT.action_status in ('C', 'S', 'M')
2478 and ACT.payroll_action_id = PACT.payroll_action_id
2479 and PACT.action_type = CLASS.action_type
2480 and CLASS.classification_name = 'SEQUENCED'
2481 and NVL(PACT.legislative_parameters,'TEST') <> 'PAY_SIM');
2482 end if;
2483 --
2484 end if;
2485 end if;
2486 --
2487 -- When rolling back a void payment then ensure that the void is against the
2488 -- latest chequewriter run for the payment.
2489 --
2490 if p_info.action_type = 'D' then
2491 select null
2492 into dummy
2493 from dual
2494 where not exists (select null
2495 from
2496 pay_assignment_actions paac2,
2497 pay_assignment_actions paac,
2498 pay_action_interlocks pai
2499 where pai.locking_action_id = p_info.assact_id
2500 and pai.locked_action_id = paac.assignment_action_id
2501 and paac.pre_payment_id = paac2.pre_payment_id
2502 and paac2.action_sequence > paac.action_sequence);
2503 end if;
2504 --
2505 exception
2506 when no_data_found then
2507 -- Catch all interlock failure message.
2508 if p_info.legislation_code = 'GB' then
2509 hr_utility.set_message (801, 'HR_52975_ACTION_UNDO_INTLOK_GB');
2510 else
2511 hr_utility.set_message (801, 'HR_7507_ACTION_UNDO_INTLOCK');
2512 end if;
2513 hr_utility.raise_error;
2514 end;
2515 end val_assact_rollback;
2516 --
2517 /*
2518 * assignment level error handler. When we encounter
2519 * an assignment level error, we call this procedure.
2520 * This controls the counting of errors and writing
2521 * messages to the message lines table.
2522 */
2523 procedure assact_error(p_info in rollback_rec,
2524 error_code in number, error_message in varchar2) is
2525 c_indent varchar2(40);
2526 message_text pay_message_lines.line_text%type;
2527 begin
2528 if g_debug then
2529 c_indent := 'py_rollback_pkg.assact_error';
2530 hr_utility.set_location(c_indent, 10);
2531 end if;
2532 --
2533 -- handle the assignment action level error.
2534 -- get the message text to write. Need to get it
2535 -- in diffferent ways for oracle and user errors.
2536 if(error_code = hr_utility.hr_error_number)
2537 then
2538 -- specific exception raised.
2539 message_text := substrb(hr_utility.get_message, 1, 240);
2540 else
2541 -- oracle error.
2542 message_text := error_message;
2543 end if;
2544 --
2545 -- we can now insert the messge to message lines.
2546 if g_debug then
2547 hr_utility.set_location(c_indent, 10);
2548 end if;
2549 insert into pay_message_lines (
2550 line_sequence,
2551 payroll_id,
2552 message_level,
2553 source_id,
2554 source_type,
2555 line_text)
2556 values (pay_message_lines_s.nextval,
2557 p_info.payroll_id,
2558 'F', -- it's a fatal message.
2559 p_info.assact_id,
2560 'A', -- assignment action level.
2561 message_text);
2562 --
2563 pay_core_utils.push_message(801, null, message_text, 'F');
2564 --
2565 -- keep track of the number of errors
2566 -- fail if we have had too many.
2567 g_error_count := g_error_count + 1;
2568 --
2569 if(g_error_count > p_info.max_errors_allowed)
2570 then
2571 -- too many errors. we now abort with a message.
2572 -- commit any work we have already done if
2573 -- we are allowed to do so.
2574 if(p_info.dml_mode = 'FULL' or p_info.multi_thread)
2575 then
2576 commit;
2577 end if;
2578 --
2579 -- raise error to indicate entire process has failed.
2580 hr_utility.set_message (801, 'HR_7269_ASS_TOO_MANY_ERRORS');
2581 hr_utility.raise_error;
2582 end if;
2583 end assact_error;
2584 --
2585 /*
2586 * Lock and return a range row.
2587 * A range of ids are locked by first setting a database
2588 * lock and then updating the status to 'P', at which
2589 * point is 'belongs' to the thread and we can commit.
2590 * If there are no lockable rows, returns a null for
2591 * the chunk number to indicate end of processing.
2592 */
2593 function next_range(p_info in rollback_rec)
2594 return range_rec is
2595 norows boolean;
2596 range_info range_rec;
2597 c_indent varchar2(40);
2598 begin
2599 if g_debug then
2600 c_indent := 'py_rollback_pkg.next_range';
2601 hr_utility.set_location(c_indent, 1);
2602 end if;
2603 -- select a range row for update.
2604 begin
2605 if g_debug then
2606 hr_utility.set_location(c_indent, 2);
2607 end if;
2608 select rge.chunk_number,
2609 rge.starting_person_id,
2610 rge.ending_person_id
2611 into range_info
2612 from pay_population_ranges rge
2613 where rge.payroll_action_id = p_info.pact_id
2614 and rge.range_status = 'U'
2615 and rownum < 2
2616 for update of rge.chunk_number;
2617 --
2618 if g_debug then
2619 hr_utility.set_location(c_indent, 3);
2620 end if;
2621 -- If we reach here, we have a range row
2622 -- and we therefore wish to lock it.
2623 update pay_population_ranges pop
2624 set pop.range_status = 'P'
2625 where pop.payroll_action_id = p_info.pact_id
2626 and pop.chunk_number = range_info.chunk_number;
2627 --
2628 if g_debug then
2629 hr_utility.set_location(c_indent, 4);
2630 end if;
2631 -- Only commit if we are allowed to.
2632 if(p_info.multi_thread or p_info.dml_mode = 'FULL')
2633 then
2634 if g_debug then
2635 hr_utility.set_location(c_indent, 5);
2636 end if;
2637 commit;
2638 end if;
2639 exception
2640 when no_data_found then
2641 if g_debug then
2642 hr_utility.set_location(c_indent, 7);
2643 end if;
2644 range_info.chunk_number := null;
2645 end;
2646 --
2647 if g_debug then
2648 hr_utility.set_location(c_indent, 8);
2649 end if;
2650 return(range_info);
2651 end next_range;
2652 --
2653 procedure perform_act_rollback(p_info in out nocopy rollback_rec)
2654 is
2655 begin
2656 if g_debug then
2657 hr_utility.set_location ('perform_asg_rollback',10);
2658 end if;
2659 --
2660 -- set a savepoint in case we fail.
2661 savepoint before;
2662 --
2663 -- make checks for validity of rollback.
2664 val_assact_rollback(p_info); --
2665 --
2666 -- actually perform the rollback/mark for retry.
2667 do_assact_rollback(p_info);
2668 --
2669 if g_debug then
2670 hr_utility.set_location ('perform_asg_rollback',20);
2671 end if;
2672 -- if succeeded in processing, we reset the
2673 -- error counter, since we only wish to count
2674 -- consecutive errors.
2675 g_error_count := 0;
2676 --
2677 exception
2678 -- we may be reaching here due to failure in validation
2679 -- or because we have an unhandled exception (oracle error).
2680 -- in both cases we attempt to write the message text to
2681 -- message lines before continuing. This is done up to
2682 -- the error limit, then we exit.
2683 when others then
2684 if g_debug then
2685 hr_utility.set_location ('perform_asg_rollback',30);
2686 end if;
2687 rollback to savepoint before; -- throw away any work.
2688 if(p_info.all_or_nothing)
2689 then
2690 -- fail immediately for this case.
2691 raise;
2692 else
2693 assact_error(p_info, sqlcode, sqlerrm);
2694 end if;
2695 end;
2696 /*
2697 * Performs the dml for rolling back or
2698 * marking for retry assignment actions.
2699 */
2700 procedure assact_dml(p_info in out nocopy rollback_rec) is
2701 --
2702 range_info range_rec;
2703 --
2704 /*
2705 * Notice we outer join to period of service to
2706 * allow locking when we have a row. We will not have
2707 * a period of service for benefit assignments.
2708 */
2709 cursor c1 is
2710 select act.assignment_action_id, -- Bug 6834017 ,Removed ordered hint
2711 asg.period_of_service_id
2712 from per_all_assignments_f asg,
2713 pay_assignment_actions act
2714 where act.payroll_action_id = p_info.pact_id
2715 and asg.assignment_id = act.assignment_id
2716 and act.source_action_id is null
2717 and ((p_info.action_type = 'X'
2718 and asg.effective_start_date = (select max(asg2.effective_start_date)
2719 from per_all_assignments_f asg2
2720 where asg2.assignment_id =
2721 asg.assignment_id)
2722 )
2723 or
2724 ((p_info.action_type = 'PRU' or p_info.action_type = 'Z')
2725 and asg.effective_start_date = (select max(asg2.effective_start_date)
2726 from per_all_assignments_f asg2
2727 where asg2.assignment_id =
2728 asg.assignment_id
2729 and asg2.effective_start_date <=
2730 p_info.action_date)
2731 )
2732 /* or
2733 (p_info.action_type = 'BEE'
2734 and asg.effective_start_date = (select max(ASS2.effective_start_date)
2735 from per_all_assignments_f ASS2,
2736 pay_batch_lines pbl
2737 where ASS2.assignment_id = asg.assignment_id
2738 and pbl.batch_id (+) = p_info.batch_id
2739 and pbl.assignment_id (+) = asg.assignment_id
2740 and pbl.effective_Date (+) between ASS2.effective_start_date
2741 and ASS2.effective_end_date))
2742 */ or
2743 (p_info.action_type not in ('BEE','Z','X')
2744 and p_info.action_date between
2745 asg.effective_start_date and asg.effective_end_date))
2746 and asg.person_id between
2747 range_info.starting_person and range_info.ending_person
2748 for update of act.action_status,
2749 asg.assignment_id
2750 order by act.action_sequence desc;
2751 --
2752 cursor c1_bee is
2753 select act.assignment_action_id, -- Bug 6834017 ,Removed ordered hint
2754 asg.period_of_service_id
2755 from per_all_assignments_f asg,
2756 pay_assignment_actions act
2757 where act.payroll_action_id = p_info.pact_id
2758 and asg.assignment_id = act.assignment_id
2759 and act.source_action_id is null
2760 and p_info.action_type = 'BEE'
2761 and asg.effective_start_date = (select max(ASS2.effective_start_date)
2762 from per_all_assignments_f ASS2,
2763 pay_batch_lines pbl
2764 where ASS2.assignment_id = asg.assignment_id
2765 and pbl.batch_id (+) = p_info.batch_id
2766 and pbl.assignment_id (+) = asg.assignment_id
2767 and pbl.effective_Date (+) between ASS2.effective_start_date
2768 and ASS2.effective_end_date)
2769 for update of act.action_status,
2770 asg.assignment_id
2771 order by act.action_sequence desc;
2772 --
2773 cursor c2 is
2774 select act.assignment_action_id
2775 from pay_assignment_actions act
2776 where act.payroll_action_id = p_info.pact_id
2777 and act.source_action_id is null
2778 and act.object_id between
2779 range_info.starting_person and range_info.ending_person
2780 for update of act.action_status
2781 order by act.action_sequence desc;
2782 --
2783 cursor c3(c_period_of_service_id number) is
2784 select pos.period_of_service_id
2785 from per_periods_of_service pos
2786 where pos.period_of_service_id = c_period_of_service_id
2787 for update of pos.period_of_service_id;
2788 --
2789 commit_limit number;
2790 begin
2791 if g_debug then
2792 hr_utility.set_location ('assact_dml',1);
2793 end if;
2794 -- Attempt to get a range to process.
2795 range_info := next_range(p_info);
2796 --
2797 if g_debug then
2798 if g_debug then
2799 hr_utility.trace('max_single_undo = ' || p_info.max_single_undo);
2800 hr_utility.trace('max_errors_allowed = ' || p_info.max_errors_allowed);
2801 hr_utility.set_location ('assact_dml',2);
2802 end if;
2803 end if;
2804 -- Continue to process a chunk at a time,
2805 -- as long as we can lock a range row.
2806 while(range_info.chunk_number is not null)
2807 loop
2808 hr_utility.set_location ('assact_dml',3);
2809 --
2810 /* By default it must be an assignment action */
2811 if (p_info.object_type is null) then
2812 if(p_info.action_type <> 'BEE') then
2813 for c1rec in c1 loop
2814 p_info.assact_id := c1rec.assignment_action_id;
2815 if c1rec.period_of_service_id is not null then
2816 for c3rec in c3(c1rec.period_of_service_id) loop
2817 null; -- Locking Period of service.
2818 end loop;
2819 end if;
2820 perform_act_rollback(p_info);
2821 end loop; -- assact loop.
2822 else
2823 for c1rec in c1_bee loop
2824 p_info.assact_id := c1rec.assignment_action_id;
2825 if c1rec.period_of_service_id is not null then
2826 for c3rec in c3(c1rec.period_of_service_id) loop
2827 null; -- Locking Period of service.
2828 end loop;
2829 end if;
2830 perform_act_rollback(p_info);
2831 end loop; -- assact loop.
2832 end if;
2833 else
2834 /* OK, it must be an object action */
2835 for c2rec in c2 loop
2836 p_info.assact_id := c2rec.assignment_action_id;
2837 perform_act_rollback(p_info);
2838 end loop; -- objact loop.
2839 end if;
2840 --
2841 -- this range row is finished with.
2842 if g_debug then
2843 hr_utility.set_location('assact_dml', 20);
2844 end if;
2845 delete from pay_population_ranges range
2846 where range.payroll_action_id = p_info.pact_id
2847 and range.chunk_number = range_info.chunk_number;
2848 --
2849 if g_debug then
2850 hr_utility.set_location ('assact_dml',10);
2851 end if;
2852 -- commit our processing, but only if we are
2853 -- mult-threading and dml_mode is appropriate.
2854 -- reset the commit limit to zero.
2855 if(p_info.multi_thread or p_info.dml_mode = 'FULL')
2856 then
2857 commit;
2858 commit_limit := 0;
2859 end if;
2860 --
2861 if g_debug then
2862 hr_utility.set_location ('assact_dml',11);
2863 end if;
2864 -- Attempt to lock another range.
2865 range_info := next_range(p_info);
2866 end loop;
2867 --
2868 if g_debug then
2869 hr_utility.set_location ('assact_dml',12);
2870 end if;
2871 end assact_dml;
2872 -- --
2873 /*
2874 * validates rules that control what type of
2875 * actions we can perform a rollback or mark
2876 * for retry payroll action on.
2877 */
2878 procedure val_pact_rr_rules (p_info in rollback_rec)
2879 is
2880 dummy NUMBER;
2881 begin
2882 if g_debug then
2883 hr_utility.set_location('val_pact_rr_rules', 10);
2884 end if;
2885 --
2886 if(p_info.rollback_mode = 'RETRY')
2887 then
2888 if(p_info.action_type in ( 'E', 'H', 'D', 'PP'))
2889 then
2890 hr_utility.set_message(801, 'HR_7093_ACTION_CANT_RETPAY');
2891 hr_utility.set_message_token('ACTION_NAME', p_info.action_name);
2892 hr_utility.raise_error;
2893 end if;
2894 end if;
2895 --
2896 -- Special check for Purge for both modes.
2897 -- We are not allowed to rollback or mark for retry an entire
2898 -- purge payroll action if there are any assignment actions
2899 -- with secondary_status = 'C'.
2900 if (p_info.action_type = 'Z') then
2901 declare
2902 l_complete number;
2903 begin
2904 select count(*)
2905 into l_complete
2906 from pay_assignment_actions act
2907 where act.payroll_action_id = p_info.pact_id
2908 and act.secondary_status = 'C';
2909 --
2910 if(l_complete > 0) then
2911 hr_utility.set_message(801, 'PAY_289020_PUR_CANT_ROLLBACK');
2912 hr_utility.raise_error;
2913 end if;
2914 end;
2915 end if;
2916 end val_pact_rr_rules;
2917 --
2918 --
2919 /*
2920 * checks if the process that is being checked for retry has a dependant, or
2921 * succeeding, process that is not in a status of complete.
2922 */
2923 procedure val_dependant (p_info in rollback_rec)
2924 is
2925 w_payroll_id_1 number(9);
2926
2927 cursor chk_dep is
2928 select distinct pac.payroll_action_id
2929 from pay_assignment_actions act2,
2930 pay_action_interlocks pai,
2931 pay_assignment_actions act,
2932 pay_payroll_actions pac,
2933 pay_payroll_actions pac2
2934 where pac2.payroll_action_id = p_info.pact_id
2935 and act2.payroll_action_id = pac2.payroll_action_id
2936 and pac.payroll_action_id = act.payroll_action_id
2937 and pai.locking_action_id = act.assignment_action_id
2938 and pai.locked_action_id = act2.assignment_action_id
2939 and pac.action_status <> 'C'
2940 and pac.action_type in ('A', 'H', 'M', 'PP');
2941
2942 begin
2943 if g_debug then
2944 hr_utility.set_location('val_dependant', 18);
2945 end if;
2946
2947 open chk_dep;
2948 fetch chk_dep into w_payroll_id_1;
2949
2950 if chk_dep%found
2951 then
2952 if p_info.legislation_code = 'GB' then
2953 hr_utility.set_message (801, 'HR_52975_ACTION_UNDO_INTLOK_GB');
2954 else
2955 hr_utility.set_message (801, 'HR_7507_ACTION_UNDO_INTLOCK');
2956 end if;
2957 hr_utility.raise_error;
2958 end if;
2959
2960 close chk_dep;
2961 --
2962 end val_dependant ;
2963 --
2964 /*
2965 * validates rules that control what type of actions we
2966 * can perform a rollback/mark for retry assignment action on.
2967 */
2968 procedure val_assact_rr_rules (p_info in rollback_rec)
2969 is
2970 begin
2971 -- Validate the rollback and mark for retry rules for
2972 -- assignment actions.
2973 if g_debug then
2974 hr_utility.set_location('val_assact_rr_rules', 10);
2975 end if;
2976 --
2977 if(p_info.rollback_mode = 'RETRY')
2978 then
2979 if(p_info.action_type in ( 'PRU', 'E', 'M', 'H', 'D', 'PP') or
2980 (p_info.action_type = 'T' and p_info.sub_ledger_acc = 'N'))
2981 then
2982 hr_utility.set_message(801, 'HR_7508_ACTION_ACT_RR_RULE');
2983 hr_utility.set_message_token('ACTION_NAME', p_info.action_name);
2984 hr_utility.raise_error;
2985 end if;
2986 else
2987 -- !!!! note - temporary change for RN project.
2988 -- allow rollback of individual Magnetic Transfer assact.
2989 if(p_info.action_type in ('Q', 'U', 'E', 'PRU') or
2990 (p_info.action_type = 'T' and p_info.sub_ledger_acc = 'N'))
2991 then
2992 hr_utility.set_message(801, 'HR_7508_ACTION_ACT_RR_RULE');
2993 hr_utility.set_message_token('ACTION_NAME', p_info.action_name);
2994 hr_utility.raise_error;
2995 end if;
2996 end if;
2997 end val_assact_rr_rules;
2998 --
2999 /*
3000 * validate the parameters passed to the rollback
3001 * assignment and payroll action procedures.
3002 */
3003 procedure val_params (p_info in rollback_rec)
3004 is
3005 begin
3006 -- where applicable, check that parameters
3007 -- have reasonable values.
3008 if g_debug then
3009 hr_utility.set_location('val_params', 10);
3010 end if;
3011 if(p_info.rollback_mode not in ('RETRY', 'ROLLBACK', 'BACKPAY'))
3012 then
3013 hr_utility.set_message(801, 'HR_7000_ACTION_BAD_ROLL_MODE');
3014 hr_utility.raise_error;
3015 end if;
3016 --
3017 if(p_info.dml_mode not in ('FULL', 'NO_COMMIT', 'NONE'))
3018 then
3019 hr_utility.set_message(801, 'HR_7509_ACTION_BAD_DML_MODE');
3020 hr_utility.raise_error;
3021 end if;
3022 --
3023 -- certain values are illegal if they are combined.
3024 -- note that these checks are only applicable to
3025 -- the payroll action rollback level.
3026 if(p_info.rollback_level = 'P')
3027 then
3028 null;
3029 end if;
3030 end val_params;
3031 --
3032 /*
3033 * if the rollback payroll action is being called in
3034 * single threaded mode, we need to insert a range
3035 * row. This allows the processing to have the same
3036 * interface for both multi and single-thread modes.
3037 * NOTE: no date track restriction is required for
3038 * this statement, as we obtaining min and max
3039 * values. This happens to be convenient for Purge.
3040 */
3041 procedure single_thread_range(p_info in rollback_rec)
3042 is
3043 l_payroll_action_id number;
3044 begin
3045 l_payroll_action_id := p_info.pact_id;
3046 -- ok, we are single-threading. Need to remove any existing
3047 -- range rows (thought there are unlikely to be any), and
3048 -- then insert a special row.
3049 if g_debug then
3050 hr_utility.set_location('single_thread_range', 10);
3051 end if;
3052 delete from pay_population_ranges range
3053 where range.payroll_action_id = l_payroll_action_id;
3054 --
3055 if g_debug then
3056 hr_utility.set_location('single_thread_range', 20);
3057 end if;
3058
3059 if (p_info.object_type is null) then
3060 insert into pay_population_ranges (
3061 payroll_action_id,
3062 chunk_number,
3063 starting_person_id,
3064 ending_person_id,
3065 range_status)
3066 select /*+ USE_NL(asg)
3067 INDEX(asg PER_ASSIGNMENTS_F_PK) */
3068 pac.payroll_action_id,
3069 1,
3070 min(asg.person_id),
3071 max(asg.person_id),
3072 'U'
3073 from pay_payroll_actions pac,
3074 pay_assignment_actions act,
3075 per_all_assignments_f asg
3076 where pac.payroll_action_id = l_payroll_action_id
3077 and act.payroll_action_id = pac.payroll_action_id
3078 and asg.assignment_id = act.assignment_id
3079 group by pac.payroll_action_id;
3080 else
3081 insert into pay_population_ranges (
3082 payroll_action_id,
3083 chunk_number,
3084 starting_person_id,
3085 ending_person_id,
3086 range_status)
3087 select pac.payroll_action_id,
3088 1,
3089 min(act.object_id),
3090 max(act.object_id),
3091 'U'
3092 from pay_payroll_actions pac,
3093 pay_assignment_actions act
3094 where pac.payroll_action_id = l_payroll_action_id
3095 and act.payroll_action_id = pac.payroll_action_id
3096 group by pac.payroll_action_id;
3097 end if;
3098 --
3099 if g_debug then
3100 hr_utility.set_location('single_thread_range', 30);
3101 end if;
3102 end single_thread_range;
3103 --
3104 /*
3105 * this is called when we are rolling back. We need to know
3106 * whether or not the assignment actions have all been
3107 * deleted, otherwise we do not wish to remove the payroll
3108 * action.
3109 */
3110 function rollback_complete(p_payroll_action_id in number)
3111 return boolean is
3112 dummy number;
3113 begin
3114 select null
3115 into dummy
3116 from sys.dual
3117 where exists (
3118 select null
3119 from pay_assignment_actions act
3120 where act.payroll_action_id = p_payroll_action_id);
3121 --
3122 -- There are still assignment actions.
3123 return(false);
3124 --
3125 exception
3126 when no_data_found then
3127 -- There are no longer assignment actions.
3128 -- the rollback is considered complete.
3129 return(true);
3130 end rollback_complete;
3131 --
3132 /*
3133 * If we are limiting the dml that can be performed, this procedure
3134 * is called to ensure that we do not breach the limit.
3135 * This should only occur when the rollback procedure is called
3136 * from a forms session. In this case, user is advised to launch
3137 * a Rollback process from SRS.
3138 */
3139 procedure val_limit_dml(p_info in rollback_rec) is
3140 action_count number;
3141 begin
3142 select count(*)
3143 into action_count
3144 from pay_assignment_actions act
3145 where act.payroll_action_id = p_info.pact_id
3146 and rownum < (p_info.max_single_undo + 2);
3147 --
3148 if(action_count > p_info.max_single_undo) then
3149 hr_utility.set_message(801, 'HR_7722_ACTION_COMMIT_LIMIT');
3150 hr_utility.set_message_token('COMMIT_LIMIT',p_info.max_single_undo);
3151 hr_utility.raise_error;
3152 end if;
3153 end val_limit_dml;
3154 --
3155 /*
3156 * Perform the rolling back or Marking for Retry of a Payroll Action.
3157 * Can also be used for validation that such an action is
3158 * permissible. For the use and meaning of the parameters, please
3159 * refer to the package header.
3160 */
3161 procedure rollback_payroll_action
3162 (
3163 p_payroll_action_id in number,
3164 p_rollback_mode in varchar2 default 'ROLLBACK',
3165 p_leave_base_table_row in boolean default false,
3166 p_all_or_nothing in boolean default true,
3167 p_dml_mode in varchar2 default 'NO_COMMIT',
3168 p_multi_thread in boolean default false,
3169 p_limit_dml in boolean default false,
3170 p_grp_multi_thread in boolean default false
3171 ) is
3172 info rollback_rec; -- 'global' information.
3173 c_indent varchar2(40);
3174 l_date_earned date;
3175 begin
3176 g_debug := hr_utility.debug_enabled;
3177 if g_debug then
3178 c_indent := 'py_rollback_pkg.rollback_payroll_action';
3179 hr_utility.set_location(c_indent, 5);
3180 end if;
3181 -- set up the parameters.
3182 info.rollback_mode := p_rollback_mode;
3183 info.rollback_level := 'P'; -- processing entire Payroll Action.
3184 info.leave_row := p_leave_base_table_row;
3185 info.all_or_nothing := p_all_or_nothing;
3186 info.multi_thread := p_multi_thread;
3187 info.grp_multi_thread := p_grp_multi_thread;
3188 info.dml_mode := p_dml_mode;
3189 info.limit_dml := p_limit_dml;
3190 info.pact_id := p_payroll_action_id;
3191 --
3192 -- Set the Continuous Calc override flag, so that the trigger points
3193 -- are not fired.
3194 pay_continuous_calc.g_override_cc := TRUE;
3195 --
3196 -- Ensure delete from gl_interface in remove_gl_entries on
3197 -- each execution.
3198 mtgl_mode_cached := FALSE;
3199 --
3200 -- how many errors can we stand, what commit limit do we have?
3201 info.max_errors_allowed := action_parameter('MAX_ERRORS_ALLOWED');
3202 info.max_single_undo := action_parameter('MAX_SINGLE_UNDO');
3203 info.set_date_earned := action_parameter('SET_DATE_EARNED');
3204 --
3205 -- May wish to limit number of actions that can
3206 -- be rolled back. This is mainly for forms.
3207 if(info.limit_dml and not info.multi_thread) then
3208 val_limit_dml(info);
3209 end if;
3210 --
3211 get_pact_info(info); -- get payroll action level information.
3212 --
3213 info.retro_purge := legislation_rule(info.legislation_code, 'RETRO_DELETE');
3214 pay_core_utils.get_upgrade_status(info.bg_id,
3215 'SINGLE_BAL_TABLE',
3216 info.single_bal_table);
3217 --
3218 val_params(info); -- validate parameters passed in.
3219
3220 if(info.rollback_mode = 'RETRY' and info.action_status in ('C', 'S'))
3221 then
3222 val_dependant(info); -- does the payroll action have an uncompleted
3223 -- dependant payroll action?
3224 end if;
3225
3226 val_pact_rr_rules(info); -- can we rollback the payroll action.
3227 --
3228 if(not info.multi_thread) then
3229 -- single threading, insert special range row.
3230 single_thread_range(info);
3231 end if;
3232 --
3233 -- Depending on the dml mode, we may wish to
3234 -- set a savepoint.
3235 if(info.dml_mode = 'NONE') then
3236 if g_debug then
3237 hr_utility.set_location(c_indent, 10);
3238 end if;
3239 savepoint no_dml;
3240 end if;
3241 --
3242 if (info.action_type = 'PRU') then
3243 remove_pact_payment(info.pact_id);
3244 end if;
3245 --
3246 assact_dml(info); -- do the rollback of assact rows.
3247 --
3248 -- delete archive_items for the context of payroll_action_id
3249 --
3250 if g_debug then
3251 hr_utility.set_location(c_indent, 12);
3252 end if;
3253 --
3254 -- Remove archiver items at the payroll action level
3255 if (info.action_type = 'X' or
3256 info.action_type = 'PP' or
3257 info.action_type = 'M') then
3258 remove_archive_items(info, info.pact_id, 'PA');
3259 remove_action_information(info.pact_id, 'PA');
3260 remove_file_details(info, info.pact_id, 'PPA');
3261 end if;
3262 --
3263 if g_debug then
3264 hr_utility.set_location(c_indent, 15);
3265 end if;
3266 --
3267 --
3268 -- delete group level run balances
3269 --
3270 if (info.sequenced_flag and
3271 rollback_complete(info.pact_id)) then
3272 delete from pay_run_balances
3273 where payroll_action_id = info.pact_id;
3274 end if;
3275 --
3276 if(info.dml_mode = 'NONE') then
3277 hr_utility.set_location(c_indent, 20);
3278 rollback to savepoint no_dml;
3279 end if;
3280 --
3281 -- we insert a message to indicate that the rollback was successful.
3282 -- Note that we perform this whether or not we are going to actually
3283 -- delete the payroll action row, as we assume that the caller
3284 -- will perform this action, even if we do not. Also note that it is
3285 -- only done if we have rolled back all assignment actions.
3286 -- Finally, if we are multi-threading, we wish to leave the process
3287 -- to insert the message.
3288 if(info.rollback_mode = 'ROLLBACK' and
3289 rollback_complete(info.pact_id) and
3290 not info.multi_thread)
3291 then
3292 remove_messages(info, 'P');
3293 -- Only insert message if the action is not an
3294 -- initial balance upload.
3295 if (info.action_type <> 'I') then
3296 ins_rollback_message(info, 'P');
3297 end if;
3298 end if;
3299 --
3300 -- now if the rollback is successful then we update the bee batch.
3301 if (rollback_complete(info.pact_id) and info.action_type ='BEE') then
3302 pay_mix_rollback_pkg.set_status(info.pact_id,info.leave_row);
3303 end if;
3304 --
3305 -- now we perform any action that we require (and
3306 -- are allowed to perform) on the payroll action
3307 -- row itself. Normally, we would not wish to touch
3308 -- the row if the client was a form.
3309 if(not info.leave_row and rollback_complete(info.pact_id))
3310 then
3311 -- delete the payroll action row if we are told to.
3312 if g_debug then
3313 hr_utility.set_location(c_indent, 30);
3314 end if;
3315 delete from pay_chunk_status
3316 where payroll_action_id = info.pact_id;
3317 delete from pay_payroll_actions pac
3318 where pac.payroll_action_id = info.pact_id;
3319 else
3320 if (info.sequenced_flag=FALSE) then
3321 if (info.rollback_mode <> 'BACKPAY'
3322 and info.rollback_mode <> 'RETRY'
3323 and info.action_type <> 'BEE') then
3324 if info.rollback_level = 'P' then
3325 if info.set_date_earned = 'Y' then
3326 select max(date_earned)
3327 into l_date_earned
3328 from pay_payroll_actions locked_pact,
3329 pay_assignment_actions locked,
3330 pay_assignment_actions locking,
3331 pay_action_interlocks locks
3332 where locking.payroll_action_id =info.pact_id
3333 and locking.assignment_action_id =locks.locking_action_id
3334 and locked.assignment_action_id =locks.locked_action_id
3335 and locked.payroll_action_id =locked_pact.payroll_action_id;
3336 --
3337 update pay_payroll_actions pac
3338 set pac.date_earned = l_date_earned
3339 where pac.payroll_action_id = info.pact_id;
3340 end if;
3341 end if;
3342 end if;
3343 end if;
3344 end if;
3345 --
3346 -- decide if we wish to perform that final commit
3347 if(info.dml_mode = 'FULL')
3348 then
3349 if g_debug then
3350 hr_utility.set_location(c_indent, 40);
3351 end if;
3352 commit;
3353 end if;
3354 --
3355 pay_continuous_calc.g_override_cc := FALSE;
3356 --
3357 exception
3358 when others then
3359 pay_continuous_calc.g_override_cc := FALSE;
3360 raise;
3361 end rollback_payroll_action;
3362 --
3363 /*
3364 * Interface to rollback/mark for retry of an assignment action.
3365 * see the package header for details of the parameters.
3366 * Takes into account assignment level erroring.
3367 */
3368 procedure rollback_ass_action
3369 (
3370 p_assignment_action_id in number,
3371 p_rollback_mode in varchar2 default 'ROLLBACK',
3372 p_leave_base_table_row in boolean default false,
3373 p_all_or_nothing in boolean default true,
3374 p_dml_mode in varchar2 default 'NO_COMMIT',
3375 p_multi_thread in boolean default false,
3376 p_grp_multi_thread in boolean default false
3377 ) is
3378 info rollback_rec;
3379 c_indent varchar2(40);
3380 l_date_earned date;
3381 l_current_date_earned date;
3382 src_action_id number;
3383 --
3384 begin
3385 g_debug := hr_utility.debug_enabled;
3386 -- need to know the payroll action.
3387 if g_debug then
3388 c_indent := 'py_rollback_pkg.rollback_ass_action';
3389 hr_utility.set_location(c_indent, 10);
3390 end if;
3391 select act.payroll_action_id, act.source_action_id, act.object_type
3392 into info.pact_id, src_action_id, info.object_type
3393 from pay_assignment_actions act
3394 where act.assignment_action_id = p_assignment_action_id;
3395 --
3396 -- instantiate the other parameters that are relevant.
3397 info.assact_id := p_assignment_action_id;
3398 info.rollback_mode := p_rollback_mode;
3399 info.rollback_level := 'A';
3400 info.leave_row := p_leave_base_table_row;
3401 info.dml_mode := p_dml_mode;
3402 info.multi_thread := p_multi_thread;
3403 info.grp_multi_thread := p_grp_multi_thread;
3404 --
3405 -- Check that it is a master action.
3406 if src_action_id is not null then
3407 hr_utility.set_message(801, 'PAY_289114_RLBK_CHLD_ACT');
3408 hr_utility.raise_error;
3409 end if;
3410 --
3411 -- how many errors can we stand, what commit limit do we have?
3412 info.max_errors_allowed := action_parameter('MAX_ERRORS_ALLOWED');
3413 info.max_single_undo := action_parameter('MAX_SINGLE_UNDO');
3414 info.set_date_earned := action_parameter('SET_DATE_EARNED');
3415 --
3416 get_pact_info(info); -- get info about payroll action.
3417 --
3418 info.retro_purge := legislation_rule(info.legislation_code, 'RETRO_DELETE');
3419 pay_core_utils.get_upgrade_status(info.bg_id,
3420 'SINGLE_BAL_TABLE',
3421 info.single_bal_table);
3422 --
3423 val_params(info); -- parameter validation.
3424 --
3425 -- For BackPay, we do not care about normal
3426 -- rules about whether a single action of a
3427 -- particular action type can be rolled
3428 -- back or not.
3429 if(info.rollback_mode <> 'BACKPAY') then
3430 val_assact_rr_rules(info);
3431 else
3432 select assignment_id
3433 into info.assignment_id
3434 from pay_assignment_actions
3435 where assignment_action_id = info.assact_id;
3436 end if;
3437 --
3438 -- perform the rollback/mark for retry itself.
3439 -- from now on, errors are considered to be assignment action
3440 -- level. Depending on the mode, we may stop immediately.
3441 -- In backpay case, we do not wish to validate the rollback,
3442 -- simply wishing to perform it. This is because BackPay does
3443 -- only performs rollback on Reversals, Runs and QuickPays.
3444 begin
3445 --
3446 -- in case we fail.
3447 savepoint before;
3448 --
3449 -- Set the Continuous Calc override flag, so that the trigger points
3450 -- are not fired.
3451 pay_continuous_calc.g_override_cc := TRUE;
3452 --
3453 if(info.rollback_mode <> 'BACKPAY') then
3454 val_assact_rollback(info);
3455 end if;
3456 --
3457 -- Only perform dml if allowed to.
3458 if(info.dml_mode <> 'NONE') then
3459 do_assact_rollback(info);
3460 -- update date earned for payroll action
3461 if (info.sequenced_flag=FALSE) then
3462 if (info.rollback_mode <> 'BACKPAY'
3463 and info.rollback_mode <> 'RETRY'
3464 and info.action_type <> 'X'
3465 and info.action_type <> 'BEE') then
3466 if info.rollback_level = 'A' then
3467
3468 if info.set_date_earned = 'Y' then
3469 begin
3470 -- Handle that the rolled back assignment action
3471 -- may have been the last one
3472 select max(locked_pact.date_earned), locking_pact.date_earned
3473 into l_date_earned, l_current_date_earned
3474 from pay_payroll_actions locked_pact,
3475 pay_assignment_actions locked,
3476 pay_assignment_actions locking,
3477 pay_action_interlocks locks,
3478 pay_payroll_actions locking_pact
3479 where locking_pact.payroll_action_id =info.pact_id
3480 and locking.payroll_action_id =locking_pact.payroll_action_id
3481 and locking.assignment_action_id =locks.locking_action_id
3482 and locked.assignment_action_id =locks.locked_action_id
3483 and locked.payroll_action_id =locked_pact.payroll_action_id
3484 group by locking_pact.date_earned;
3485 --
3486 if (l_date_earned < l_current_date_earned) then
3487 update pay_payroll_actions pac
3488 set pac.date_earned = l_date_earned
3489 where pac.payroll_action_id = info.pact_id;
3490 end if;
3491 --
3492 exception
3493 when others then
3494 update pay_payroll_actions pac
3495 set pac.date_earned = null
3496 where pac.payroll_action_id = info.pact_id;
3497 end;
3498 end if;
3499 end if;
3500 end if;
3501 end if;
3502 --
3503 -- Remove the group run balances for resersal.
3504 --
3505 if (info.action_type = 'V') then
3506 --
3507 delete from pay_run_balances
3508 where payroll_action_id = info.pact_id;
3509 --
3510 end if;
3511 end if;
3512 g_error_count := 0; -- only count consecutive errors.
3513 pay_continuous_calc.g_override_cc := FALSE;
3514 exception
3515 -- Throw away any work we have done.
3516 when others then
3517 rollback to savepoint before;
3518 pay_continuous_calc.g_override_cc := FALSE;
3519 if(p_all_or_nothing) then
3520 raise;
3521 else
3522 assact_error(info, sqlcode, sqlerrm);
3523 end if;
3524 end;
3525 --
3526 -- we may wish to commit.
3527 if(info.dml_mode = 'FULL')
3528 then
3529 commit;
3530 end if;
3531 end rollback_ass_action;
3532 --
3533 --
3534 begin
3535 --
3536 -- Having the error counter as a package global and
3537 -- initialising it here allows the error counting
3538 -- mechanism to work whether we are rolling back a
3539 -- whole payroll action or assignment action by
3540 -- assignment action.
3541 g_error_count := 0;
3542 -- hr_utility.trace_on(null, 'ORACLE');
3543 end py_rollback_pkg;