1 package body hr_chkfmt as
2 /* $Header: pychkfmt.pkb 120.7 2007/11/06 10:38:55 ayegappa noship $ */
3
4 g_group_sep_profile CONSTANT VARCHAR2(2) := NVL(fnd_profile.value('HR_NUMBER_SEPARATOR'),'N');
5
6 FUNCTION add_remove_group_separator ( input IN VARCHAR2
7 , remove_separator IN BOOLEAN DEFAULT FALSE)
8 RETURN VARCHAR2
9 IS
10 l_output VARCHAR2(100);
11 l_group_separator VARCHAR2(2) := substr(ltrim(to_char(1032,'0G999')),2,1);
12 --NVL(SUBSTR(fnd_profile.value('ICX_NUMERIC_CHARACTERS'),2,1),',');
13 l_dec_separator VARCHAR2(2) := substr(ltrim(to_char(.3,'0D0')),2,1);
14 --NVL(SUBSTR(fnd_profile.value('ICX_NUMERIC_CHARACTERS'),1,1),'.');
15 l_negative_flag BOOLEAN := FALSE ;
16 BEGIN
17
18 IF remove_separator THEN
19 l_output := REPLACE(input,l_group_separator,'');
20 ELSE
21
22 IF (input<0 and input>-1) THEN -- Added for bug 5707731.
23 l_negative_flag := TRUE;
24 END IF;
25
26 l_output := LTRIM(TO_CHAR( TRUNC(TO_NUMBER(input)), '99G999G999G999G999G999G990'));
27
28 IF INSTR(input,l_dec_separator) <> 0 THEN
29 l_output := l_output || l_dec_separator || SUBSTR(input,INSTR(input,l_dec_separator) + 1);
30 END IF;
31
32 IF (l_negative_flag) THEN -- Added for bug 5707731
33 l_output := '-' || l_output ;
34 END IF;
35
36
37 END IF;
38
39 RETURN l_output;
40
41 END add_remove_group_separator;
42
43 ----------------------------- chkmoney ----------------------------------
44 /*
45 NAME
46 chkmoney - format currency.
47 DESCRIPTION
48 Formats and checks currency input.
49 Uses FND_CURRENCIES to get information about precision.
50 NOTES
51 p_value can be passed in in either NLS or canonical format, as
52 indicated by p_value_is_canonical. p_value is always returned in
53 NLS format, rounded and padded according to the rules in table
54 fnd_currencies.
55 */
56 PROCEDURE chkmoney
57 (
58 p_value IN OUT NOCOPY VARCHAR2, -- the input to be formatted (see notes).
59 p_output IN OUT NOCOPY VARCHAR2, -- the canonical format of returned p_value.
60 p_curcode IN VARCHAR2, -- currency code.
61 p_minimum IN VARCHAR2, -- minimum in canonical format.
62 p_maximum IN VARCHAR2, -- maximum in canonical format.
63 p_rgeflg IN OUT NOCOPY VARCHAR2, -- success or otherwise of range check.
64 p_result OUT NOCOPY BOOLEAN, -- the result of the format check.
65 p_value_is_canonical IN BOOLEAN --TRUE if value is passed IN in canonical format.
66 ) IS
67 RGE_SUCC CONSTANT VARCHAR2(1) := 'S';
68 RGE_FAIL CONSTANT VARCHAR2(1) := 'F';
69 --
70 -- Max and min value that can be handled by the money format.
71 --
72 MAX_VALUE CONSTANT NUMBER := 99999999999999999999;
73 MIN_VALUE CONSTANT NUMBER := -99999999999999999999;
74
75 nvalue NUMBER; -- used to hold p_value as a number.
76 noutput NUMBER; -- used to hold p_output as a number.
77 l_value VARCHAR2(100);
78 BEGIN
79 p_result := TRUE;
80 IF p_value_is_canonical THEN
81 nvalue := fnd_number.canonical_to_number( p_value );
82 ELSE
83 IF g_group_sep_profile = 'Y' THEN
84 l_value := add_remove_group_separator(p_value,TRUE);
85 IF p_value = l_value THEN
86 nvalue := TO_NUMBER( l_value );
87 ELSIF p_value = add_remove_group_separator(l_value) THEN
88 nvalue := TO_NUMBER(l_value);
89 ELSE
90 nvalue := p_value;
91 p_result := FALSE;
92 END IF;
93 ELSE
94 nvalue := TO_NUMBER( p_value ); --uses session NLS settings.
95 END IF;
96 END IF;
97 SELECT DECODE --round to min acct limits if available.
98 ( fc.minimum_accountable_unit,
99 NULL, ROUND( nvalue, fc.precision ),
100 ROUND( nvalue / fc.minimum_accountable_unit ) * fc.minimum_accountable_unit
101 )
102 , LTRIM
103 ( TO_CHAR
104 ( DECODE --round to min acct limits if available.
105 ( fc.minimum_accountable_unit,
106 NULL, ROUND( nvalue, fc.precision ),
107 ROUND( nvalue / fc.minimum_accountable_unit ) * fc.minimum_accountable_unit
108 )
109 , CONCAT --construct NLS format mask.
110 ( '99999999999999999990', --currencies formatted without NLS 'G'.
111 DECODE( fc.precision, 0, '', RPAD( 'D', fc.precision+1, '9' ) )
112 )
113 ), ' ' --left trim white space.
114 )
115 INTO noutput
116 , p_value
117 FROM fnd_currencies fc
118 WHERE fc.currency_code = p_curcode;
119 -- range checking.
120 IF p_minimum IS NOT NULL THEN
121 IF noutput < fnd_number.canonical_to_number( p_minimum ) THEN
122 p_rgeflg := RGE_FAIL;
123 END IF;
124 END IF;
125 IF p_maximum IS NOT NULL THEN
126 IF noutput > fnd_number.canonical_to_number( p_maximum ) THEN
127 p_rgeflg := RGE_FAIL;
128 END IF;
129 END IF;
130
131 IF not (noutput between MIN_VALUE and MAX_VALUE) then
132 p_result := FALSE;
133 END IF;
134
135 IF g_group_sep_profile = 'Y' THEN
136 p_value := add_remove_group_separator(p_value);
137 END IF;
138
139 p_output := fnd_number.number_to_canonical( noutput );
140 EXCEPTION
141 -- this catches illegal numbers.
142 WHEN VALUE_ERROR THEN
143 p_result := FALSE;
144 WHEN OTHERS THEN
145 p_result := FALSE;
146 END chkmoney;
147 --
148 ------------------------------ chkdech ----------------------------------
149 /*
150 NAME
151 chkdech - format check hours in decimal format..
152 DESCRIPTION
153 Converts p_value to an NLS VARCHAR2 representation with p_format
154 number of significant decimal places.
155 P_result returns FALSE if p_value fails conversion to a number.
156 NOTES
157 p_value can be passed in in either NLS or canonical format, as
158 indicated by p_value_is_canonical. p_value is always returned in
159 NLS format, rounded and padded according to p_format.
160 */
161 PROCEDURE chkdech
162 (
163 p_value IN OUT NOCOPY VARCHAR2, -- the input to be formatted.
164 p_format IN VARCHAR2, -- the specific format.
165 p_minimum IN VARCHAR2, -- minimum in canonical format.
166 p_maximum IN VARCHAR2, -- maximum in canonical format.
167 p_rgeflg IN OUT NOCOPY VARCHAR2, -- success or otherwise of range check.
168 p_result OUT NOCOPY BOOLEAN, -- the result of the format check.
169 p_value_is_canonical IN BOOLEAN --TRUE if value is passed IN in canonical format.
170 ) IS
171 RGE_SUCC CONSTANT VARCHAR2(1) := 'S';
172 RGE_FAIL CONSTANT VARCHAR2(1) := 'F';
173 decplace PLS_INTEGER; -- number of decimal places.
174 nvalue NUMBER; -- used to hold p_value as a number.
175 BEGIN
176 p_result := TRUE; -- start by assuming success.
177 IF p_value_is_canonical THEN
178 nvalue := fnd_number.canonical_to_number( p_value );
179 ELSE
180 nvalue := TO_NUMBER( p_value ); --uses session NLS settings.
181 END IF;
182 -- can get dec places from the last character of the format:
183 IF p_format = 'HOURS' THEN
184 decplace := 3; -- for backwards compatability.
185 ELSE
186 decplace := TO_NUMBER( SUBSTR( p_format, -1, 1 ) );
187 END IF;
188 -- round and format the number.
189 nvalue := ROUND( nvalue, decplace );
190 SELECT LTRIM( TO_CHAR( nvalue, CONCAT( '999999999999990',
191 DECODE( decplace, 0, '', RPAD( 'D', decplace+1, '9' ) ) ) ) , ' ' )
192 INTO p_value
193 FROM dual;
194 -- range checking.
195 IF p_minimum IS NOT NULL THEN
196 IF nvalue < fnd_number.canonical_to_number( p_minimum ) THEN
197 p_rgeflg := RGE_FAIL;
198 END IF;
199 END IF;
200 IF p_maximum IS NOT NULL THEN
201 IF nvalue > fnd_number.canonical_to_number( p_maximum ) THEN
202 p_rgeflg := RGE_FAIL;
203 END IF;
204 END IF;
205 EXCEPTION
206 WHEN OTHERS THEN --when varchar2 conversion to number fails.
207 p_result := FALSE;
208 END chkdech;
209 --
210 --------------------------------- chknum --------------------------------
211 /*
212 NAME
213 chknum - check format of number
214 DESCRIPTION
215 Check format of number (decimal) and integer.
216 P_result returns FALSE if p_value fails conversion to a number.
217 NOTES
218 p_value can be passed in in either NLS or canonical format, as
219 indicated by p_value_is_canonical. p_value is always returned in
220 NLS format (integers are unaffected by NLS formatting). Note
221 Decimal separater is still required, even for whole decimal
222 numbers. E.g. 20 becomes '20.'.
223 */
224 PROCEDURE chknum
225 (
226 p_value IN OUT NOCOPY VARCHAR2, -- value to be formatted.
227 p_output IN OUT NOCOPY VARCHAR2, -- the canonical format of returned p_value.
228 p_minimum IN VARCHAR2, -- minimum in canonical format.
229 p_maximum IN VARCHAR2, -- maximum in canonical format.
230 p_rgeflg IN OUT NOCOPY VARCHAR2, -- success or otherwise of range check.
231 p_format IN VARCHAR2, -- the format to check.
235 RGE_SUCC CONSTANT VARCHAR2(1) := 'S';
232 p_result OUT NOCOPY BOOLEAN, -- true (success) or false (failure).
233 p_value_is_canonical IN BOOLEAN --TRUE if value is passed IN in canonical format.
234 ) IS
236 RGE_FAIL CONSTANT VARCHAR2(1) := 'F';
237
238 --
239 -- Max and min value that can be handled by the number format.
240 --
241 MAX_VALUE CONSTANT NUMBER := 99999999999999999999;
242 MIN_VALUE CONSTANT NUMBER := -99999999999999999999;
243
244 nvalue NUMBER; -- used to hold p_value as a number.
245 l_value VARCHAR2(100);
246 BEGIN
247 p_result := TRUE; -- start by assuming success.
248 IF p_value_is_canonical THEN
249 nvalue := fnd_number.canonical_to_number( p_value );
250 ELSE
251 IF g_group_sep_profile = 'Y' THEN
252 l_value := add_remove_group_separator(p_value,TRUE);
253 IF p_value = l_value THEN
254 nvalue := TO_NUMBER( l_value );
255 ELSIF p_value = add_remove_group_separator(l_value) THEN
256 nvalue := TO_NUMBER(l_value);
257 ELSE
258 nvalue := p_value;
259 p_result := FALSE;
260 END IF;
261 ELSE
262 nvalue := TO_NUMBER( p_value ); --uses session NLS settings.
263 END IF;
264 END IF;
265
266 IF p_format = 'INTEGER' or p_format = 'I' THEN
267 IF MOD( nvalue, 1 ) <> 0 THEN
268 p_result := FALSE; --p_value is not an integer.
269 ELSE
270 p_value := TO_CHAR( nvalue ); --integers do not have Decimal separater.
271 END IF;
272 ELSE
273 -- Convert number to NLS string.
274 if (nvalue = trunc(nvalue)) then
275 p_value := LTRIM( TO_CHAR( nvalue, '99999999999999999990' ) );
276 else
277 p_value := LTRIM( RTRIM( TO_CHAR( nvalue,
278 '99999999999999999990D99999999999999999999' ), '0' ) );
279 end if;
280 END IF;
281 -- range checking.
282 IF p_minimum IS NOT NULL THEN
283 IF nvalue < fnd_number.canonical_to_number( p_minimum ) THEN
284 p_rgeflg := RGE_FAIL;
285 END IF;
286 END IF;
287 IF p_maximum IS NOT NULL THEN
288 IF nvalue > fnd_number.canonical_to_number( p_maximum ) THEN
289 p_rgeflg := RGE_FAIL;
290 END IF;
291 END IF;
292
293 IF not (nvalue between MIN_VALUE and MAX_VALUE) then
294 p_result := FALSE;
295 END IF;
296
297 p_output := fnd_number.number_to_canonical(p_value);
298
299 IF g_group_sep_profile = 'Y' THEN
300 p_value := add_remove_group_separator(p_value);
301 END IF;
302 EXCEPTION
303 WHEN OTHERS THEN --when varchar2 conversion to number fails.
304 p_result := FALSE;
305 END chknum;
306 --
307 --------------------------- checkformat -----------------------------------
308 /*
309 NAME
310 checkformat - checks format of various inputs.
311 DESCRIPTION
312 Entry point for the checkformat routine.
313 Is used to check the validity of the following formats:
314 CHAR : arbitrary string of characters.
315 UPPER : converts string to upper case.
316 LOWER : converts string to lower case.
317 INITCAP : init caps string.
318 INTEGER : checks that input is integer.
319 NUMBER : checks input is valid decimal number.
320 ND : Same as number, (another days format).
321 TIMES : checks input is valid time.
322 DATE : checks input is valid date (DD-MON-YYYY).
323 HOURS : checks input is valid number of hours.
324 DB_ITEM_NAME : checks input is valid database item name.
325 PAY_NAME : checks input is valid payroll name.
326 NACHA : checks input contains valid nacha digits.
327 KANA : checks input is KANA character.
331 Use canonical format for decimal numbers.
328 NOTES
329 This procedure is called directly from FF RSP user exit.
330 Maximum and minimum parameters:
332 */
336 format in varchar2, -- the format to check.
333 procedure checkformat
334 (
335 value in out nocopy varchar2, -- the value to be formatted.
337 output in out nocopy varchar2, -- the formatted value on output.
338 minimum in varchar2, -- minimum value (can be null).
339 maximum in varchar2, -- maximum value (can be null).
340 nullok in varchar2, -- is ok to be null ?
341 rgeflg in out nocopy varchar2, -- used for range checking.
342 curcode in varchar2 -- currency code to be used for money format.
343 ) is
344 result boolean;
345 RGE_SUCC constant varchar2(1) := 'S';
346 RGE_FAIL constant varchar2(1) := 'F';
347 --
348 -------------------------------- chkdate --------------------------------
349 /*
350 NAME
351 chkdate - check format of date
352 DESCRIPTION
353 Checks date formats.
354 NOTES
355 The following date formats are now handled:
356 Specified Real Input Field Output Field
357 ------------ ----------- ----------- ------------
358 D_DDMONYY DD-MON-RR 28-JAN-92 28-JAN-1992
359 D_DDMONYYYY DD-MON-RRRR 28-JAN-1992 28-JAN-1992
360 D_DDMONYYYY DD-MON-RRRR 28-AUG-01 28-AUG-2001
361 D_DDMMYY DD-MM-RR 28-01-92 28-JAN-1992
362 D_DDMMYYYY DD-MM-RRRR 28-01-1992 28-JAN-1992
363 D_DDMMYYYY DD-MM-RRRR 28-01-01 28-JAN-2001
364 D_MMDDYY MM-DD-RR 01-28-02 28-JAN-2002
365 D_MMDDYYYY MM-DD-RRRR 01-28-1992 28-JAN-1992
366 D_MMDDYYYY MM-DD-RRRR 01-28-01 28-JAN-2001
367 --
368 - If format is one of the 'YYYY' types, and only 'YY'
369 value is input, the date is output using century rounding.
370 See the examples above.
371 - The exception handler is used to detect illegal dates.
372 - Range checking is allowed on all formats, but the
373 limits must be in the same format as the input.
374 - The output format is always in 'DD-MON-YYYY'.
375 - If the input format has a 2 digit year
376 */
377 procedure chkdate
378 (
379 value in out nocopy varchar2, -- date value to be checked.
380 format in varchar2, -- the particular date format.
381 output in out nocopy varchar2, -- the converted date format.
382 minimum in varchar2, -- minimum date.
383 maximum in varchar2, -- maximum date.
384 rgeflg in out nocopy varchar2, -- success or otherwise of range check.
385 result out nocopy boolean -- format success or fail.
386 ) is
387 realfmt varchar2(11); -- the real format.
388 l_date date;
389 begin
390
391 result := TRUE;
392 -- now check that we have the correct date format
393 -- passed in.
394 l_date := fnd_date.displaydate_to_date(value);
395 --
396 -- the date format has been correctly verified.
397 -- now return it to the output field in the
398 -- canonical format of of 'YYYY/MM/DD'
399 output := fnd_date.date_to_canonical(l_date);
400 --
401 -- Return the corrected format to the output.
402 -- Needed for instance where user inputs a
403 -- value like '01-jan-99' which we want displayed
404 -- as '01-JAN-1999'.
405 value := fnd_date.date_to_displaydate(l_date);
406 --
407 -- minimum and maximum checking.
408 if(minimum is not null) then
409 if(l_date < fnd_date.canonical_to_date(minimum)) then
410 rgeflg := RGE_FAIL;
411 return;
412 end if;
413 end if;
414 if(maximum is not null) then
415 if(l_date > fnd_date.canonical_to_date(maximum)) then
416 rgeflg := RGE_FAIL;
417 return;
418 end if;
419 end if;
420 exception
421 -- have to user the 'others' exception, since there is
422 -- no specific exception to catch illegal date formats.
423 when others then
424 result := FALSE;
425 end chkdate;
426 --
427 ------------------------------- chkhours --------------------------------
428 /*
429 NAME
430 chkhours - check hours format and convert.
431 DESCRIPTION
432 Performs the following actions. Firstly, validates
433 hours in the following formats: H_HH, H_HHMM, H_HHMMSS.
434 Secondly, it converts these to an internal format,
435 which is currently number(40,20).
436 Will perform conversions such as 112:3 -> 112:30.
437 NOTES
438 <none>
439 */
440 procedure chkhours
441 (
442 value in out nocopy varchar2, -- the input value to be formatted.
443 format in varchar2, -- the specific format.
444 output in out nocopy varchar2, -- value in canonical format.
445 minimum in varchar2, -- min hours value in canonical format.
446 maximum in varchar2, -- min hours value in canonical format.
447 rgeflg in out nocopy varchar2, -- indicate success or otherwise of range.
448 result out nocopy boolean -- success or failure flag.
449 ) is
450 INT_PREC constant number := 20; -- internal format precision.
451 SEPARATOR constant varchar2(1) := ':';
452 MIN_HHMM constant number := 3;
453 MIN_HHMMSS constant number := 6;
454 hours varchar2(40);
455 minutes varchar2(40);
456 seconds varchar2(40);
457 minplussec varchar2(40); -- holds minutes + seconds string.
458 len number; -- length of the input string.
459 minseppos number; -- minute separator position.
460 secseppos number; -- seconds separator position.
464 minutes := 0;
461 negative boolean; -- is the input negative??
462 begin
463 hours := 0;
465 seconds := 0;
466 negative := FALSE;
467 -- if the first character of the input
468 -- is a minus sign, we assume the input is negative.
469 if(substr(value,1,1) = '-') then
470 negative := TRUE;
471 value := substr(value,2); -- remove the minus sign.
472 end if;
473 -- bug 6522314. Added nvl
474 len := nvl(length(value),0); -- len of input without any negation sign.
475 -- get the values of hours, minutes and seconds,
476 -- depending on the format passed.
477 if(format = 'H_HH') then
478 -- check is number and integer.
479 if(trunc(value) <> value) then
480 result := FALSE;
481 return;
482 end if;
483 hours := value;
484 elsif(format = 'H_HHMM') then
485 declare
486 check_fmt varchar2(10);
487 begin
488 if(len < MIN_HHMM) then
489 result := FALSE;
490 return;
491 end if;
492 minseppos := instr(value,SEPARATOR); -- where is the colon char.
493 -- error if either the separator is the first or last
494 -- character, or there is an illegal separator.
495 if(minseppos = 1 or minseppos = len or minseppos = 0) then
496 result := FALSE;
497 return;
498 end if;
499 hours := substr(value,1,(minseppos - 1)); -- hours string.
500 minutes := substr(value,(minseppos + 1),len); -- minutes string.
501 -- Check that we do not have any illegal
502 -- characters in our format.
503 check_fmt := to_char(to_date(minutes,'MI'),'MI');
504 minutes := rpad(minutes,2,'0'); -- format correctly.
505 end;
506 elsif(format = 'H_HHMMSS') then
507 minseppos := instr(value,SEPARATOR); -- pos of minutes sep.
508 -- Check that we have a legal minutes separator.
509 if(minseppos = 1 or minseppos = len or minseppos = 0) then
510 result := FALSE;
511 return;
512 end if;
513 hours := substr(value,1,(minseppos - 1));
514 -- check that the hours string represents an integer.
515 if(trunc(hours) <> hours) then
516 result := FALSE;
517 return;
518 end if;
519 minplussec := substr(value,(minseppos + 1),len);
520 minutes := to_char(to_date(minplussec,'MI:SS'),'MI');
521 seconds := to_char(to_date(minplussec,'MI:SS'),'SS');
522 end if;
523 --
524 -- apply some sanity checks.
525 if(hours < 0 or minutes < 0 or minutes > 59 or
526 seconds < 0 or seconds > 59) then
527 result := FALSE;
528 return;
529 end if;
530 --
531 -- do the output of the format.
532 if(format = 'H_HHMM') then
533 value := hours || SEPARATOR || minutes;
534 elsif(format = 'H_HHMMSS') then
535 value := hours || SEPARATOR || minutes || SEPARATOR || seconds;
536 else
537 -- format is H_HH.
538 null;
539 end if;
540 --
541 -- output the converted value.
542 output := fnd_number.number_to_canonical(
543 round(hours + (minutes/60) + (seconds/3600),INT_PREC) );
544 --
545 -- having done the checks, we need to check
546 -- if we originally had negative input
547 if(negative = TRUE) then
548 output := '-' || output;
549 value := '-' || value;
550 end if;
551 -- minimum and maximum checking.
552 if(minimum is not null) then
553 if(fnd_number.canonical_to_number(output) <
554 fnd_number.canonical_to_number(minimum)) then
555 rgeflg := RGE_FAIL;
556 return;
557 end if;
558 end if;
559 if(maximum is not null) then
560 if(fnd_number.canonical_to_number(output) >
561 fnd_number.canonical_to_number(maximum)) then
562 rgeflg := RGE_FAIL;
563 return;
564 end if;
565 end if;
566 exception
567 -- this exception could be raised if illegal
568 -- number supplied as a minimum or maximum.
569 when value_error then
570 result := FALSE;
571 when others then
572 result := FALSE;
573 end chkhours;
574 --
575 -------------------------------- chktime --------------------------------
576 /*
577 NAME
578 chktime - check the format of time.
579 DESCRIPTION
580 Routine checks that time is correcly formatted.
581 Will do format conversions like '2:2' -> '02:20'.
582 NOTES
583 Exceptions processing used to catch any illegal
584 time formats passed to routine.
585 */
586 procedure chktime
587 (
588 value in out nocopy varchar2,
589 minimum in varchar2, -- minimum allow able value
590 maximum in varchar2, -- maximum allowable value
591 rgeflg in out nocopy varchar2, -- success or otherwise of range check.
592 result out nocopy boolean
593 ) is
594 TIME_SEPARATOR constant varchar2(1) := ':'; -- make this a constant.
595 isdate date; -- used when checking is legal date.
596 hours varchar2(2); -- hold hours component.
597 minutes varchar2(2); -- hold minutes component.
598 len number; -- length of string.
599 seppos number; -- the character position of the time separator.
600 --
601 begin
605 if(seppos = 0) then
602 -- first thing, check that we have a legal oracle time format.
603 isdate := to_date(value,'HH24:MI'); -- raises exception if not.
604 seppos := instr(value,TIME_SEPARATOR); -- look for legal separator.
606 result := FALSE;
607 return;
608 end if;
609 -- separate hours and minutes.
610 len := length(value); -- how long the time string.
611 hours := substr(value,1,(seppos - 1)); -- get hours string.
612 minutes := substr(value,(seppos + 1),len); -- get minutes string.
613 -- now we put them together using lpad and rpad to format correctly.
614 value := lpad(hours,2,'0') || TIME_SEPARATOR || rpad(minutes,2,'0');
615 --
616 -- check this again following formatting.
617 isdate := to_date(value,'HH24:MI');
618 --
619 result := TRUE;
620 if(minimum is not null) then
621 if(isdate <
622 to_date(minimum,'HH24:MI')) then
623 rgeflg := RGE_FAIL;
624 return;
625 end if;
626 end if;
627 if(maximum is not null) then
628 if(isdate >
629 to_date(maximum,'HH24:MI')) then
630 rgeflg := RGE_FAIL;
631 return;
632 end if;
633 end if;
634 exception
635 -- use 'others' exception because there are
636 -- no specific errors we can trap for illegal times.
637 when others then
638 result := FALSE;
639 end chktime;
640 --
641 -------------------------------- chkpay ---------------------------------
642 /*
643 NAME
644 chkpay - check payroll name does not contain illegal characters.
645 DESCRIPTION
646 Used to ensure that a name passed in only comprises of:
647 First character : alpha characters (upper or lower case).
648 Subsequent chars: alpha, numeric, space and underscore.
649 NOTES
650 Use the translate function and dbms_sql package to check for
651 illegal chars. Cannot be called from pragma restrict_references
652 code.
653 */
654 function chkpay
655 (
656 value in varchar2 -- the name to check.
657 ) return boolean is
658 l_cursor_id binary_integer; -- Cursor for dynamic PL/SQL.
659 statement varchar2(2000); -- Dynamic PL/SQL statement.
660
661 copy varchar2(240); -- Copy of string without spaces.
662
663 chunk varchar2(2000); -- Chunk to be syntax-checked.
664 spos integer; -- Start position of chunk in input string.
665 epos integer; -- End position of chunk in input string.
666 clen number; -- Length of input string in characters.
667 first boolean; -- Is this the first chunk being processed ?
668
669 -- The following string will be added to any chunks to avoid problems
670 -- with reserved words being rejected.
671 MUCK constant varchar2(3) := 'ZQX';
672
673 -- Variables for checking for PL/SQL characters that aren't
674 -- allowed in name syntax.
675 exchk varchar2(240);
676 match varchar2(240);
677 PADCH constant varchar2(1) := '$';
678
679 SPACE constant varchar2(1) := ' ';
680
681 -- Valid PL/SQL identifier name characters that are are illegal
682 -- in HR, Payroll, and Formula names.
683 PLSQL_EXCLUDE varchar2(64);
684 -- Maximum length of the name being checked in bytes.
685 MAX_NAME_LEN constant number := 80;
686 -- Maximum PL/SQL name length in bytes.
687 MAX_PLSQL_LEN constant number := 30;
688 begin
689 -------------------------------------------------------------
690 -- Name syntax is a letter followed by a string containing --
691 -- letters, digits, ' ', and '_'. PL/SQL does not have any --
692 -- character classification functions e.g. to say what's a --
693 -- 'letter' or a 'digit'. PL/SQL identifier name syntax is --
694 -- the same as the name syntax except that it allows '#' --
695 -- and '$' characters in the names, and allows " quoted --
696 -- identifier names which may contain spaces. --
697 -------------------------------------------------------------
698 -- The basic algorithm is to use the input value as a --
699 -- PL/SQL identifier name in some dynamic PL/SQL code. The --
700 -- PL/SQL parser will syntax check the value as a PL/SQL --
701 -- identifier name - if an error is detected an exception --
702 -- will be raised. The code can reject values that contain --
703 -- '#', '$', or could be quoted identifiers, before trying --
704 -- to parse the dynamic PL/SQL. If the parse is okay, the --
705 -- syntax is okay. The algorithm is slightly complicated --
706 -- by fact the PL/SQL names may only be up 30 bytes in --
707 -- length, whereas the names being checked may be up to 80 --
708 -- bytes in length. The input value is chopped into chunks --
709 -- of size 30 bytes or less and the PL/SQL test is run on --
710 -- the chunks. --
711 -------------------------------------------------------------
712
713 if ( ( value is not null or length( value ) <> 0 ) and
714 lengthb( value ) <= MAX_NAME_LEN ) then
715
716 -- Set up the PL/SQL exclusion characters.
717 PLSQL_EXCLUDE := '"$#' || to_multi_byte( '"$#' );
718
719 -- Check that the string does not contain any excluded PL/SQL
720 -- characters.
721 match := PADCH;
722 match := lpad( match, length( PLSQL_EXCLUDE ), PADCH );
723 exchk := translate( value, PLSQL_EXCLUDE, match );
724 exchk := replace( exchk, PADCH, '' );
728
725 if ( exchk is null or length( exchk ) < length( value ) ) then
726 return( FALSE );
727 end if;
729 -- We have to operate on a copy of the string without the spaces
730 -- because PL/SQL variable names may not contain spaces.
731 if ( substr( value, 1, 1 ) = SPACE ) then
732 return( FALSE );
733 end if;
734 copy := replace( value, SPACE, '' );
735 clen := length( copy );
736
737 -- Check the name string chunk by chunk. Need to do this chunk
738 -- by chunk because string can be longer than the PL/SQL allows.
739
740 -- Set up information for the first chunk to be checked.
741 first := TRUE;
742 spos := 1;
743 epos := clen;
744 chunk := copy || MUCK;
745
746 while ( spos <= clen ) loop
747 -- Make sure that the chunk is short enough for PL/SQL to
748 -- handle.
749 while ( lengthb( chunk ) > MAX_PLSQL_LEN ) loop
750 epos := ( spos + epos ) / 2;
751 if ( first ) then
752 -- Append MUCK to make sure that the start of the name
753 -- is okay.
754 chunk := substr( copy, spos, epos - spos + 1 ) || MUCK;
755 else
756 -- Prepend MUCK because the chunk may not start with a
757 -- letter.
758 chunk := MUCK || substr( copy, spos, epos - spos + 1 );
759 end if;
760 end loop;
761
762 if ( first ) then
763 first := FALSE;
764 end if;
765
766 -- Build a dynamic SQL statement using the name as a variable
767 -- name. This will syntax check the name as a valid PL/SQL name.
768 statement := 'DECLARE ' || chunk || ' NUMBER;BEGIN ' ||
769 chunk || ':=1;END;';
770 l_cursor_id := dbms_sql.open_cursor;
771 dbms_sql.parse( l_cursor_id, statement, dbms_sql.native );
772 dbms_sql.close_cursor( l_cursor_id );
773
774 -- Move onto next the chunk.
775 spos := epos + 1;
776 epos := clen;
777 if ( spos <= clen ) then
778 -- Prepend MUCK because the chunk may not start
779 -- with a letter.
780 chunk := MUCK || substr( copy, spos, epos - spos + 1 );
781 end if;
782 end loop;
783
784 -- Exited the loop without problems, so value is good.
785 return( TRUE );
786 else
787 -- String is null, zero length, or too long.
788 return( FALSE );
789 end if;
790
791 -- Exception handler to catch errors in the dynamic SQL ie.
792 -- the syntax of the chunk being tested is invalid.
793 exception
794 when others then
795 begin
796 --
797 -- Make sure that the cursor was closed.
798 --
799 if ( dbms_sql.is_open( l_cursor_id ) ) then
800 dbms_sql.close_cursor( l_cursor_id );
801 end if;
802 return( FALSE );
803 end;
804 end chkpay;
805 --
806 -------------------------------- chkdbi ---------------------------------
807 /*
808 NAME
809 chkdbi - check format of database item name.
810 DESCRIPTION
811 Check that db item name only contains legal characters.
812 The are the following:
813 First character : upper or lower case alphabetic characters.
814 Subsequent chars: alpha, numeric or underscore.
815
816 JULY-2004: introduced a new style of database item name where
817 any text within double-quotes is allowed.
818
819 NOTES
820 Use the translate function and dbms_sql package to check for
821 illegal chars. Cannot be called from pragma restrict_references
822 code.
823 */
824 function chkdbi
825 (
826 value in varchar2 -- the name to check.
827 ) return boolean is
828 l_cursor_id binary_integer; -- Cursor for dynamic PL/SQL.
829 statement varchar2(2000); -- Dynamic PL/SQL statement.
830
831 chunk varchar2(2000); -- Chunk to be syntax-checked.
832 spos integer; -- Start position of chunk in input string.
833 epos integer; -- End position of chunk in input string.
834 clen number; -- Length of input string in characters.
835 first boolean; -- Is this the first chunk being processed ?
836
837 -- The following string will be added to any chunks to avoid problems
838 -- with reserved words being rejected.
839 MUCK constant varchar2(3) := 'ZQX';
840
841 -- Variables for checking for PL/SQL characters that aren't
842 -- allowed in name syntax.
843 exchk varchar2(240);
844 match varchar2(240);
845 PADCH constant varchar2(1) := '$';
846
847 -- Valid PL/SQL identifier name characters that are are illegal
848 -- in HR, Payroll, and Formula names.
849 PLSQL_EXCLUDE varchar2(64);
850 -- Maximum length of the name being checked in characters.
851 MAX_NAME_LEN constant number := 160;
852 -- Maximum PL/SQL name length in bytes.
853 MAX_PLSQL_LEN constant number := 30;
854 -- Maximum name length in bytes.
855 MAX_BYTE_LENGTH constant number := 240;
856
857 QUOTE1 varchar2(16);
858 QUOTE2 varchar2(16);
859 thechar varchar2(16);
860 begin
861 -------------------------------------------------------------
862 -- Name syntax is a letter followed by a string containing --
866 -- the same as the name syntax except that it allows '#' --
863 -- letters, digits, and '_'. PL/SQL does not have any --
864 -- character classification functions e.g. to say what's a --
865 -- 'letter' or a 'digit'. PL/SQL identifier name syntax is --
867 -- and '$' characters in the names, and allows " quoted --
868 -- identifier names which may contain spaces. --
869 -------------------------------------------------------------
870 -- The basic algorithm is to use the input value as a --
871 -- PL/SQL identifier name in some dynamic PL/SQL code. The --
872 -- PL/SQL parser will syntax check the value as a PL/SQL --
873 -- identifier name - if an error is detected an exception --
874 -- will be raised. The code can reject values that contain --
875 -- '#', '$', or could be quoted identifiers, before trying --
876 -- to parse the dynamic PL/SQL. If the parse is okay, the --
877 -- syntax is okay. The algorithm is slightly complicated --
878 -- by fact the PL/SQL names may only be up 30 bytes in --
879 -- length, whereas the names being checked may be up to 80 --
880 -- bytes in length. The input value is chopped into chunks --
881 -- of size 30 bytes or less and the PL/SQL test is run on --
882 -- the chunks. --
883 -------------------------------------------------------------
884
885 if ( ( value is not null or length( value ) <> 0 ) and
886 length( value ) <= MAX_NAME_LEN
887 and lengthb( value ) <= MAX_BYTE_LENGTH ) then
888 --
889 -- First look for double-quote delimited value.
890 --
891 QUOTE1 := '"';
892 QUOTE2 := to_multi_byte('"');
893 thechar := substr(value, 1, 1);
894 if thechar = QUOTE1 or thechar = QUOTE2 then
895 --
896 -- Minimum acceptable string is "".
897 --
898 clen := length(value);
899 if clen = 1 then
900 return FALSE;
901 end if;
902 --
903 -- Check for end-quote.
904 --
905 thechar := substr(value, clen, 1);
906 if thechar = QUOTE1 or thechar = QUOTE2 then
907 --
908 -- Quotes must be paired within the string.
909 --
910 if clen > 2 then
911 --
912 -- Strip off start and end quotes.
913 --
914 chunk := substr(value, 2, clen - 2);
915 while chunk is not null and
916 instr(chunk, QUOTE1) <> 0 and
917 instr(chunk, QUOTE2) <> 0 loop
918 thechar := substr(chunk, 1, 1);
919 if thechar = QUOTE1 or thechar = QUOTE2 then
920 thechar := substr(chunk, 2, 1);
921 if thechar is not null and
922 (thechar = QUOTE1 or thechar = QUOTE2) then
923 --
924 -- Skip the paired quotes.
925 --
926 chunk := substr(chunk, 3);
927 else
928 --
929 -- Error because of unpaired quote.
930 --
931 return FALSE;
932 end if;
933 else
934 --
935 -- Skip the first character.
936 --
937 chunk := substr(chunk, 2);
938 end if;
939 end loop;
940 end if;
941 --
942 -- It's got here so it's valid.
943 --
944 return TRUE;
945 end if;
946 --
947 -- No end-quote found.
948 --
949 return FALSE;
950 end if;
951
952 -- Set up the PL/SQL exclusion characters.
953 PLSQL_EXCLUDE := '"$#' || to_multi_byte( '"$#' );
954
955 -- Save the length (in characters) of the input string.
956 clen := length( value );
957
958 -- Check that the string does not contain any excluded PL/SQL
959 -- characters.
960 match := PADCH;
961 match := lpad( match, length( PLSQL_EXCLUDE ), PADCH );
962 exchk := translate( value, PLSQL_EXCLUDE, match );
963 exchk := replace( exchk, PADCH, '' );
964 if ( exchk is null or length( exchk ) < clen ) then
965 return( FALSE );
966 end if;
967
968 -- Check the name string chunk by chunk. Need to do this chunk
969 -- by chunk because string can be longer than the PL/SQL allows.
970
971 -- Set up information for the first chunk to be checked.
972 first := TRUE;
973 spos := 1;
974 epos := clen;
975 chunk := value || MUCK;
976
977 while ( spos <= clen ) loop
978 -- Make sure that the chunk is short enough for PL/SQL to
979 -- handle.
980 while ( lengthb( chunk ) > MAX_PLSQL_LEN ) loop
981 epos := ( spos + epos ) / 2;
982 if ( first ) then
983 -- Append MUCK to make sure that the start of the name
984 -- is okay.
985 chunk := substr( value, spos, epos - spos + 1 ) || MUCK;
986 else
987 -- Prepend MUCK because the chunk may not start with a
988 -- letter.
989 chunk := MUCK || substr( value, spos, epos - spos + 1 );
993 if ( first ) then
990 end if;
991 end loop;
992
994 first := FALSE;
995 end if;
996
997 -- Build a dynamic SQL statement using the name as a variable
998 -- name. This will syntax check the name as a valid PL/SQL name.
999 statement := 'DECLARE ' || chunk || ' NUMBER;BEGIN ' ||
1000 chunk || ':=1;END;';
1001 l_cursor_id := dbms_sql.open_cursor;
1002 dbms_sql.parse( l_cursor_id, statement, dbms_sql.native );
1003 dbms_sql.close_cursor( l_cursor_id );
1004
1005 -- Move onto next the chunk.
1006 spos := epos + 1;
1007 epos := clen;
1008 if ( spos <= clen ) then
1009 -- Prepend MUCK because the chunk may not start
1010 -- with a letter.
1011 chunk := MUCK || substr( value, spos, epos - spos + 1 );
1012 end if;
1013 end loop;
1014
1015 -- Exited the loop without problems, so value is good.
1016 return( TRUE );
1017 else
1018 -- String is null, zero length, or too long.
1019 return( FALSE );
1020 end if;
1021
1022 -- Exception handler to catch errors in the dynamic SQL ie.
1023 -- the syntax of the chunk being tested is invalid.
1024 exception
1025 when others then
1026 begin
1027 --
1028 -- Make sure that the cursor was closed.
1029 --
1030 if ( dbms_sql.is_open( l_cursor_id ) ) then
1031 dbms_sql.close_cursor( l_cursor_id );
1032 end if;
1033 return( FALSE );
1034 end;
1035 end chkdbi;
1036 --
1037 -------------------------------- chknacha -------------------------------
1038 /*
1039 NAME
1040 chkknacha - check legal NACHA string.
1041 DESCRIPTION
1042 Checks that inputs used for NACHA only contain
1043 a certain defined range of characters. These are:
1044 0-9, A-Z (upper case), blank, asterisk, ampersand,
1045 comma, hyphen, decimal and dollar.
1046 NOTES
1047 Uses translate to check for illegal characters.
1048 */
1049 procedure chknacha
1050 (
1051 value in out nocopy varchar2, -- the name to check.
1052 result out nocopy boolean -- result of the formatting.
1053 ) is
1054 trres varchar(240); -- result from the translate statement.
1055 legal varchar(100); -- holds list of legal characters.
1056 match varchar(100); -- holds match characters for translate.
1057 ALPHA constant varchar2(52) := 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
1058 NUMERIC constant varchar(10) := '0123456789';
1059 SPECIAL constant varchar(8) := '*&,-.$_ ';
1060 LEGCHAR constant varchar(1) := '*';
1061 begin
1062 -- convert any alpha characters to upper case.
1063 value := nls_upper(value);
1064 -- build up list of legal characters for first character.
1065 legal := ALPHA;
1066 -- now do a translate on the first character of value.
1067 trres := translate(substr(value,1,1),legal,LEGCHAR);
1068 if(nvl(trres,LEGCHAR) <> LEGCHAR) then
1069 result := FALSE;
1070 return;
1071 end if;
1072 -- if string is longer than one character,
1073 -- check the full legal list.
1074 if(length(value) > 1) then
1075 legal := ALPHA || NUMERIC || SPECIAL;
1076 match := lpad(LEGCHAR,length(legal),LEGCHAR);
1077 trres := translate(substr(value,2),legal,LEGCHAR);
1078 trres := replace(trres,LEGCHAR,'');
1079 -- if all characters in value are legal, trres should be null.
1080 if(trres is not null) then
1081 result := FALSE;
1082 return;
1083 end if;
1084 end if;
1085 end chknacha;
1086 --
1087 ------------------------ chk_half_kana --------------------------------
1088 procedure chk_half_kana(value in varchar2,
1089 result out nocopy boolean) is
1090 l_charset varchar2(64) := substr(userenv('language'),instr(userenv('language'),'.')+1);
1091 l_strlen number := length(value);
1092 l_ch varchar2(5);
1093 l_correct BOOLEAN := TRUE;
1094 i number := 1;
1095 begin
1096 --
1097 -- make sure that all the characters are half kana
1098 --
1099 while i <= l_strlen and l_correct loop
1100 l_ch := substr(value, i, 1);
1101 --
1102 -- Check if characters are valid against the characterset.
1103 --
1104 if l_charset='JA16SJIS' then
1105 if not ascii(l_ch) between 32 and 126 and
1106 not ascii(l_ch) between 161 and 223 then
1107 l_correct := FALSE;
1108 end if;
1109 elsif l_charset='JA16EUC' then
1110 if not ascii(l_ch) between 32 and 126 and
1111 not ascii(l_ch) between 36513 and 36575 then
1112 l_correct := FALSE;
1113 end if;
1114 elsif (l_charset='UTF8' or l_charset='AL32UTF8') then
1115 if not ascii(l_ch) between 32 and 126 and
1116 not ascii(l_ch) between 15711649 and 15711679 and
1117 not ascii(l_ch) between 15711872 and 15711903 then
1118 l_correct := FALSE;
1119 end if;
1120 else
1121 -- (Bug 1477718)
1122 -- Exit and return true when another characterset is used.
1123 --
1124 exit;
1125 end if;
1126 i := i + 1;
1127 end loop;
1128 --
1129 -- Set out variable
1130 --
1131 result:=l_correct;
1132 --
1133 end chk_half_kana;
1137 -- start by checking if the input is allowed to be null.
1134 --
1135 begin
1136 rgeflg := RGE_SUCC; -- start by saying range checking succeeded.
1138 if(nullok = 'N' and value is null) then
1139 hr_utility.set_message(801,'HR_51159_INVAL_VALUE_FORMAT');
1140 hr_utility.raise_error;
1141 end if;
1142 -- if ok to be null and value is null, then return immediately.
1143 if(nullok = 'Y' and value is null) then
1144 output := NULL;
1145 return;
1146 end if;
1147 -- Choose correct action for format specifier.
1148 if(format = 'CHAR' or format = 'C') then
1149 -- we can have minimum and maximum values.
1150 if(minimum is not null) then
1151 if(value < minimum) then
1152 rgeflg := RGE_FAIL;
1153 end if;
1154 end if;
1155 if(maximum is not null) then
1156 if(value > maximum) then
1157 rgeflg := RGE_FAIL;
1158 end if;
1159 end if;
1160 output := value;
1161 elsif(format = 'UPPER') then
1162 value := nls_upper(value);
1163 output := value;
1164 elsif(format = 'LOWER') then
1165 value := nls_lower(value);
1166 output := value;
1167 elsif(format = 'INITCAP') then
1168 value := nls_initcap(value);
1169 output := value;
1170 --
1171 elsif(format = 'M' or format = 'MONEY') then
1172 chkmoney(value,output,curcode,minimum,maximum,rgeflg,result,FALSE);
1173 if(result = FALSE) then
1174 hr_utility.set_message(801,'HR_51152_INVAL_MON_FORMAT');
1175 hr_utility.raise_error;
1176 end if;
1177 elsif(format = 'I' or format = 'N' or format = 'NUMBER'
1178 or format = 'ND') then
1179 chknum(value,output,minimum,maximum,rgeflg,format,result,FALSE);
1180 if(result = FALSE) then
1181 hr_utility.set_message(801,'HR_51153_INVAL_NUM_FORMAT');
1182 hr_utility.raise_error;
1183 end if;
1184 --output is in canonical format
1185 --output := fnd_number.number_to_canonical( to_number(value) );
1186 elsif(format = 'H_HH' or format = 'H_HHMM' or
1187 format = 'H_HHMMSS') then
1188 chkhours(value,format,output,minimum,maximum,rgeflg,result);
1189 if(result = FALSE) then
1190 hr_utility.set_message(801,'HR_51153_INVAL_NUM_FORMAT');
1191 hr_utility.raise_error;
1192 end if;
1193 elsif(format = 'TIMES' or format = 'T') then
1194 chktime(value, minimum, maximum, rgeflg, result);
1195 if(result = FALSE) then
1196 hr_utility.set_message(801,'HR_51154_INVAL_TIME_FORMAT');
1197 hr_utility.raise_error;
1198 end if;
1199 output := value;
1200
1201 --elsif(format = 'D_DDMONYY' or format = 'D_DDMONYYYY' or
1202 --format = 'D_DDMMYY' or format = 'D_DDMMYYYY' or
1203 --format = 'D_MMDDYY' or format = 'D_MMDDYYYY' or
1204 --format = 'DATE') then
1205 elsif (format = 'D' or format = 'DATE') then
1206 chkdate(value,format,output,minimum,maximum,rgeflg,result);
1207 if(result = FALSE) then
1208 hr_utility.set_message(801,'HR_51155_INVAL_DATE_FORMAT');
1209 hr_utility.raise_error;
1210 end if;
1211 elsif(format = 'H_DECIMAL1' or format = 'H_DECIMAL2'
1212 or format = 'H_DECIMAL3' or format = 'HOURS') then
1213 chkdech(value,format,minimum,maximum,rgeflg,result,FALSE);
1214 if(result = FALSE) then
1215 hr_utility.set_message(801,'HR_51153_INVAL_NUM_FORMAT');
1216 hr_utility.raise_error;
1217 end if;
1218 --output is in canonical format
1219 output := fnd_number.number_to_canonical( to_number(value) );
1220 elsif(format = 'DB_ITEM_NAME') then
1221 if(chkdbi(value) = FALSE) then
1222 hr_utility.set_message(801,'HR_51156_INVAL_NUM_FORMAT');
1223 hr_utility.raise_error;
1224 end if;
1225 output := value;
1226 elsif(format = 'PAY_NAME') then
1227 if(chkpay(value) = FALSE) then
1228 hr_utility.set_message(801,'HR_51157_INVAL_PAY_NAME_FORMAT');
1229 hr_utility.raise_error;
1230 end if;
1231 output := value;
1232 elsif(format = 'NACHA') then
1233 chknacha(value,result); -- check for legal NACHA characters
1234 if(result = FALSE) then
1235 hr_utility.set_message(801,'HR_51158_INVAL_NACHA_FORMAT');
1236 hr_utility.raise_error;
1237 end if;
1238 output := value;
1239 elsif(format = 'KANA'or format = 'K') then
1240 chk_half_kana(value,result);
1241 if(result = FALSE) then
1242 hr_utility.set_message(801, 'HR_72021_PER_INVALID_KANA');
1243 hr_utility.raise_error;
1244 end if;
1245 else
1246 -- invalid format.
1247 hr_utility.set_message(801,'HR_51159_INVAL_VALUE_FORMAT');
1248 hr_utility.raise_error;
1249 end if;
1250 end checkformat;
1251 --
1252 --------------------------- changeformat -----------------------------------
1253 /*
1254 NAME
1255 changeformat - converts from internal to external formats.
1256 DESCRIPTION
1257 Is called when you need to convert from a format that is
1258 held in one format internally but which needs to be
1259 displayed in another format.
1260 NOTES
1261 Currently, the following formats require conversion:
1262 date formats, money and H_HHMM/H_HHMMSS.
1263 */
1264 function changeformat
1265 (
1266 input in varchar2, -- the input format.
1267 format in varchar2, -- indicates the format to convert to.
1268 curcode in varchar2 -- currency code for money format.
1269 ) return varchar2 is
1270 --
1271 value varchar2(240); -- needed when calling chkdech.
1272 rgeflg varchar2(1); -- needed when calling chkdech.
1276 ---------------------------- to_money ----------------------------------
1273 result boolean; -- needed when calling chkdech.
1274 output varchar2(240); -- the output format.
1275 --
1277 /*
1278 NAME
1279 to_money - converts internal currency format to external one.
1280 DESCRIPTION
1281 Converts a decimal number (in which currency is held)
1282 to the external format.
1283 NOTES
1284 Currently, the internal and external formats are the same,
1285 but this function exists as a stub for later use.
1286 */
1287 function to_money
1288 (
1289 input in varchar2, -- the input to format.
1290 curcode in varchar2 -- the currency code.
1291 ) return varchar2 is
1292 value varchar2(240);
1293 output varchar2(240);
1294 rgeflg varchar2(10);
1295 result boolean;
1296 begin
1297 -- use the checkformat procedure to handle format.
1298 value := input;
1299 chkmoney(value,output,curcode,null,null,rgeflg,result,TRUE);
1300 return(value);
1301 end to_money;
1302 --
1303 ---------------------------- to_hours -----------------------------------
1304 /*
1305 NAME
1306 to_hours - converts decimal hours to hours formats.
1307 DESCRIPTION
1308 This converts from decimal into either H_HHMM or H_HHMMSS.
1309 NOTES
1310 <none>
1311 */
1312 function to_hours(input in varchar2, format in varchar2)
1313 return varchar2 is
1314 hours varchar2(100); -- holds the hours string.
1315 mins number; -- holds minutes (and seconds) string.
1316 begin
1317 -- separate hours string.
1318 hours := trunc(fnd_number.canonical_to_number( input ));
1319 mins := abs(round((fnd_number.canonical_to_number( input ) - hours)
1320 * 3600));
1321 --
1322 -- Bugfix 4269787
1323 -- If mins has been rounded to 3600 we have 1 hour!
1324 if mins = 3600 then
1325 hours := hours+1;
1326 mins := 0;
1327 end if;
1328 --
1329 -- Bugfix 3650335
1330 -- Ensure the sign of the input is maintained.
1331 if hours = '0' and mins > 0
1332 and sign(fnd_number.canonical_to_number(input)) = -1 then
1333 --
1334 -- Prefix the hours value with a minus sign as this will have been
1335 -- lost in the conversion process.
1336 --
1337 hours := '-'||hours;
1338 --
1339 end if;
1340 --
1341 -- process diffferently for H_HHMM and H_HHMMSS.
1342 if(format = 'H_HHMM') then
1343 return(hours || ':' ||
1344 to_char(to_date(to_char(mins),'SSSSS'),'MI'));
1345 else
1346 return(hours || ':' ||
1347 to_char(to_date(to_char(mins),'SSSSS'),'MI:SS'));
1348 end if;
1349 end to_hours;
1350 --
1351 ---------------------------- conv_date ----------------------------------
1352 /*
1353 NAME
1354 conv_date - convert internal to displayed date format.
1355 DESCRIPTION
1356 Dates are converted from the universal internal format
1357 of 'DD-MON-YYYY' to whatever is specified by 'format'.
1358 NOTES
1359 <none>
1360 */
1361 function conv_date(input in varchar2,format in varchar2)
1362 return varchar2 is
1363 l_date date ;
1364 oraformat varchar2(11);
1365 begin
1366 if(format = 'D' or format = 'DATE') then
1367 l_date := fnd_date.canonical_to_date(input) ;
1368 else
1369 oraformat := 'UNKNOWN'; -- this should cause failure.
1370 end if;
1371 --
1372 -- now convert to external format.
1373 return(fnd_date.date_to_displaydate(l_date));
1374 end conv_date;
1375 --
1376 begin
1377 if(input is null) then
1378 output := NULL; -- if input is null, do not do any processing.
1379 -- main statement to do the conversion.
1380 else
1381 if(format = 'H_HHMM' or format = 'H_HHMMSS') then
1382 output := to_hours(input,format);
1383 elsif(format = 'M' or format = 'MONEY') then
1384 output := to_money(input,curcode);
1385 elsif(format like 'H_DECIMAL%') then
1386 value := input;
1387 chkdech(value,format,null,null,rgeflg,result,TRUE);
1388 output := value;
1389 elsif(format = 'N' or format = 'NUMBER' or format = 'ND') then
1390 value := input;
1391 chknum(value,output,null,null,rgeflg,format,result,TRUE);
1392 output := value;
1393 elsif(format = 'INTEGER' or format = 'I' ) then
1394 value := input;
1395 chknum(value,output,null,null,rgeflg,format,result,TRUE);
1396 output := value;
1397 elsif(format = 'D' or format = 'DATE') then
1398 -- convert to required external format.
1399 output := conv_date(input,format);
1400 else
1401 -- all other formats remain the same.
1402 output := input;
1403 end if;
1404 end if;
1405 return(output);
1406 end changeformat;
1407 --
1408 --------------------------- changeformat -----------------------------------
1409 /*
1410 NAME
1411 changeformat - converts from internal to external formats.
1412 DESCRIPTION
1413 Is called when you need to convert from a format that is
1414 held in one format internally but which needs to be
1415 displayed in another format.
1416 NOTES
1417 Currently, the following formats require conversion:
1418 date formats, money and H_HHMM/H_HHMMSS.
1419 */
1420 procedure changeformat
1421 (
1422 input in varchar2, -- the input format.
1426 ) is
1423 output out nocopy varchar2, -- the output formated
1424 format in varchar2, -- indicates the format to convert to.
1425 curcode in varchar2 -- currency code for money format.
1427 begin
1428 output := changeformat(input, format, curcode);
1429 end changeformat;
1430 --
1431 end hr_chkfmt;