DBA Data[Home] [Help]

PACKAGE BODY: APPS.HR_PAYMENTS

Source


1 package body hr_payments as
2 /* $Header: pypaymnt.pkb 120.4 2011/09/22 09:38:37 kskoduri ship $ */
3 /*
4  * ---------------------------------------------------------------------------
5    Copyright (c) Oracle Corporation (UK) Ltd 1992.
6    All Rights Reserved.
7   --
8   --
9   PRODUCT
10     Oracle*Payroll
11   NAME
12     hr_payments   (hrppm.pkb)
13   NOTES
14     per-payments procedures.  Used for validation of DDL on:
15     PAY_PAYMENT_TYPES
16     PAY_ORG_PAYMENT_METHODS
17     PAY_ORG_PAY_METHOD_USAGES
18     PAY_PERSONAL_PAYMENT_METHODS
19   MODIFIED
20     amcinnes          16-NOV-1992  Created with ppt_brui
21     amcinnes          20-DEC-1992  Added all other payments procedures
22     amcinnes          07-JAN-1993  GEN_BALANCE now called from forms
23     amcinnes          11-JAN-1993  Corrected operation of gen balance
24     amcinnes          21-JAN-1993  Changes for new standards
25     amcinnes          14-JUN-1993  Changes for change to PPT that whoever
26                                    changed it should have done.
27                                    Removed all refs to formula/formula_id
28     afrith            29-SEP-1993  Change gen-balance to use remuneration flag
29     rneale	      20-JUN-1994  Added match_currency for use by PAYWSDPM.
30     rfine	40.4  21-MAR-1995  Fixed fnd_message.set_name calls in
31     rfine	40.5  22-MAR-1995  Changed check_pp so it now checks for
32 				   pre-payments after the date passed in only,
33 				   not 'on or after' that date. WWbug 264094.
34     sdoshi     115.1  30-MAR-1999  Flexible Dates Conversion
35     tbattoo    115.2  10-JAN-2001  Modified check_currency function.  Added
36 						     an nvl in the IF statement.
37     kskoduri   115.4  14-JUN-2011  Added the procedure check_ppm to validate
38 				   if prepayments exist before updating a
39 				   personal payment method via selfservice
40     kskoduri   115.6  27-JUN-2011  Added NOCOPY hint to remove the GSCC fail
41     kskoduri   115.7  22-SEP-2011  Added NOCOPY hint to remove the GSCC fail
42   --
43  * ---------------------------------------------------------------------------
44  */
45 --
46 /*--------------------------- validate_magnetic ------------------------------
47 
48 NAME
49   validate_magnetic
50 DESCRIPTION
51   Validate business rules for pay_payment_types
52 NOTES
53   Category is magnetic if this is called.
54   Check pre-validation_requied flag is set.
55   If pre-validation, check that the values and days are set.
56 */
57 function validate_magnetic(validate in varchar2,
58                            validation_days in number,
59                            validation_value in varchar2) return boolean is
60 --
61 begin
62   --
63   hr_utility.set_location('HR_PAYMENTS.VALIDATE_MAGNETIC',1);
64   --
65   -- Check mand values for mag method are there.
66   --
67   if validate is null then
68   --
69     hr_utility.set_message(801,'HR_6227_PAYM_MAND_MAG_DETAILS');
70     hr_utility.raise_error;
71     return(false);
72   --
73   end if;
74   --
75   -- Check pre-validation flag is set
76   --
77   if validate = 'Y' then
78     --
79     -- Magnetic validation required. Days and values must be set
80     --
81     if validation_days is null or validation_value is null then
82       --
83       hr_utility.set_message(801,'HR_6228_PAYM_NO_VALIDATION');
84       hr_utility.raise_error;
85       return(false);
86       --
87     end if;
88     --
89   end if;
90   --
91   return(true);
92   --
93 end validate_magnetic;
94 --
95 /*--------------------------- check_ok_default----------------------------------
96 
97 NAME
98   check_ok_default
99 DESCRIPTION
100   Check the payment type is allowed as a default
101 NOTES
102   CASH and CHECK allowed.
103 */
104 function check_ok_default(category in varchar2) return boolean is
105 begin
106   --
107   hr_utility.set_location('HR_PAYMENTS.CHECK_DEFAULT',1);
108   --
109   if category = 'CA' or category = 'CH' then
110     --
111     return(true);
112     --
113   else
114     --
115     hr_utility.set_message(801,'HR_6229_PAYM_BAD_DEFAULT_TYPE');
116     hr_utility.raise_error;
117     return(false);
118     --
119   end if;
120   --
121 end check_ok_default;
122 --
123 /*--------------------------- ppt_brui -----------------------------------
124 NAME
125   ppt_brui
126 DESCRIPTION
127   pay_payment_types trigger
128 NOTES
129   Calls various validation routines on new/updated row
130 */
131 procedure ppt_brui(allow_as_default in varchar2,
132                    category in varchar2,
133                    pre_validation_required in varchar2,
134                    validation_days in number,
135                    validation_value in varchar2) is
136 status boolean;
137 begin
138   --
139   if allow_as_default = 'Y' then
140     --
141     status := check_ok_default(category);
142     --
143   end if;
144   --
145   if category = 'MT' then
146     --
147     -- Mag Tape so do the required checks
148     --
149     status := validate_magnetic(pre_validation_required,
150                                 validation_days,
151                                 validation_value);
152     --
153   end if;
154   --
155 end ppt_brui;
156 --------------------------- check_account -----------------------------------
157 /*
158 NAME
159   Check_account
160 DESCRIPTION
161   Checks that the OPM has an external account in the required territory.
162 NOTES
163   If the payment type of the OPM requires an account in a certain terrritory
164   then this must be checked.
165   Returns true or false (with application error)
166 */
167 function check_account(account in varchar2,
168                        type in varchar2) return boolean is
169 required_territory varchar2(3);
170 actual_territory varchar2(3);
171 begin
172   --
173   -- One row each from EXA and PPT.
174   --
175   hr_utility.set_location('HR_PAYMENTS.CHECK_ACCOUNT',1);
176   --
177   select ppt.territory_code,
178          exa.territory_code
179   into   required_territory,
180          actual_territory
181   from   pay_payment_types ppt,
182          pay_external_accounts exa
183   where  exa.external_account_id = account
184   and    ppt.payment_type_id = type;
185   --
186   -- Check that they are the same and generate an error if not
187   --
188   hr_utility.set_location('HR_PAYMENTS.CHECK_ACCOUNT',2);
189   --
190   if required_territory <> actual_territory then
191     --
192     hr_utility.set_message(801,'HR_6220_PAYM_INVALID_ACT');
193     hr_utility.set_message_token('TERITORY',required_territory);
194     hr_utility.raise_error;
195     return(false);
196     --
197   else
198     --
199     return(true);
200     --
201   end if;
202   --
203 exception
204   --
205   when no_data_found then
206     --
207     hr_utility.set_message(801,'HR_6230_PAYM_NO_ACCT_TYPE');
208     hr_utility.raise_error;
209     return(false);
210     --
211   --
212 end check_account;
213 --
214 --------------------------- check_currency -----------------------------------
215 /*
216 NAME
217   Check_currency
218 DESCRIPTION
219   Checks that the currency required by the type is met by the OPM
220 NOTES
221   If the types of this OPM requires that payments be made in a specific
222   currency, check that this is the case.
223   Returns true or false (with application error)
224 */
225 function check_currency(type in varchar2,
226                         opm_currency in varchar2) return boolean is
227 required_currency varchar2(16);
228 begin
229   --
230   hr_utility.set_location('HR_PAYMENTS.CHECK_CURRENCY',1);
231   --
232   select ppt.currency_code
233   into   required_currency
234   from   pay_payment_types ppt
235   where  ppt.payment_type_id = type;
236   --
237   -- Check that they are the same.  If not report the error
238   --
239   if nvl(required_currency,opm_currency) <> opm_currency then
240     --
241     hr_utility.set_message(801,'HR_6231_PAYM_INVALID_CURRENCY');
242     hr_utility.set_message_token('CURRENCY',required_currency);
243     hr_utility.raise_error;
244     return(false);
245     --
246   else
247     --
248     return(true);
249     --
250   end if;
251   --
252 exception
253   --
254   when no_data_found then
255     --
256     hr_utility.set_message(801,'HR_6232_PAYM_NO_TYPE');
257     hr_utility.raise_error;
258     return(false);
259     --
260   --
261 end check_currency;
262 --
263 ---------------------------match_currency---------------------------------
264 /*
265 NAME
266     match_currency
267 DESCRIPTION
268     ensures the currency for the OPM matches that required by the balance
269     type and the payment type.
270 NOTES
271     Checks if the payment_type has a required currency and that the OPM's
272     currency matches this via check_currency. Then ensures that the currency
273     for the balance type matches this currency.
274 */
275 procedure match_currency(type in varchar2,
276                          opm_currency in varchar2,
277                          def_balance in varchar2) is
278 bal_type varchar2(9);
279 bal_currency varchar2(16);
280 begin
281  --
282  hr_utility.set_location('HR_PAYMENTS.MATCH_CURRENCY',1);
283  --
284  if check_currency(type,opm_currency) then
285  --
286    select pdb.balance_type_id
287    into bal_type
288    from pay_defined_balances pdb
289    where defined_balance_id = def_balance;
290  --
291    select pbt.currency_code
292    into bal_currency
293    from pay_balance_types pbt
294    where balance_type_id = bal_type;
295  --
296    if opm_currency <> bal_currency then
297      fnd_message.set_name('PAY','HR_7132_PAY_ORG_PAY_CURRENCY');
298      fnd_message.raise_error;
299    end if;
300  --
301  end if;
302 --
303  exception
304 --
305  when no_data_found then
306    fnd_message.set_name('PAY','HR_7133_PAY_ORG_PAYM_NO_BAL');
307    fnd_message.raise_error;
308 --
309 end match_currency;
310 --
311 --------------------------- gen_balance -----------------------------------
312 /*
313 NAME
314   gen_balance
315 DESCRIPTION
316   Generate the defined balance for pre-payments.
317 NOTES
318   There will be one balance dimension which has the attribute payments_flag
319   set to 'Y'. This is the 'payments dimesion.  There will be one defined
320   balance with this balance dimension for each legislation.  This
321   defined balance id must be inserted into the defined_balance_id column
322   of the OPM.
323   --
324 */
325 function gen_balance(leg_code in varchar2) return number is
326 no_payments_balance exception;
327 defined_balance number(16);
328 begin
329   --
330   -- Get it then (if its there)
331   --
332   hr_utility.set_location('HR_PAYMENTS.GEN_BALANCE',1);
333   --
334   select pdb.defined_balance_id
335   into   defined_balance
336   from   pay_balance_types pbt,
337          pay_balance_dimensions pbd,
338          pay_defined_balances pdb
339   where  pdb.legislation_code = leg_code
340   and    pdb.business_group_id is null
341   and    pdb.balance_dimension_id = pbd.balance_dimension_id
342   and    pbt.balance_type_id = pdb.balance_type_id
343   and    pbd.payments_flag = 'Y'
344   and    pbt.assignment_remuneration_flag = 'Y';
345   --
346   -- Return the defined balance
347   --
348   return(defined_balance);
349   --
350 exception
351   --
352   when no_data_found then
353     --
354     hr_utility.set_message(801,'HR_6233_PAYM_NO_PAY_BALANCE');
355     hr_utility.raise_error;
356     return(0);
357     --
358 end gen_balance;
359 --
360 --------------------------- check_prepay -----------------------------------
361 /*
362 NAME
363   check_prepay
364 DESCRIPTION
365   Check there are no pre-payment records for this OPM.
366 NOTES
367   The OPM may only be updated or deleted  if it has no pre-payments with an
368   effective date after the validation start date.
369 */
370 function check_prepay(opm_id in number,
371                       val_start_date in varchar2) return boolean is
372 dummy varchar2(2);
373 begin
374   --
375   hr_utility.set_location('HR_PAYMENTS.CHECK_PREPAY',1);
376   --
377   select 1
378   into   dummy
379   from   dual
380   where  not exists(
381          select 1
382          from   pay_pre_payments pp
383          where  pp.org_payment_method_id = opm_id
384          and    exists(
385                 select 1
386                 from   pay_assignment_actions aa,
387                        pay_payroll_actions pa
388                 where  pp.assignment_action_id = aa.assignment_action_id
389                 and    aa.payroll_action_id = pa.payroll_action_id
390                 and    pa.effective_date >=
391                                      fnd_date.canonical_to_date(val_start_date)));
392   --
393   -- A row returned means no pre-payments after the validation date...OK
394   --
395   return(true);
396   --
397 exception
398   --
399   when no_data_found then
400     --
401     hr_utility.set_message(801,'HR_6234_PAYM_ENTRIES_EXIST');
402     hr_utility.raise_error;
403     return(false);
404     --
405 end check_prepay;
406 --
407 --------------------------- check_ppm -----------------------------------
408 /*
409 NAME
410   check_ppm
411 DESCRIPTION
412   On delete check no PPMs depend on the OPM
413 NOTES
414   An OPM may not be deleted when there is a PPM which is dependant upon it.
415   Here DE deletes are what we are talking about.
416   eg
417      |-------------PPM-------------------|
418      |-------------OPM---------|
419                                ^
420                                DE Del Invalid
421   --
422 */
423 function check_ppm(val_start_date in varchar2,
424                    opm_id in varchar2) return boolean is
425 dummy number;
426 begin
427   --
428   -- If there is a ppm which finishes after the validation start date, then
429   -- the (DE) delete is invalid.  This case is given if no rows are returned
430   -- and is picked up in the error handler.
431   --
432   hr_utility.set_location('HR_PAYMENTS.CHECK_PPM',1);
433   --
434   select 1
435   into   dummy
436   from   dual
437   where  not exists(
438          select 1
439          from   pay_personal_payment_methods_f ppm
440          where  ppm.org_payment_method_id = opm_id
441          and    ppm.effective_end_date > fnd_date.canonical_to_date(val_start_date));
442   --
443   if dummy = 1 then
444     --
445     return(true);
446     --
447   end if;
448   --
449   return(false);     -- Never should get here
450   --
451 exception
452   --
453   when no_data_found then
454     --
455     hr_utility.set_message(801,'HR_6235_PAYM_EXISTING_PPMS');
456     hr_utility.raise_error;
457     return(false);
458     --
459 end check_ppm;
460 --
461 --------------------------- check_default -----------------------------------
462 /*
463 NAME
464   check_default
465 DESCRIPTION
466   Check that on delete there are no payrolls using this method as default.
467 NOTES
468   Each payroll must have a default payment method.  If this OPM is used as
469   default by any payrolls (DE mode) then it cannot be deleted.
470 */
471 function check_default(opm_id in varchar2,
472                        val_start_date in varchar2) return boolean is
473 valid_del varchar2(2);
474 begin
475   --
476   -- Check if any payrolls use this OPM whichare valid after the delete date.
477   --
478   hr_utility.set_location('HR_PAYMENTS.CHECK_DEFAULT',1);
479   --
480   select 'Y'
481   into   valid_del
482   from   dual
483   where  not exists(
484          select 1
485          from   pay_payrolls_f pp
486          where  pp.default_payment_method_id = opm_id
487          and    pp.effective_end_date > fnd_date.canonical_to_date(val_start_date));
488   --
489   if valid_del = 'Y' then
490     --
491     return(true);
492     --
493   end if;
494   --
495   return(false);    -- Should never be here
496   --
497 exception
498   --
499   when no_data_found then
500     --
501     hr_utility.set_message(801,'HR_6236_PAYM_USED_AS_DEFAULT');
502     hr_utility.raise_error;
503     return(false);
504     --
505 end check_default;
506 --
507 --------------------------- check_amt -----------------------------------
508 /*
509 NAME
510   check_amt
511 DESCRIPTION
512   Check the method is defined with a valid amount or percentage
513 NOTES
514   The PPM must be paid as an amount or percentage of original pay.  Check that
515   one (and only one) of these has been specified for the method.
516 */
517 function check_amt(percent in varchar2, amount in varchar2) return boolean is
518 --
519 begin
520   --
521   if amount is null and percent is not null then
522     --
523     return(true);
524     --
525   elsif amount is not null and percent is null then
526     --
527     return(true);
528     --
529   else
530     --
531     hr_utility.set_message(801,'HR_6221_PAYM_INVALID_PPM');
532     hr_utility.raise_error;
533     return(false);
534     --
535   end if;
536   --
537 end;
538 --
539 --------------------------- mt_checks -----------------------------------
540 /*
541 NAME
542   mt_checks
543 DESCRIPTION
544   Check if the PPT category is 'MT'. If so do relevant checks.
545 NOTES
546   If MT then must have a valid external account to pay into.
547 */
548 function mt_checks(opm_id in varchar2,
549                    val_start_date in varchar2,
550                    account_id in varchar2) return boolean is
551 required_territory varchar2(16);
552 actual_territory varchar2(16);
553 category varchar2(20);
554 begin
555   --
556   -- Check if an account is specified and if so get the territory
557   --
558   hr_utility.set_location('HR_PAYMENTS.MT_CHECKS',1);
559   --
560   if account_id is null then
561     --
562     actual_territory := 'NONE';
563     --
564   else
565     --
566     begin
567       --
568       -- Check the account is valid
569       --
570       select exa.territory_code
571       into   actual_territory
572       from   pay_external_accounts exa
573       where  exa.external_account_id = account_id;
574       --
575     exception
576       --
577       when no_data_found then
578         --
579         hr_utility.set_message(801,'HR_6223_PAYM_BAD_ACCT');
580         hr_utility.raise_error;
581       --
582     end;
583     --
584   end if;
585   --
586   -- Now make sure its in the right territory (if required)
587   --
588   hr_utility.set_location('HR_PAYMENTS.MT_CHECKS',2);
589   --
590   select nvl(ppt.territory_code, 'NONE'),
591          ppt.category
592   into   required_territory,
593          category
594   from   pay_payment_types ppt,
595          pay_org_payment_methods_f opm
596   where  opm.org_payment_method_id = opm_id
597   and    opm.payment_type_id = ppt.payment_type_id
598   and    fnd_date.canonical_to_date(val_start_date) between
599          opm.effective_start_date and opm.effective_end_date;
600   --
601   -- Check the category.  If it is 'MT' do the checks...
602   --
603   hr_utility.set_location('HR_PAYMENTS.MT_CHECKS',3);
604   --
605   if category = 'MT' then
606     --
607     if actual_territory <> required_territory then
608       --
609       if required_territory <> 'NONE' then
610         --
611         hr_utility.set_message(801,'HR_6220_PAYM_INVALID_ACT');
612         hr_utility.set_message_token('TERITORY',required_territory);
613         hr_utility.raise_error;
614         return(false);
615         --
616       end if;
617     end if;
618     --
619   end if;
620   --
621   return(true);
622   --
623 exception
624   --
625   when no_data_found then
626     --
627     hr_utility.set_message(801,'HR_6224_PAYM_NO_OPM');
628     hr_utility.raise_error;
629     return(false);
630     --
631 end mt_checks;
632 --
633 --------------------------- unique_priority -----------------------------------
634 /*
635 NAME
636   unique_priority
637 DESCRIPTION
638   Check the priority is unique at all times fo the assignment.
639 NOTES
640   Two PPMs for the same assignment must have different priorities, or the
641   results of pre-payments will be unrepeatable.  This is called from the form
642   and as an update/insert trigger.
643 */
644 function unique_priority(in_priority in varchar2,
645                          val_start_date in varchar2,
646                          val_end_date in varchar2,
647                          assignment in varchar2) return boolean is
648 duplicate varchar2(2);
649 begin
650   --
651   hr_utility.set_location('HR_PAYMENTS.UNIQUE_PRIORITY',1);
652   --
653   select 'N'
654   into   duplicate
655   from   sys.dual
656   where  not exists(
657          select 1
658          from   pay_personal_payment_methods_f ppm
659          where  ppm.assignment_id = assignment
660          and    ppm.priority = in_priority
661          and    fnd_date.canonical_to_date(val_start_date) < ppm.effective_end_date
662          and    fnd_date.canonical_to_date(val_end_date) > ppm.effective_start_date);
663   --
664   -- See how we did
665   --
666   if duplicate = 'N' then
667     --
668     return true;
669     --
670   end if;
671   --
672 exception
673   --
674   when no_data_found then
675     --
676     hr_utility.set_message(801,'HR_6225_PAYM_DUP_PRIORITY');
677     hr_utility.raise_error;
678     return false;
679     --
680 end unique_priority;
681 --
682 --------------------------- check_pp -----------------------------------
683 /*
684 NAME
685   check_pp
686 DESCRIPTION
687   Checks there are no outstanding pre-payments on delete
688 NOTES
689   Before deleting the PPM must make sure there are no PPs which use it after
690   val_start_date.
691 */
692 function check_pp(ppm_id in varchar2,
693                   val_start_date in varchar2) return boolean is
694 status varchar2(2);
695 begin
696   --
697   hr_utility.set_location('HR_PAYMENTS.CHECK_PP',1);
698   --
699   -- WWbug 264094. Changed below from effective_date >= val_start_date to
700   -- effective_date > val_start_date. This has the effect of allowing the
701   -- delete if there are pre-payments on the deleteion date, providing there
702   -- aren't any after the date.
703   --
704   select 'Y'
705   into   status
706   from   sys.dual
707   where  not exists(
708          select 1
709          from   pay_payroll_actions pa,
710                 pay_assignment_actions aa,
711                 pay_pre_payments pp
712          where  pp.personal_payment_method_id = ppm_id
713          and    pp.assignment_action_id = aa.assignment_action_id
714          and    aa.payroll_action_id = pa.payroll_action_id
715          and    pa.effective_date > fnd_date.canonical_to_date(val_start_date));
716   --
717   -- If there is a row, then all is cool, but check anyhow to be defensive.
718   --
719   hr_utility.set_location('HR_PAYMENTS.CHECK_PP',2);
720   --
721   if status = 'Y' then
722     --
723     return true;
724     --
725   end if;
726   --
727 exception
728   --
729   when no_data_found then
730     --
731     -- This means future PPs exist so flag it.
732     --
733     hr_utility.set_message(801,'HR_6226_PAYM_PPS_EXIST');
734     hr_utility.raise_error;
735     return false;
736     --
737 end check_pp;
738 --
739 
740 
741 --------------------------- check_ppm -----------------------------------
742 /*
743 NAME
744   check_ppm used for selfservice pages
745 DESCRIPTION
746   Checks there are no outstanding pre-payments on update
747 NOTES
748   Before updating the PPM must make sure there are no PPs for the particular
749   transaction Added for bug 10392383
750 */
751 
752 procedure check_ppm(trans_step_id in varchar2,
753                     status out nocopy varchar2) is
754 ppm_id Number(9);
755 eff_date date;
756 begin
757   --
758   status := 'Y';
759   hr_utility.set_location('HR_PAYMENTS.CHECK_PPM',1);
760   hr_utility.trace('trans_step_id is '||trans_step_id);
761 
762   /*Handled the No Data Found for the bug 13010568 */
763 
764   begin
765 	  SELECT  personal_payment_method_id
766 		       ,effective_date
767 	  INTO   ppm_id, eff_date
768 		FROM    pay_pss_transaction_steps
769 		WHERE   transaction_step_id = trans_step_id;
770   exception
771   --
772 	  when no_data_found then
773 	     hr_utility.set_location('HR_PAYMENTS.CHECK_PPM',11);
774 	     status := 'Y';
775 	     return;
776   end;
777 
778   hr_utility.set_location('HR_PAYMENTS.CHECK_PPM',2);
779 
780   select 'Y'
781   into   status
782   from   sys.dual
783   where  not exists(
784          select 1
785          from   pay_payroll_actions pa,
786                 pay_assignment_actions aa,
787                 pay_pre_payments pp
788          where  pp.personal_payment_method_id = ppm_id
789          and    pp.assignment_action_id = aa.assignment_action_id
790          and    aa.payroll_action_id = pa.payroll_action_id
791          and    pa.effective_date > eff_date);
792 
793   hr_utility.set_location('HR_PAYMENTS.CHECK_PPM',4);
794   --
795   if status = 'Y' then
796      status := 'Y';
797     --
798   end if;
799   --
800 exception
801   --
802   when no_data_found then
803     hr_utility.set_location('HR_PAYMENTS.CHECK_PPM',5);
804      status := 'N';
805     --
806 end check_ppm;
807 --
808 end hr_payments;