1 PACKAGE BODY gl_currency_api AS
2 /* $Header: glustcrb.pls 120.7 2005/05/05 01:44:15 kvora ship $ */
3
4 ---
5 --- PRIVATE VARIABLES
6 ---
7
8 ---
9 --- PRIVATE FUNCTIONS
10 ---
11
12 --
13 -- Procedure
14 -- get_info
15 --
16 -- Purpose
17 -- Gets the currency type information about given currency.
18 -- Also set the x_invalid_currency flag if the given currency is invalid.
19 --
20 -- History
21 -- 15-JUL-97 W Wong Created
22 --
23 -- Arguments
24 -- x_currency Currency to be checked
25 -- x_eff_date Effecitve date
26 -- x_conversion_rate Fixed rate for conversion
27 -- x_mau Minimum accountable unit
28 -- x_currency_type Type of currency specified in x_currency
29 --
30 PROCEDURE get_info(
31 x_currency VARCHAR2,
32 x_eff_date DATE,
33 x_conversion_rate IN OUT NOCOPY NUMBER,
34 x_mau IN OUT NOCOPY NUMBER,
35 x_currency_type IN OUT NOCOPY VARCHAR2 ) IS
36
37 BEGIN
38 -- Get currency information from FND_CURRENCIES table
39 SELECT decode( derive_type,
40 'EURO', 'EURO',
41 'EMU', decode( sign( trunc(x_eff_date) -
42 trunc(derive_effective)),
43 -1, 'OTHER',
44 'EMU'),
45 'OTHER' ),
46 decode( derive_type, 'EURO', 1,
47 'EMU', derive_factor,
48 'OTHER', -1 ),
49 nvl( minimum_accountable_unit, power( 10, (-1 * precision)))
50 INTO x_currency_type,
51 x_conversion_rate,
52 x_mau
53 FROM FND_CURRENCIES
54 WHERE currency_code = x_currency;
55
56 EXCEPTION
57 WHEN NO_DATA_FOUND THEN
58 raise INVALID_CURRENCY;
59
60 END get_info;
61
62 --
63 -- Function
64 -- get_fixed_conv_rate
65 --
66 -- Purpose
67 -- Returns Fixed conversion rate between two currencies
68 -- where both currencies are not the EURO, or EMU currencies.
69 -- This routine hits the GL_FIXED_CONV_RATES.
70 --
71 -- History
72 -- 01-Mar-2005 Srini Pala Created
73 --
74 -- Arguments
75 -- x_from_currency From currency
76 -- x_to_currency To currency
77 -- x_conversion_date Conversion date
78 -- x_conversion_type Conversion type
79 -- l_fixed_conv_rate Fixed conversion rate.
80 --
81
82 PROCEDURE get_fixed_conv_rate(x_from_currency IN OUT NOCOPY VARCHAR2,
83 x_to_currency IN OUT NOCOPY VARCHAR2,
84 x_conversion_date Date,
85 x_conversion_type VARCHAR2 ,
86 x_fixed_conv_rate OUT NOCOPY NUMBER) IS
87
88 direct_from_fix_rate NUMBER;
89 l_fix_rate NUMBER;
90
91 inverse_to_fix_rate NUMBER;
92 new_from_currency VARCHAR2(15);
93 new_to_currency VARCHAR2(15);
94 l_fixed_relation VARCHAR2(15);
95 l_currency_from VARCHAR2(15);
96 l_currency_to VARCHAR2(15);
97 l_continue BOOLEAN := FALSE;
98 l_final_rate NUMBER;
99
100 CURSOR is_there_fixed_rate(l_from_curr VARCHAR2,
101 l_to_curr VARCHAR2,
102 l_eff_date DATE) IS
103 SELECT old_currency,
104 replacement_currency,
105 fixed_conversion_rate
106 FROM GL_FIXED_CONV_RATES
107 WHERE old_currency IN (l_from_curr,l_to_curr)
108 AND effective_start_date <= trunc(l_eff_date)
109 ORDER BY DECODE(old_currency, l_from_curr,0,1);
110 BEGIN
111 l_currency_from := x_from_currency;
112 l_currency_to := x_to_currency;
113 direct_from_fix_rate := 1;
114 inverse_to_fix_rate := 1;
115
116 IF(x_from_currency = x_to_currency) THEN
117 x_fixed_conv_rate := 1;
118 END IF;
119
120 /*-----------------------------------------------------------------------+
121 This routine should check whether there is a fixed rate relationship
122 exist between the from currency and the to_currency in the
123 GL_FIXED_CONV_RATES table.
124 Some EUROPEAN countries are getting rid of ending zero's
125 from their currency. In this case those countries define
126 a fixed rate relationship between the old currency and the new
127 replacement currency starting from an effective date.
128 For example Turky replaced thier old currency with the new currency
129 and effective from 01-01-2005.
130 If we want to find a conversion between old Turky currency and
131 USD, then we need to follow the following rule after 01-01-2005.
132 First find rate between
133 OLD Turky Currency -> New Turky Currency in GL_FIXED_CONV_RATES
134 Then
135 New Turky Currency -> USD in GL_DAILY_RATES table.
136 The following code added to do this job.
137 +-----------------------------------------------------------------------*/
138
139 /* ********************************************************************+
140 | A few possible different scenarios |
141 | The rate may be calculated between two currencies as follows |
142 | |
143 | 1) Old Currency to French Franks |
144 | Old Currency -> New Currency from the GL_FIXED_CONV_RATES table |
145 | New Currency -> EURO from the GL_DAILY_RATES |
146 | EURO -> FRENCH FRANK fixed rate from the FND_CURRENCIES |
147 | |
148 | 2) USD to New Currency |
149 | USD -> New CURRENCY from the GL Daily Rates Table. |
150 | |
151 | 3) USD to Old Currency |
152 | USD -> New CURRENCY from the GL Daily Rates Table. |
153 | New curency -> Old Currency fixed rate |
154 | from GL Fixed Conv Rates |
155 | |
156 | 4) Old Currency to CAD |
157 | Old Currency -> New Currency from |
158 | the GL_FIXED_CONV_RATES table |
159 | New Currency -> CAD from the GL_DAILY_RATES |
160 | |
161 +######################################################################*/
162 -- Check the passed currencies have any fixed relationships exist or not.
163 -- This check avoids unnecssary processing if there is no fixed
164 -- rate relationship.
165
166 OPEN is_there_fixed_rate(l_currency_from,
167 l_currency_to,
168 x_conversion_date);
169
170 FETCH is_there_fixed_rate INTO new_from_currency,
171 new_to_currency,
172 l_fix_rate;
173
174 IF (is_there_fixed_rate%FOUND) THEN
175 l_continue := TRUE;
176 ELSE
177 l_continue := FALSE;
178 direct_from_fix_rate := 1;
179 inverse_to_fix_rate := 1;
180 x_fixed_conv_rate := 1;
181 CLOSE is_there_fixed_rate;
182 END IF;
183
184 /*---------------------------------------------------------------------+
185 | First try finding a fixed conversion from the old currency column. |
186 | If there is a rate, then it is fine, otherwise try to find the |
187 | inverse rate by querying on replacement currency. |
188 | If there exists a fixed conversion relationship, then set the |
189 | x_from_currency to retrive the rate between the new currency to the |
190 | x_to_currency from GL_DAILY_RATES table. |
191 | |
192 | ************THIS PART HANDLES ON THE FROM CURRENCY SIDE.********* |
193 | |
194 | IF x_from_currency = OLD TURKY currency |
195 | Then it finds OLD TURKY CURRENCY to NEW TURKEY CURRENCY |
196 | If x_to_currency = NEW TURKY CURRENCY then this part |
197 | alone returns the final rate. |
198 | Else It will find the other part of the rate from |
199 | GL Daily Rates table. |
200 | New Turky Currency to USD |
201 +---------------------------------------------------------------------*/
202
203 IF ( l_continue) THEN
204
205 IF (l_currency_from = new_from_currency) THEN
206 direct_from_fix_rate:= l_fix_rate;
207 x_from_currency := new_to_currency;
208
209 ELSIF (l_currency_to = new_from_currency) THEN
210 inverse_to_fix_rate := 1/l_fix_rate;
211 x_to_currency := new_to_currency;
212
213 END IF;
214
215 /*---------------------------------------------------------------------+
216 | This part handles when we are trying to find a rate from |
217 | one coutries old currency to another coutries old currency. |
218 | For example Find a rate between Old1->Old2 |
219 | Then Old1-> NEW1 from GL_FIXED_CONV_RATES, |
220 | New1->New2 from GL_DAILY_RATE |
221 | New2->Old2 from GL_FIXED_CONV_RATES The following code |
222 | handles this calculation. |
223 +---------------------------------------------------------------------*/
224 -- Fetch the second row if there exists one.
225
226 FETCH is_there_fixed_rate INTO new_from_currency,
227 new_to_currency,
228 l_fix_rate;
229
230 If (is_there_fixed_rate%FOUND) THEN
231
232
233 IF (l_currency_to = new_from_currency) THEN
234 inverse_to_fix_rate :=1/l_fix_rate;
235 x_to_currency := new_to_currency;
236
237 END IF;
238
239 End If;
240
241
242 CLOSE is_there_fixed_rate;
243
244 l_final_rate := (direct_from_fix_rate* inverse_to_fix_rate);
245 x_fixed_conv_rate := l_final_rate;
246
247 END IF; -- End of if (l_continue)
248 END;
249
250
251 --
252 -- Function
253 -- get_other_rate
254 --
255 -- Purpose
256 -- Returns conversion rate between two currencies where both currencies
257 -- are not the EURO, or EMU currencies.
258 --
259 -- History
260 -- 15-JUL-97 W Wong Created
261 --
262 -- 14-Mar-2005 Srini Pala Fixed rate relationship enhancements
263 -- are made.
264 -- Arguments
265 -- x_from_currency From currency
266 -- x_to_currency To currency
267 -- x_conversion_date Conversion date
268 -- x_conversion_type Conversion type
269 --
270 FUNCTION get_other_rate (
271 x_from_currency VARCHAR2,
272 x_to_currency VARCHAR2,
273 x_conversion_date Date,
274 x_conversion_type VARCHAR2 ) RETURN NUMBER IS
275
276 rate NUMBER;
277 l_from_currency VARCHAR2(15);
278 l_to_currency VARCHAR2(15);
279 l_fix_rate NUMBER;
280
281 BEGIN
282
283 l_from_currency := x_from_currency;
284 l_to_currency := x_to_currency;
285
286 IF(x_from_currency = x_to_currency) THEN
287 return (1);
288 END IF;
289
290 -- Get the Fixed conversion rate if there exists one.
291
292 get_fixed_conv_rate(l_from_currency,
293 l_to_currency,
294 x_conversion_date,
295 x_conversion_type,
296 l_fix_rate);
297
298
299 IF (l_from_currency = l_to_currency) THEN
300
301 rate := 1;
302
303 ELSE
304 -- Get conversion rate between the two currencies from GL_DAILY_RATES
305 SELECT conversion_rate
306 INTO rate
307 FROM GL_DAILY_RATES
308 WHERE from_currency = l_from_currency
309 AND to_currency = l_to_currency
310 AND conversion_date = trunc(x_conversion_date)
311 AND conversion_type = x_conversion_type;
312 END IF;
313
314 return(l_fix_rate*rate );
315
316 EXCEPTION
317 WHEN NO_DATA_FOUND THEN
318 raise NO_RATE;
319 END get_other_rate;
320
321
322 --
323 -- Function
324 -- get_other_closest_rate
325 --
326 -- Purpose
327 -- Returns conversion rate between two currencies where both currencies
328 -- are not the EURO, or EMU currencies.
329 --
330 -- History
331 -- 15-JUL-97 W Wong Created
332 --
333 -- 14-MAR-2005 Srini Pala Added Fixed conversion rate relationship
334 -- logic.
338 -- x_from_currency From currency
335 -- More detailed explanation is in the
336 -- get_fixed_conv_rate() routine.
337 -- Arguments
339 -- x_to_currency To currency
340 -- x_conversion_date Conversion date
341 -- x_conversion_type Conversion type
342 -- x_max_roll_days Number of days to rollback for a rate
343 --
344 FUNCTION get_other_closest_rate (
345 x_from_currency VARCHAR2,
346 x_to_currency VARCHAR2,
347 x_conversion_date Date,
348 x_conversion_type VARCHAR2,
349 x_max_roll_days NUMBER ) RETURN NUMBER IS
350
351 -- This cursor finds the latest rate defined between the given two
352 -- currencies using x_conversion_type within the period between
353 -- x_max_roll_days prior to x_conversion_date AND x_conversion_date.
354 CURSOR closest_rate_curr(g_from_currency VARCHAR2,
355 g_to_currency VARCHAR2) IS
356 SELECT conversion_rate
357 FROM GL_DAILY_RATES
358 WHERE from_currency = g_from_currency
359 AND to_currency = g_to_currency
360 AND conversion_type = x_conversion_type
361 AND conversion_date BETWEEN
362 ( decode( sign (x_max_roll_days),
363 1, trunc(x_conversion_date) - x_max_roll_days,
364 -1, trunc(to_date('1000/01/01', 'YYYY/MM/DD'))))
365 AND trunc(x_conversion_date)
366 ORDER BY conversion_date DESC;
367
368 rate NUMBER;
369 l_from_curr VARCHAR2(15);
370 l_to_curr VARCHAR2(15);
371 l_fixed_conv_rate NUMBER;
372
373 BEGIN
374
375 l_from_curr := x_from_currency;
376 l_to_curr := x_to_currency;
377
378 -- Try to search for a rate on the given conversion date
379 rate := get_other_rate( x_from_currency,
380 x_to_currency,
381 x_conversion_date,
382 x_conversion_type );
383
384 return( rate );
385
386 EXCEPTION
387 -- No conversion rate was found on the given conversion date.
388 -- Try to search for the latest conversion rate with a prior conversion
389 -- date then x_conversion_date.
390 WHEN NO_RATE THEN
391 IF ( x_max_roll_days = 0 ) THEN
392 -- Do not search backwards for the conversion rate.
393 raise NO_RATE;
394
395 ELSE
396 -- Get the Fixed conversion rate if there exists one.
397
398 get_fixed_conv_rate(l_from_curr,
399 l_to_curr,
400 x_conversion_date,
401 x_conversion_type,
402 l_fixed_conv_rate);
403
404 IF (l_from_curr <> l_to_curr) THEN
405 -- Search backwards for a conversion rate with the given currencies
406 -- and conversion type.
407 OPEN closest_rate_curr(l_from_curr, l_to_curr);
408 FETCH closest_rate_curr INTO rate;
409
410 IF NOT closest_rate_curr%FOUND THEN
411 raise NO_RATE;
412 ELSE
413 return( rate * l_fixed_conv_rate);
414 END IF;
415 ELSE
416 return (l_fixed_conv_rate);
417 END IF;
418
419 END IF;
420
421 END get_other_closest_rate;
422
423
424 ---
425 --- PUBLIC FUNCTIONS
426 ---
427
428 --
429 -- Function
430 -- is_fixed_rate
431 --
432 -- Purpose
433 -- Returns if there is a fixed rate between the two currencies.
434 --
435 -- History
436 -- 15-JUL-97 W Wong Created
437 -- 14-MAR-2005 Srini Pala Added Fixed conversion rate relationship
438 -- logic.
439 -- More detailed explanation is in
440 -- the get_fixed_conv_rate() routine.
441 --
442 -- Arguments
443 -- x_from_currency From currency
444 -- x_to_currency To currency
445 -- x_effective_date Effective date
446 --
447 FUNCTION is_fixed_rate (
448 x_from_currency VARCHAR2,
449 x_to_currency VARCHAR2,
450 x_effective_date DATE ) RETURN VARCHAR2 IS
451
452 to_type VARCHAR2(8);
453 from_type VARCHAR2(8);
454 rate NUMBER; -- Value ignored in this function
455 mau NUMBER; -- Value ignored in this function
456
457 /* Fixed conversion relationships enhancements start */
458 CURSOR is_there_fix_rate(l_from_curr VARCHAR2,
459 l_to_curr VARCHAR2,
460 l_eff_date DATE) IS
461 SELECT 'EXIST'
462 FROM GL_FIXED_CONV_RATES
463 WHERE old_currency IN (l_from_curr,l_to_curr)
464 AND ((old_currency = l_from_curr
465 AND replacement_currency = l_to_curr)
466 OR (replacement_currency = l_from_curr
467 AND old_currency = l_to_curr))
468 AND effective_start_date <= trunc(l_eff_date)
469 AND ROWNUM =1;
470 l_fix_rate VARCHAR2(10);
471
472 /* Fixed conversion relationships enhancements End */
473
474
475 BEGIN
479 END IF;
476 -- Check if both currencies are identical
477 IF ( x_from_currency = x_to_currency ) THEN
478 return 'Y';
480
481 -- Get currency information of the x_from_currency
482 get_info( x_from_currency, x_effective_date, rate, mau, from_type );
483
484 -- Get currency information of the x_to_currency
485 get_info( x_to_currency, x_effective_date, rate, mau, to_type );
486
487 -- Check if there is a fixed rate between the two given currencies
488 IF (( from_type IN ('EMU', 'EURO')) AND
489 ( to_type IN ('EMU', 'EURO'))) THEN
490 return 'Y';
491
492 ELSE
493 /* Fixed conversion relationships enhancements start */
494
495 OPEN is_there_fix_rate (x_from_currency,
496 x_to_currency,
497 x_effective_date);
498 FETCH is_there_fix_rate INTO l_fix_rate;
499
500 IF (is_there_fix_rate%FOUND) THEN
501
502 return 'Y';
503 /* Fixed conversion relationships enhancements end */
504 ELSE
505 return 'N';
506 END IF;
507 END IF;
508
509 END is_fixed_rate;
510
511
512 --
513 -- Procedure
514 -- get_relation
515 --
516 -- Purpose
517 -- Returns the relationship between the two currencies given.
518 -- Also check if there is a fixed rate between the two currencies
519 -- on the effective date.
520 --
521 -- History
522 -- 15-JUL-97 W Wong Created
523 --
524 -- 14-MAR-2005 Srini Pala Added Fixed conversion rate relationship
525 -- logic.
526 -- More detailed explanation is in the
527 -- get_fixed_conv_rate() routine.
528 -- Arguments
529 -- x_from_currency From currency
530 -- x_to_currency To currency
531 -- x_effective_date Effective date
532 -- x_fixed_rate TRUE if there is a fixed rate between the
533 -- currencies on the effective date;
534 -- FALSE otherwise
535 -- x_relationship Relationship between the two currencies
536 --
537 PROCEDURE get_relation(
538 x_from_currency VARCHAR2,
539 x_to_currency VARCHAR2,
540 x_effective_date DATE,
541 x_fixed_rate IN OUT NOCOPY BOOLEAN,
542 x_relationship IN OUT NOCOPY VARCHAR2 ) IS
543
544 to_type VARCHAR2(8);
545 from_type VARCHAR2(8);
546 rate NUMBER; -- Value ignored in this function
547 mau NUMBER; -- Value ignored in this function
548
549 /* Fixed conversion relationships enhancements start */
550
551 CURSOR is_there_fix_relation(l_from_curr VARCHAR2,
552 l_to_curr VARCHAR2,
553 l_eff_date DATE) IS
554 SELECT 'EXIST'
555 FROM GL_FIXED_CONV_RATES
556 WHERE old_currency IN (l_from_curr,l_to_curr)
557 AND ((old_currency = l_from_curr
558 AND replacement_currency = l_to_curr)
559 OR (replacement_currency = l_from_curr
560 AND old_currency = l_to_curr))
561 AND effective_start_date <= trunc(l_eff_date)
562 AND ROWNUM =1;
563 l_fix_relationship VARCHAR2(10);
564
565 /* Fixed conversion relationships enhancements End */
566
567 BEGIN
568 -- Get currency information from the x_from_currency
569 get_info ( x_from_currency, x_effective_date, rate, mau, from_type );
570
571 -- Get currency information from the x_to_currency
572 get_info ( x_to_currency, x_effective_date, rate, mau, to_type );
573
574 -- Check if there is a fixed rate between the two given currencies
575 IF ( x_from_currency = x_to_currency ) THEN
576 x_fixed_rate := TRUE;
577
578 ELSE
579 IF (( from_type IN ('EMU', 'EURO')) AND
580 ( to_type IN ('EMU', 'EURO'))) THEN
581 x_fixed_rate := TRUE;
582
583 ELSE
584 /* Fixed conversion relationships enhancements start */
585
586 OPEN is_there_fix_relation(x_from_currency,
587 x_to_currency,
588 x_effective_date);
589 FETCH is_there_fix_relation INTO l_fix_relationship;
590
591 IF (is_there_fix_relation%FOUND) THEN
592 x_fixed_rate := TRUE;
593 /* Fixed conversion relationships enhancements end */
594
595 ELSE
596 x_fixed_rate := FALSE;
597 END IF;
598 END IF;
599 END IF;
600
601
602 -- Get the relationship between the currencies
603 x_relationship := from_type || '-' || to_type;
604
605 END get_relation;
606
607
608 --
609 -- FUNCTION
610 -- get_euro_code
611 --
612 -- Purpose
613 -- Returns the currency code for the EURO currency. We need to
614 -- select this currency code from fnd_currencies table because
615 -- the currency code for EURO has not been fixed at this time.
616 --
620 -- Arguments
617 -- History
618 -- 24-JUL-97 W Wong Created
619 --
621 -- None.
622 --
623 FUNCTION get_euro_code RETURN VARCHAR2 IS
624 euro_code VARCHAR2(15);
625
626 BEGIN
627 -- Get currency code of the EURO currency
628 SELECT currency_code
629 INTO euro_code
630 FROM FND_CURRENCIES
631 WHERE derive_type = 'EURO';
632
633 return( euro_code );
634
635 EXCEPTION
636 WHEN NO_DATA_FOUND THEN
637 raise INVALID_CURRENCY;
638
639 END get_euro_code;
640
641 --
642 -- Function
643 -- get_rate
644 --
645 -- Purpose
646 -- Returns the rate between the two currencies for a given conversion
647 -- date and conversion type.
648 --
649 -- History
650 -- 15-JUL-97 W Wong Created
651 --
652 -- Arguments
653 -- x_from_currency From currency
654 -- x_to_currency To currency
655 -- x_conversion_date Conversion date
656 -- x_conversion_type Conversion type
657 --
658 FUNCTION get_rate (
659 x_from_currency VARCHAR2,
660 x_to_currency VARCHAR2,
661 x_conversion_date DATE,
662 x_conversion_type VARCHAR2 DEFAULT NULL) RETURN NUMBER IS
663
664 euro_code VARCHAR2(15);
665 to_type VARCHAR2(8);
666 from_type VARCHAR2(8);
667 to_rate NUMBER;
668 from_rate NUMBER;
669 other_rate NUMBER;
670 mau NUMBER; -- Value ignored in this function
671
672 BEGIN
673 -- Check if both currencies are identical
674 IF ( x_from_currency = x_to_currency ) THEN
675 return( 1 );
676 END IF;
677
678 -- Get currency information from the x_from_currency
679 get_info ( x_from_currency, x_conversion_date, from_rate, mau,
680 from_type );
681
682 -- Get currency information from the x_to_currency
683 get_info ( x_to_currency, x_conversion_date, to_rate, mau, to_type );
684
685 -- Calculate the conversion rate according to both currency types
686 IF ( from_type = 'EMU' ) THEN
687 IF ( to_type = 'EMU' ) THEN
688 return( to_rate / from_rate );
689
690 ELSIF ( to_type = 'EURO' ) THEN
691 return( 1 / from_rate );
692
693 ELSIF ( to_type = 'OTHER' ) THEN
694 -- Find out conversion rate from EURO to x_to_currency
695 euro_code := get_euro_code;
696 other_rate := get_other_rate( euro_code, x_to_currency,
697 x_conversion_date,
698 x_conversion_type );
699
700 -- Get conversion rate by converting EMU -> EURO -> OTHER
701 return( other_rate / from_rate );
702 END IF;
703
704 ELSIF ( from_type = 'EURO' ) THEN
705 IF ( to_type = 'EMU' ) THEN
706 return( to_rate );
707
708 ELSIF ( to_type = 'EURO' ) THEN
709 -- We should never comes to this case as it should be
710 -- caught when we check if both to and from currency
711 -- is the same at the beginning of this function
712 return( 1 );
713
714 ELSIF ( to_type = 'OTHER' ) THEN
715 other_rate := get_other_rate( x_from_currency, x_to_currency,
716 x_conversion_date,
717 x_conversion_type );
718 return( other_rate );
719 END IF;
720
721 ELSIF ( from_type = 'OTHER' ) THEN
722 IF ( to_type = 'EMU' ) THEN
723 -- Find out conversion rate from x_from_currency to EURO
724 euro_code := get_euro_code;
725 other_rate := get_other_rate( x_from_currency, euro_code,
726 x_conversion_date,
727 x_conversion_type );
728
729 -- Get conversion rate by converting OTHER -> EURO -> EMU
730 return( other_rate * to_rate );
731
732 ELSIF ( to_type = 'EURO' ) THEN
733 other_rate := get_other_rate( x_from_currency, x_to_currency,
734 x_conversion_date,
735 x_conversion_type );
736 return( other_rate );
737
738 ELSIF ( to_type = 'OTHER' ) THEN
739 other_rate := get_other_rate( x_from_currency, x_to_currency,
740 x_conversion_date,
741 x_conversion_type );
742 return( other_rate );
743 END IF;
744 END IF;
745
746 END get_rate;
747
748
749 --
750 -- Function
751 -- get_rate
752 --
753 -- Purpose
754 -- Returns the rate between the from currency and the functional
755 -- currency of the ledgers.
756 --
757 -- History
758 -- 15-JUL-97 W Wong Created
759 --
760 -- Arguments
761 -- x_set_of_books_id Ledger id
762 -- x_from_currency From currency
763 -- x_conversion_date Conversion date
764 -- x_conversion_type Conversion type
765 --
766 FUNCTION get_rate (
767 x_set_of_books_id NUMBER,
768 x_from_currency VARCHAR2,
769 x_conversion_date DATE,
770 x_conversion_type VARCHAR2 DEFAULT NULL) RETURN NUMBER IS
771
772 to_currency VARCHAR2(15);
773 rate NUMBER;
774
775 BEGIN
776 -- Get to_currency from GL_LEDGERS, i.e. the functional currency
777 SELECT currency_code
781
778 INTO to_currency
779 FROM GL_LEDGERS
780 WHERE ledger_id = x_set_of_books_id;
782 -- Call get_rate() with the to_currency we get from the ledger
783 rate := get_rate( x_from_currency, to_currency, x_conversion_date,
784 x_conversion_type );
785
786 return( rate );
787
788 END get_rate;
789
790 --
791 -- Function
792 -- get_rate_sql
793 --
794 -- Purpose
795 -- Returns the rate between the two currencies for a given conversion
796 -- date and conversion type by calling get_rate().
797 --
798 -- Return -1 if the NO_RATE exception is raised in get_rate().
799 -- -2 if the INVALID_CURRENCY exception is raised in get_rate().
800 --
801 -- History
802 -- 04-DEC-97 W Wong Created
803 --
804 -- Arguments
805 -- x_from_currency From currency
806 -- x_to_currency To currency
807 -- x_conversion_date Conversion date
808 -- x_conversion_type Conversion type
809 --
810 FUNCTION get_rate_sql (
811 x_from_currency VARCHAR2,
812 x_to_currency VARCHAR2,
813 x_conversion_date DATE,
814 x_conversion_type VARCHAR2 DEFAULT NULL) RETURN NUMBER IS
815
816 rate NUMBER;
817 BEGIN
818 -- Call get_rate() using the given parameters
819 rate := get_rate( x_from_currency, x_to_currency, x_conversion_date,
820 x_conversion_type );
821 return( rate );
822
823 EXCEPTION
824 WHEN NO_RATE THEN
825 rate := -1;
826 return( rate );
827
828 WHEN INVALID_CURRENCY THEN
829 rate := -2;
830 return( rate );
831
832 END get_rate_sql;
833
834
835 --
836 -- Function
837 -- get_rate_sql
838 --
839 -- Purpose
840 -- Returns the rate between the from currency and the functional
841 -- currency of the ledgers by calling get_rate().
842 --
843 -- Return -1 if the NO_RATE exception is raised in get_rate().
844 -- -2 if the INVALID_CURRENCY exception is raised in get_rate().
845 --
846 -- History
847 -- 04-DEC-97 W Wong Created
848 --
849 -- Arguments
850 -- x_set_of_books_id Ledger id
851 -- x_from_currency From currency
852 -- x_conversion_date Conversion date
853 -- x_conversion_type Conversion type
854 --
855 FUNCTION get_rate_sql (
856 x_set_of_books_id NUMBER,
857 x_from_currency VARCHAR2,
858 x_conversion_date DATE,
859 x_conversion_type VARCHAR2 DEFAULT NULL) RETURN NUMBER IS
860
861 rate NUMBER;
862 BEGIN
863
864 -- Call get_rate() using the given parameters
865 rate := get_rate( x_set_of_books_id, x_from_currency, x_conversion_date,
866 x_conversion_type );
867 return( rate );
868
869 EXCEPTION
870 WHEN NO_RATE THEN
871 rate := -1;
872 return( rate );
873
874 WHEN INVALID_CURRENCY THEN
875 rate := -2;
876 return( rate );
877
878 END get_rate_sql;
879
880 --
881 -- Function
882 -- get_closest_rate
883 --
884 -- Purpose
885 -- Returns the rate between the two currencies for a given conversion
886 -- date and conversion type.
887 --
888 -- If such a rate is not defined for the specified conversion_date, it
889 -- searches backward for a rate defined for the same currencies and
890 -- conversion type. It searches backward up to x_max_roll_days prior
891 -- to the specified x_conversion_date.
892 --
893 -- History
894 -- 04-DEC-97 W Wong Created
895 --
896 -- Arguments
897 -- x_from_currency From currency
898 -- x_to_currency To currency
899 -- x_conversion_date Conversion date
900 -- x_conversion_type Conversion type
901 -- x_max_roll_days Number of days to rollback for a rate
902 --
903 FUNCTION get_closest_rate (
904 x_from_currency VARCHAR2,
905 x_to_currency VARCHAR2,
906 x_conversion_date DATE,
907 x_conversion_type VARCHAR2 DEFAULT NULL,
908 x_max_roll_days NUMBER ) RETURN NUMBER IS
909
910 euro_code VARCHAR2(15);
911 to_type VARCHAR2(8);
912 from_type VARCHAR2(8);
913 to_rate NUMBER;
914 from_rate NUMBER;
915 other_rate NUMBER;
916 mau NUMBER; -- Value ignored in this function
917
918 BEGIN
919 -- Check if both currencies are identical
920 IF ( x_from_currency = x_to_currency ) THEN
921 return( 1 );
922 END IF;
923
924 -- Get currency information from the x_from_currency
925 get_info ( x_from_currency, x_conversion_date, from_rate, mau,
926 from_type );
927
928 -- Get currency information from the x_to_currency
929 get_info ( x_to_currency, x_conversion_date, to_rate, mau, to_type );
930
931 -- Calculate the conversion rate according to both currency types
932 IF ( from_type = 'EMU' ) THEN
933 IF ( to_type = 'EMU' ) THEN
934 return( to_rate / from_rate );
935
936 ELSIF ( to_type = 'EURO' ) THEN
937 return( 1 / from_rate );
941 euro_code := get_euro_code;
938
939 ELSIF ( to_type = 'OTHER' ) THEN
940 -- Find out conversion rate from EURO to x_to_currency
942 other_rate := get_other_closest_rate( euro_code,
943 x_to_currency,
944 x_conversion_date,
945 x_conversion_type,
946 x_max_roll_days );
947
948 -- Get conversion rate by converting EMU -> EURO -> OTHER
949 return( other_rate / from_rate );
950 END IF;
951
952 ELSIF ( from_type = 'EURO' ) THEN
953 IF ( to_type = 'EMU' ) THEN
954 return( to_rate );
955
956 ELSIF ( to_type = 'EURO' ) THEN
957 -- We should never comes to this case as it should be
958 -- caught when we check if both to and from currency
959 -- is the same at the beginning of this function
960 return( 1 );
961
962 ELSIF ( to_type = 'OTHER' ) THEN
963 other_rate := get_other_closest_rate( x_from_currency,
964 x_to_currency,
965 x_conversion_date,
966 x_conversion_type,
967 x_max_roll_days );
968 return( other_rate );
969 END IF;
970
971 ELSIF ( from_type = 'OTHER' ) THEN
972 IF ( to_type = 'EMU' ) THEN
973 -- Find out conversion rate from x_from_currency to EURO
974 euro_code := get_euro_code;
975 other_rate := get_other_closest_rate( x_from_currency,
976 euro_code,
977 x_conversion_date,
978 x_conversion_type,
979 x_max_roll_days );
980
981 -- Get conversion rate by converting OTHER -> EURO -> EMU
982 return( other_rate * to_rate );
983
984 ELSIF ( to_type = 'EURO' ) THEN
985 other_rate := get_other_closest_rate( x_from_currency,
986 x_to_currency,
987 x_conversion_date,
988 x_conversion_type,
989 x_max_roll_days );
990 return( other_rate );
991
992 ELSIF ( to_type = 'OTHER' ) THEN
993 other_rate := get_other_closest_rate( x_from_currency,
994 x_to_currency,
995 x_conversion_date,
996 x_conversion_type,
997 x_max_roll_days );
998 return( other_rate );
999 END IF;
1000 END IF;
1001
1002 END get_closest_rate;
1003
1004
1005 -- Function
1006 -- get_closest_rate
1007 --
1008 -- Purpose
1009 -- Returns the rate between the from currency and the functional currency
1010 -- of the ledgers, for a given conversion date and conversion type.
1011 --
1012 -- If such a rate is not defined for the specified conversion_date, it
1013 -- searches backward for a rate defined for the same currencies and
1014 -- conversion type. It searches backward up to x_max_roll_days prior
1015 -- to the specified x_conversion_date.
1016 --
1017 -- History
1018 -- 04-DEC-97 W Wong Created
1019 --
1020 -- Arguments
1021 -- x_set_of_books_id Ledger ID
1022 -- x_from__currency From currency
1023 -- x_conversion_date Conversion date
1024 -- x_conversion_type Conversion type
1025 -- x_max_roll_days Number of days to rollback for a rate
1026 --
1027 FUNCTION get_closest_rate (
1028 x_set_of_books_id NUMBER,
1029 x_from_currency VARCHAR2,
1030 x_conversion_date DATE,
1031 x_conversion_type VARCHAR2 DEFAULT NULL,
1032 x_max_roll_days NUMBER ) RETURN NUMBER IS
1033 to_currency VARCHAR2(15);
1034 rate NUMBER;
1035
1036 BEGIN
1037 -- Get to_currency from GL_LEDGERS, i.e. the functional currency
1038 SELECT currency_code
1039 INTO to_currency
1040 FROM GL_LEDGERS
1041 WHERE ledger_id = x_set_of_books_id;
1042
1043 -- Call get_closest_rate() with the to_currency we get from the Ledgers
1044 rate := get_closest_rate( x_from_currency,
1045 to_currency,
1046 x_conversion_date,
1047 x_conversion_type,
1048 x_max_roll_days );
1049
1050 return( rate );
1051
1052 END get_closest_rate;
1053
1054
1055 --
1056 -- Function
1057 -- get_closest_rate_sql
1058 --
1059 -- Purpose
1060 -- Returns the rate between the two currencies for a given conversion
1061 -- date and conversion type by calling get_closest_rate().
1062 --
1063 -- If such a rate is not defined for the specified conversion_date, it
1064 -- searches backward for a rate defined for the same currencies and
1065 -- conversion type. It searches backward up to x_max_roll_days prior
1066 -- to the specified x_conversion_date.
1067 --
1068 -- Return -1 if the NO_RATE exception is raised in get_closest_rate().
1069 -- -2 if the INVALID_CURRENCY exception is raised in
1070 -- get_closest_rate().
1071 --
1072 -- History
1073 -- 04-DEC-97 W Wong Created
1074 --
1075 -- Arguments
1076 -- x_from_currency From currency
1077 -- x_to_currency To currency
1078 -- x_conversion_date Conversion date
1079 -- x_conversion_type Conversion type
1083 x_from_currency VARCHAR2,
1080 -- x_max_roll_days Number of days to rollback for a rate
1081 --
1082 FUNCTION get_closest_rate_sql (
1084 x_to_currency VARCHAR2,
1085 x_conversion_date DATE,
1086 x_conversion_type VARCHAR2 DEFAULT NULL,
1087 x_max_roll_days NUMBER ) RETURN NUMBER IS
1088
1089 rate NUMBER;
1090 BEGIN
1091 rate := get_closest_rate( x_from_currency, x_to_currency,
1092 x_conversion_date, x_conversion_type,
1093 x_max_roll_days );
1094 return( rate );
1095
1096 EXCEPTION
1097 WHEN NO_RATE THEN
1098 rate := -1;
1099 return( rate );
1100
1101 WHEN INVALID_CURRENCY THEN
1102 rate := -2;
1103 return( rate );
1104
1105 END get_closest_rate_sql;
1106
1107
1108 --
1109 -- Function
1110 -- get_closest_rate_sql
1111 --
1112 -- Purpose
1113 -- Returns the rate between the from currency and the functional currency
1114 -- of the ledgers, for a given conversion date and conversion type
1115 -- by calling get_closest_rate().
1116 --
1117 -- If such a rate is not defined for the specified conversion_date, it
1118 -- searches backward for a rate defined for the same currencies and
1119 -- conversion type. It searches backward up to x_max_roll_days prior
1120 -- to the specified x_conversion_date.
1121 --
1122 -- Return -1 if the NO_RATE exception is raised in get_closest_rate().
1123 -- -2 if the INVALID_CURRENCY exception is raised in
1124 -- get_closest_rate().
1125 --
1126 -- History
1127 -- 04-DEC-97 W Wong Created
1128 --
1129 -- Arguments
1130 -- x_set_of_books_id Ledger id
1131 -- x_from_currency From currency
1132 -- x_conversion_date Conversion date
1133 -- x_conversion_type Conversion type
1134 -- x_max_roll_days Number of days to rollback for a rate
1135 --
1136 FUNCTION get_closest_rate_sql (
1137 x_set_of_books_id NUMBER,
1138 x_from_currency VARCHAR2,
1139 x_conversion_date DATE,
1140 x_conversion_type VARCHAR2 DEFAULT NULL,
1141 x_max_roll_days NUMBER ) RETURN NUMBER IS
1142
1143 rate NUMBER;
1144 BEGIN
1145 rate := get_closest_rate( x_set_of_books_id, x_from_currency,
1146 x_conversion_date, x_conversion_type,
1147 x_max_roll_days );
1148 return( rate );
1149
1150 EXCEPTION
1151 WHEN NO_RATE THEN
1152 rate := -1;
1153 return( rate );
1154
1155 WHEN INVALID_CURRENCY THEN
1156 rate := -2;
1157 return( rate );
1158
1159 END get_closest_rate_sql;
1160
1161
1162 --
1163 -- Function
1164 -- convert_amount
1165 --
1166 -- Purpose
1167 -- Returns the amount converted from the from currency into the
1168 -- to currency for a given conversion date and conversion type.
1169 -- The amount returned is rounded to the precision and minimum
1170 -- account unit of the to currency.
1171 --
1172 -- History
1173 -- 15-JUL-97 W Wong Created
1174 --
1175 -- Arguments
1176 -- x_from_currency From currency
1177 -- x_to_currency To currency
1178 -- x_conversion_date Conversion date
1179 -- x_conversion_type Conversion type
1180 -- x_amount Amount to be converted from the from currency
1181 -- into the to currency
1182 --
1183 FUNCTION convert_amount (
1184 x_from_currency VARCHAR2,
1185 x_to_currency VARCHAR2,
1186 x_conversion_date DATE,
1187 x_conversion_type VARCHAR2 DEFAULT NULL,
1188 x_amount NUMBER ) RETURN NUMBER IS
1189
1190 euro_code VARCHAR2(15);
1191 to_type VARCHAR2(8);
1192 from_type VARCHAR2(8);
1193 to_rate NUMBER;
1194 from_rate NUMBER;
1195 other_rate NUMBER;
1196 from_mau NUMBER;
1197 to_mau NUMBER;
1198 converted_amount NUMBER;
1199
1200 BEGIN
1201 -- Check if both currencies are identical
1202 IF ( x_from_currency = x_to_currency ) THEN
1203 return( x_amount );
1204 END IF;
1205
1206 -- Get currency information from the from_currency
1207 get_info ( x_from_currency, x_conversion_date, from_rate, from_mau,
1208 from_type );
1209
1210 -- Get currency information from the to_currency
1211 get_info ( x_to_currency, x_conversion_date, to_rate, to_mau, to_type );
1212
1213 -- Calculate the conversion rate according to both currency types
1214 IF ( from_type = 'EMU' ) THEN
1215 IF ( to_type = 'EMU' ) THEN
1216 converted_amount := ( x_amount / from_rate ) * to_rate;
1217
1218 ELSIF ( to_type = 'EURO' ) THEN
1219 converted_amount := x_amount / from_rate;
1220
1221 ELSIF ( to_type = 'OTHER' ) THEN
1222 -- Find out conversion rate from EURO to x_to_currency
1223 euro_code := get_euro_code;
1224 other_rate := get_other_rate( euro_code, x_to_currency,
1225 x_conversion_date,
1226 x_conversion_type );
1227
1228 -- Get conversion amt by converting EMU -> EURO -> OTHER
1229 converted_amount := ( x_amount / from_rate ) * other_rate;
1230 END IF;
1234 converted_amount := x_amount * to_rate;
1231
1232 ELSIF ( from_type = 'EURO' ) THEN
1233 IF ( to_type = 'EMU' ) THEN
1235
1236 ELSIF ( to_type = 'EURO' ) THEN
1237 -- We should never comes to this case as it should be
1238 -- caught when we check if both to and from currency
1239 -- is the same at the beginning of this function
1240 converted_amount := x_amount;
1241
1242 ELSIF ( to_type = 'OTHER' ) THEN
1243 other_rate := get_other_rate( x_from_currency, x_to_currency,
1244 x_conversion_date,
1245 x_conversion_type );
1246 converted_amount := x_amount * other_rate;
1247 END IF;
1248
1249 ELSIF ( from_type = 'OTHER' ) THEN
1250 IF ( to_type = 'EMU' ) THEN
1251 -- Find out conversion rate from x_from_currency to EURO
1252 euro_code := get_euro_code;
1253 other_rate := get_other_rate( x_from_currency, euro_code,
1254 x_conversion_date,
1255 x_conversion_type );
1256
1257 -- Get conversion amt by converting OTHER -> EURO -> EMU
1258 converted_amount := ( x_amount * other_rate ) * to_rate;
1259
1260 ELSIF ( to_type = 'EURO' ) THEN
1261 other_rate := get_other_rate( x_from_currency, x_to_currency,
1262 x_conversion_date,
1263 x_conversion_type );
1264 converted_amount := x_amount * other_rate;
1265
1266 ELSIF ( to_type = 'OTHER' ) THEN
1267 other_rate := get_other_rate( x_from_currency, x_to_currency,
1268 x_conversion_date,
1269 x_conversion_type );
1270 converted_amount := x_amount * other_rate;
1271 END IF;
1272 END IF;
1273
1274 -- Rounding to the correct precision and minumum accountable units
1275 return( round( converted_amount / to_mau ) * to_mau );
1276
1277 END convert_amount;
1278
1279 --
1280 -- Function
1281 -- convert_amount
1282 --
1283 -- Purpose
1284 -- Returns the amount converted from the from currency into the
1285 -- functional currency of that ledgers. The amount returned is
1286 -- rounded to the precision and minimum account unit of the to currency.
1287 --
1288 -- History
1289 -- 15-JUL-97 W Wong Created
1290 --
1291 -- Arguments
1292 -- x_set_of_books_id Ledger id
1293 -- x_from_currency From currency
1294 -- x_conversion_date Conversion date
1295 -- x_conversion_type Conversion type
1296 -- x_amount Amount to be converted from the from currency
1297 -- into the functional currency of the ledgers
1298 --
1299 --
1300 FUNCTION convert_amount (
1301 x_set_of_books_id NUMBER,
1302 x_from_currency VARCHAR2,
1303 x_conversion_date DATE,
1304 x_conversion_type VARCHAR2 DEFAULT NULL,
1305 x_amount NUMBER ) RETURN NUMBER IS
1306 to_currency VARCHAR2(15);
1307 converted_amount NUMBER;
1308
1309 BEGIN
1310 -- Get to_currency from GL_LEDGERS, i.e. the functional currency
1311 SELECT currency_code
1312 INTO to_currency
1313 FROM GL_LEDGERS
1314 WHERE ledger_id = x_set_of_books_id;
1315
1316 -- Call convert_amount() with the to_currency we get from the Ledger
1317 converted_amount := convert_amount( x_from_currency, to_currency,
1318 x_conversion_date, x_conversion_type,
1319 x_amount );
1320
1321 return( converted_amount );
1322
1323 END convert_amount;
1324
1325
1326 --
1327 -- Function
1328 -- convert_amount_sql
1329 --
1330 -- Purpose
1331 -- Returns the amount converted from the from currency into the
1332 -- to currency for a given conversion date and conversion type by
1333 -- calling convert_amount().
1334 -- The amount returned is rounded to the precision and minimum
1335 -- account unit of the to currency.
1336 --
1337 -- Return -1 if the NO_RATE exception is raised in get_rate().
1338 -- -2 if the INVALID_CURRENCY exception is raised in get_rate().
1339 --
1340 -- History
1341 -- 04-DEC-97 W Wong Created
1342 --
1343 -- Arguments
1344 -- x_from_currency From currency
1345 -- x_to_currency To currency
1346 -- x_conversion_date Conversion date
1347 -- x_conversion_type Conversion type
1348 -- x_amount Amount to be converted from the from currency
1349 -- into the to currency
1350 --
1351 FUNCTION convert_amount_sql (
1352 x_from_currency VARCHAR2,
1353 x_to_currency VARCHAR2,
1354 x_conversion_date DATE,
1355 x_conversion_type VARCHAR2 DEFAULT NULL,
1356 x_amount NUMBER ) RETURN NUMBER IS
1357
1358 converted_amount NUMBER;
1359 BEGIN
1360 converted_amount := convert_amount( x_from_currency, x_to_currency,
1361 x_conversion_date, x_conversion_type,
1362 x_amount );
1363 return( converted_amount );
1364
1365 EXCEPTION
1366 WHEN NO_RATE THEN
1367 converted_amount := -1;
1368 return( converted_amount );
1369
1370 WHEN INVALID_CURRENCY THEN
1371 converted_amount := -2;
1372 return( converted_amount );
1373
1374 END convert_amount_sql;
1375
1376 --
1377 -- Function
1378 -- convert_amount_sql
1379 --
1383 -- The amount returned is rounded to the precision and minimum account
1380 -- Purpose
1381 -- Returns the amount converted from the from currency into the
1382 -- functional currency of that ledgers by calling convert_amount().
1384 -- unit of the to currency.
1385 --
1386 -- Return -1 if the NO_RATE exception is raised in get_rate().
1387 -- -2 if the INVALID_CURRENCY exception is raised in get_rate().
1388 --
1389 -- History
1390 -- 04-DEC-97 W Wong Created
1391 --
1392 -- Arguments
1393 -- x_set_of_books_id Ledger id
1394 -- x_from_currency From currency
1395 -- x_conversion_date Conversion date
1396 -- x_conversion_type Conversion type
1397 -- x_amount Amount to be converted from the from currency
1398 -- into the functional currency of the ledgers
1399 --
1400 --
1401 FUNCTION convert_amount_sql (
1402 x_set_of_books_id NUMBER,
1403 x_from_currency VARCHAR2,
1404 x_conversion_date DATE,
1405 x_conversion_type VARCHAR2 DEFAULT NULL,
1406 x_amount NUMBER ) RETURN NUMBER IS
1407
1408 converted_amount NUMBER;
1409 BEGIN
1410 converted_amount := convert_amount( x_set_of_books_id, x_from_currency,
1411 x_conversion_date, x_conversion_type,
1412 x_amount );
1413 return( converted_amount );
1414
1415 EXCEPTION
1416 WHEN NO_RATE THEN
1417 converted_amount := -1;
1418 return( converted_amount );
1419
1420 WHEN INVALID_CURRENCY THEN
1421 converted_amount := -2;
1422 return( converted_amount );
1423
1424 END convert_amount_sql;
1425
1426 --
1427 -- Function
1428 -- get_derive_type
1429 -- Purpose
1430 -- Gets derive type for a currency.
1431 --
1432 -- NOTE: This function is for GL ONLY!
1433 -- It'll returns GL specific derive type.
1434 --
1435 -- History
1436 -- 08/07/97 K Chen Created
1437 -- Arguments
1438 -- ledger_id NUMBER
1439 -- period VARCHAR2
1440 -- curr_code VARCHAR2
1441 -- Example
1442 -- :Parameter.derive_type := glxrvsub_pkg.get_derive_type
1443 -- (:Parameter.access_set_id, :OPTIONS.period_name,
1444 -- :Parameter.func_curr_code);
1445 -- Notes
1446 --
1447 FUNCTION get_derive_type (ledger_id NUMBER, period VARCHAR2, curr_code VARCHAR2)
1448 RETURN VARCHAR2 IS
1449 derive_type VARCHAR2(8);
1450 derive_effective DATE;
1451 BEGIN
1452
1453 SELECT derive_type, derive_effective
1454 INTO derive_type, derive_effective
1455 FROM fnd_currencies
1456 WHERE currency_code = curr_code;
1457
1458 IF (derive_type IS NULL or
1459 derive_type = 'OTHER') THEN
1460 RETURN 'OTHER';
1461 END IF;
1462
1463 IF (derive_type = 'EURO') THEN
1464 RETURN 'EURO';
1465 END IF;
1466
1467 IF (derive_effective IS NOT NULL) THEN
1468 SELECT DECODE(SIGN(trunc(derive_effective) -
1469 trunc(GPS.end_date)), 1,
1470 'OTHER',
1471 DECODE (SIGN(trunc(GPS.start_date) -
1472 trunc(derive_effective)), 1,
1473 'EMU',
1474 'INTER'))
1475 INTO derive_type
1476 FROM gl_period_statuses GPS
1477 WHERE GPS.application_id = 101
1478 AND GPS.ledger_id = ledger_id
1479 AND GPS.period_name = period;
1480
1481 RETURN derive_type;
1482 ELSE
1483 RETURN 'ERROR';
1484 END IF;
1485
1486 EXCEPTION
1487 WHEN NO_DATA_FOUND THEN
1488 raise NO_DERIVE_TYPE;
1489 END get_derive_type;
1490
1491 --
1492 -- Function
1493 -- rate_exists
1494 --
1495 -- Purpose
1496 -- Returns 'Y' if there is a conversion rate between the two currencies
1497 -- for a given conversion date and conversion type;
1498 -- 'N' otherwise.
1499 --
1500 -- History
1501 -- 03-SEP-97 W Wong Created
1502 --
1503 -- Arguments
1504 -- x_from_currency From currency
1505 -- x_to_currency To currency
1506 -- x_conversion_date Conversion date
1507 -- x_conversion_type Conversion type
1508 --
1509 FUNCTION rate_exists (
1510 x_from_currency VARCHAR2,
1511 x_to_currency VARCHAR2,
1512 x_conversion_date DATE,
1513 x_conversion_type VARCHAR2 DEFAULT NULL)
1514 RETURN VARCHAR2 IS
1515 rate NUMBER;
1516 BEGIN
1517 rate := get_rate( x_from_currency, x_to_currency,
1518 x_conversion_date, x_conversion_type );
1519
1520 -- Conversion rates exists between these two currencies for the given
1521 -- conversion rate and conversion date.
1522 return( 'Y' );
1523
1524 EXCEPTION
1525 WHEN NO_RATE THEN
1526 -- Conversion rates does not exist between these two currencies for the
1527 -- given conversion rate and conversion date.
1528 return( 'N' );
1529
1530 END rate_exists;
1531
1532 --
1533 -- Function
1534 -- get_rate_numerator_sql
1535 --
1536 -- Purpose
1537 -- Returns the numerator we should use to calculate the conversion
1538 -- rate between the two currencies for a given conversion date and
1539 -- conversion type.
1540 --
1544 -- History
1541 -- Return -1 if the NO_RATE exception is raised.
1542 -- -2 if the INVALID_CURRENCY exception is raised.
1543 --
1545 -- 11-MAY-98 W Wong Created
1546 --
1547 -- Arguments
1548 -- x_from_currency From currency
1549 -- x_to_currency To currency
1550 -- x_conversion_date Conversion date
1551 -- x_conversion_type Conversion type
1552 --
1553 FUNCTION get_rate_numerator_sql (
1554 x_from_currency VARCHAR2,
1555 x_to_currency VARCHAR2,
1556 x_conversion_date DATE,
1557 x_conversion_type VARCHAR2 DEFAULT NULL) RETURN NUMBER IS
1558
1559 euro_code VARCHAR2(15);
1560 to_type VARCHAR2(8);
1561 from_type VARCHAR2(8);
1562 to_rate NUMBER;
1563 from_rate NUMBER;
1564 other_rate NUMBER;
1565 mau NUMBER; -- Value ignored in this function
1566
1567 BEGIN
1568
1569 -- Check if both currencies are identical
1570 IF ( x_from_currency = x_to_currency ) THEN
1571 return( 1 );
1572 END IF;
1573
1574 -- Get currency information from the x_from_currency
1575 get_info ( x_from_currency, x_conversion_date, from_rate, mau,
1576 from_type );
1577
1578 -- Get currency information from the x_to_currency
1579 get_info ( x_to_currency, x_conversion_date, to_rate, mau, to_type );
1580
1581 -- Calculate the conversion rate according to both currency types
1582 IF ( from_type = 'EMU' ) THEN
1583 IF ( to_type = 'EMU' ) THEN
1584 return( to_rate );
1585
1586 ELSIF ( to_type = 'EURO' ) THEN
1587 return( 1 );
1588
1589 ELSIF ( to_type = 'OTHER' ) THEN
1590 -- Find out conversion rate from EURO to x_to_currency
1591 euro_code := get_euro_code;
1592 other_rate := get_other_rate( euro_code, x_to_currency,
1593 x_conversion_date,
1594 x_conversion_type );
1595
1596 -- Get conversion rate by converting EMU -> EURO -> OTHER
1597 return( other_rate );
1598 END IF;
1599
1600 ELSIF ( from_type = 'EURO' ) THEN
1601 IF ( to_type = 'EMU' ) THEN
1602 return( to_rate );
1603
1604 ELSIF ( to_type = 'EURO' ) THEN
1605 -- We should never comes to this case as it should be
1606 -- caught when we check if both to and from currency
1607 -- is the same at the beginning of this function
1608 return( 1 );
1609
1610 ELSIF ( to_type = 'OTHER' ) THEN
1611 other_rate := get_other_rate( x_from_currency, x_to_currency,
1612 x_conversion_date,
1613 x_conversion_type );
1614 return( other_rate );
1615 END IF;
1616
1617 ELSIF ( from_type = 'OTHER' ) THEN
1618 IF ( to_type = 'EMU' ) THEN
1619 -- Find out conversion rate from x_from_currency to EURO
1620 euro_code := get_euro_code;
1621 other_rate := get_other_rate( x_from_currency, euro_code,
1622 x_conversion_date,
1623 x_conversion_type );
1624
1625 -- Get conversion rate by converting OTHER -> EURO -> EMU
1626 return( other_rate * to_rate );
1627
1628 ELSIF ( to_type = 'EURO' ) THEN
1629 other_rate := get_other_rate( x_from_currency, x_to_currency,
1630 x_conversion_date,
1631 x_conversion_type );
1632 return( other_rate );
1633
1634 ELSIF ( to_type = 'OTHER' ) THEN
1635 other_rate := get_other_rate( x_from_currency, x_to_currency,
1636 x_conversion_date,
1637 x_conversion_type );
1638 return( other_rate );
1639 END IF;
1640 END IF;
1641
1642 EXCEPTION
1643 WHEN NO_RATE THEN
1644 return( -1 );
1645
1646 WHEN INVALID_CURRENCY THEN
1647 return( -2 );
1648
1649 END get_rate_numerator_sql;
1650
1651 --
1652 -- Function
1653 -- get_rate_numerator_sql
1654 --
1655 -- Purpose
1656 -- Returns the numerator we should use to calculate the conversion rate
1657 -- between the from currency and the functional currency of the
1658 -- ledgers.
1659 --
1660 -- History
1661 -- 11-MAY-98 W Wong Created
1662 --
1663 -- Arguments
1664 -- x_set_of_books_id Ledger_id
1665 -- x_from_currency From currency
1666 -- x_conversion_date Conversion date
1667 -- x_conversion_type Conversion type
1668 --
1669 FUNCTION get_rate_numerator_sql (
1670 x_set_of_books_id NUMBER,
1671 x_from_currency VARCHAR2,
1672 x_conversion_date DATE,
1673 x_conversion_type VARCHAR2 DEFAULT NULL) RETURN NUMBER IS
1674
1675 to_currency VARCHAR2(15);
1676 numerator NUMBER;
1677
1678 BEGIN
1679 -- Get to_currency from GL_LEDGERS, i.e. the functional currency
1680 SELECT currency_code
1681 INTO to_currency
1682 FROM GL_LEDGERS
1683 WHERE ledger_id = x_set_of_books_id;
1684
1685 -- Call get_rate_numerator_sql() with the to_currency we get from the Ledger
1686 numerator := get_rate_numerator_sql( x_from_currency,
1687 to_currency,
1688 x_conversion_date,
1689 x_conversion_type );
1690 return( numerator );
1691
1692 END get_rate_numerator_sql;
1693
1694 --
1695 -- Function
1699 -- Returns the denominator we should use to calculate the conversion
1696 -- get_rate_denominator_sql
1697 --
1698 -- Purpose
1700 -- rate between the two currencies for a given conversion date and
1701 -- conversion type.
1702 --
1703 -- Return -1 if the NO_RATE exception is raised.
1704 -- -2 if the INVALID_CURRENCY exception is raised.
1705 --
1706 -- History
1707 -- 11-MAY-98 W Wong Created
1708 --
1709 -- Arguments
1710 -- x_from_currency From currency
1711 -- x_to_currency To currency
1712 -- x_conversion_date Conversion date
1713 -- x_conversion_type Conversion type
1714 --
1715 FUNCTION get_rate_denominator_sql (
1716 x_from_currency VARCHAR2,
1717 x_to_currency VARCHAR2,
1718 x_conversion_date DATE,
1719 x_conversion_type VARCHAR2 DEFAULT NULL )
1720 RETURN NUMBER IS
1721
1722 euro_code VARCHAR2(15);
1723 to_type VARCHAR2(8);
1724 from_type VARCHAR2(8);
1725 to_rate NUMBER;
1726 from_rate NUMBER;
1727 other_rate NUMBER;
1728 mau NUMBER; -- Value ignored in this function
1729
1730 BEGIN
1731 -- Check if both currencies are identical
1732 IF ( x_from_currency = x_to_currency ) THEN
1733 return( 1 );
1734 END IF;
1735
1736 -- Get currency information from the x_from_currency
1737 get_info ( x_from_currency, x_conversion_date, from_rate, mau,
1738 from_type );
1739
1740 -- Calculate the conversion rate according to both currency types
1741 IF ( from_type = 'EMU' ) THEN
1742 return( from_rate );
1743
1744 ELSE
1745
1746 return( 1 );
1747 END IF;
1748
1749 EXCEPTION
1750 WHEN NO_RATE THEN
1751 return( -1 );
1752
1753 WHEN INVALID_CURRENCY THEN
1754 return( -2 );
1755
1756 END get_rate_denominator_sql;
1757
1758
1759 --
1760 -- Function
1761 -- get_rate_denominator_sql
1762 --
1763 -- Purpose
1764 -- Returns the denominator we should use to calculate the conversion rate
1765 -- between the from currency and the functional currency of the
1766 -- ledgers.
1767 --
1768 -- History
1769 -- 11-MAY-98 W Wong Created
1770 --
1771 -- Arguments
1772 -- x_set_of_books_id Ledger id
1773 -- x_from_currency From currency
1774 -- x_conversion_date Conversion date
1775 -- x_conversion_type Conversion type
1776 --
1777 FUNCTION get_rate_denominator_sql (
1778 x_set_of_books_id NUMBER,
1779 x_from_currency VARCHAR2,
1780 x_conversion_date DATE,
1781 x_conversion_type VARCHAR2 DEFAULT NULL )
1782 RETURN NUMBER IS
1783
1784 to_currency VARCHAR2(15);
1785 denominator NUMBER;
1786
1787 BEGIN
1788 -- Get to_currency from GL_LEDGERS, i.e. the functional currency
1789 SELECT currency_code
1790 INTO to_currency
1791 FROM GL_LEDGERS
1792 WHERE ledger_id = x_set_of_books_id;
1793
1794 -- Call get_rate_denominator_sql() with the to_currency we get from Ledger
1795 denominator := get_rate_denominator_sql( x_from_currency,
1796 to_currency,
1797 x_conversion_date,
1798 x_conversion_type );
1799 return( denominator );
1800 END get_rate_denominator_sql;
1801
1802 --
1803 -- Procedure
1804 -- get_triangulation_rate
1805 --
1806 -- Purpose
1807 -- Returns the numerator and denominator we should use to calculate
1808 -- the conversion rate between the two currencies, and the actual
1809 -- conversion rate for a given conversion date and conversion type.
1810 --
1811 -- Note: When you are calculating the triangulation rate, you should
1812 -- always divide by the x_denominator before you multiply by
1813 -- the x_numerator.
1814 --
1815 -- History
1816 -- 11-MAY-98 W Wong Created
1817 --
1818 -- Arguments
1819 -- x_from_currency From currency
1820 -- x_to_currency To currency
1821 -- x_conversion_date Conversion date
1822 -- x_conversion_type Conversion type
1823 -- x_denominator Denominator to get conversion rate
1824 -- x_numerator Numerator to get conversion rate
1825 -- x_rate Conversion rate
1826 --
1827 PROCEDURE get_triangulation_rate (
1828 x_from_currency VARCHAR2,
1829 x_to_currency VARCHAR2,
1830 x_conversion_date DATE,
1831 x_conversion_type VARCHAR2 DEFAULT NULL,
1832 x_denominator IN OUT NOCOPY NUMBER,
1833 x_numerator IN OUT NOCOPY NUMBER,
1834 x_rate IN OUT NOCOPY NUMBER ) IS
1835 BEGIN
1836 -- Get value of numerator and denominator
1837 x_numerator := get_rate_numerator_sql( x_from_currency,
1838 x_to_currency,
1839 x_conversion_date,
1840 x_conversion_type );
1841
1842 x_denominator := get_rate_denominator_sql ( x_from_currency,
1843 x_to_currency,
1844 x_conversion_date,
1845 x_conversion_type );
1846
1850
1847 -- Get conversion rate by using the x_numerator and x_denominator
1848 IF (( x_numerator > 0 ) AND ( x_denominator > 0 )) THEN
1849 x_rate := x_numerator / x_denominator;
1851 ELSE
1852 IF (( x_numerator = -2 ) OR (x_denominator = -2 )) THEN
1853 raise INVALID_CURRENCY;
1854
1855 ELSE
1856 raise NO_RATE;
1857 END IF;
1858 END IF;
1859
1860 END get_triangulation_rate;
1861
1862 --
1863 -- Procedure
1864 -- get_triangulation_rate
1865 --
1866 -- Purpose
1867 -- Returns the numerator, denominator and the conversion rate
1868 -- between the from currency and the functional currency of the
1869 -- ledgers.
1870 --
1871 -- Note: When you are calculating the triangulation rate, you should
1872 -- always divide by the x_denominator before you multiply by
1873 -- the x_numerator.
1874 --
1875 -- History
1876 -- 11-MAY-98 W Wong Created
1877 --
1878 -- Arguments
1879 -- x_set_of_books_id Ledger id
1880 -- x_from_currency From currency
1881 -- x_conversion_date Conversion date
1882 -- x_conversion_type Conversion type
1883 -- x_denominator Denominator to get conversion rate
1884 -- x_numerator Numerator to get conversion rate
1885 -- x_rate Conversion rate
1886 --
1887 PROCEDURE get_triangulation_rate (
1888 x_set_of_books_id NUMBER,
1889 x_from_currency VARCHAR2,
1890 x_conversion_date DATE,
1891 x_conversion_type VARCHAR2 DEFAULT NULL,
1892 x_denominator IN OUT NOCOPY NUMBER,
1893 x_numerator IN OUT NOCOPY NUMBER,
1894 x_rate IN OUT NOCOPY NUMBER) IS
1895
1896 to_currency VARCHAR2(15);
1897
1898 BEGIN
1899 -- Get to_currency from GL_LEDGERS, i.e. the functional currency
1900 SELECT currency_code
1901 INTO to_currency
1902 FROM GL_LEDGERS
1903 WHERE ledger_id = x_set_of_books_id;
1904
1905 -- Get value of numerator and denominator
1906 x_numerator := get_rate_numerator_sql( x_from_currency,
1907 to_currency,
1908 x_conversion_date,
1909 x_conversion_type );
1910
1911 x_denominator := get_rate_denominator_sql( x_from_currency,
1912 to_currency,
1913 x_conversion_date,
1914 x_conversion_type );
1915
1916 -- Get conversion rate by using the x_numerator and x_denominator
1917 IF (( x_numerator > 0 ) AND ( x_denominator > 0 )) THEN
1918 x_rate := x_numerator / x_denominator;
1919
1920 ELSE
1921 IF (( x_numerator = -2 ) OR (x_denominator = -2 )) THEN
1922 raise INVALID_CURRENCY;
1923 ELSE
1924 raise NO_RATE;
1925 END IF;
1926 END IF;
1927
1928 END get_triangulation_rate;
1929
1930 --
1931 -- Function
1932 -- get_closest_rate_numerator_sql
1933 --
1934 -- Purpose
1935 -- Returns the numerator we should use between the two currencies for
1936 -- a given conversion date and conversion type.
1937 --
1938 -- Return -1 if the NO_RATE exception is raised.
1939 -- -2 if the INVALID_CURRENCY exception is raised.
1940 --
1941 -- History
1942 -- 11-MAY-98 W Wong Created
1943 --
1944 -- Arguments
1945 -- x_from_currency From currency
1946 -- x_to_currency To currency
1947 -- x_conversion_date Conversion date
1948 -- x_conversion_type Conversion type
1949 -- x_max_roll_days Number of days to rollback for a rate
1950 --
1951 FUNCTION get_closest_rate_numerator_sql (
1952 x_from_currency VARCHAR2,
1953 x_to_currency VARCHAR2,
1954 x_conversion_date DATE,
1955 x_conversion_type VARCHAR2 DEFAULT NULL,
1956 x_max_roll_days NUMBER) RETURN NUMBER IS
1957
1958 euro_code VARCHAR2(15);
1959 to_type VARCHAR2(8);
1960 from_type VARCHAR2(8);
1961 to_rate NUMBER;
1962 from_rate NUMBER;
1963 other_rate NUMBER;
1964 mau NUMBER; -- Value ignored in this function
1965
1966 BEGIN
1967 -- Check if both currencies are identical
1968 IF ( x_from_currency = x_to_currency ) THEN
1969 return( 1 );
1970 END IF;
1971
1972 -- Get currency information from the x_from_currency
1973 get_info ( x_from_currency, x_conversion_date, from_rate, mau,
1974 from_type );
1975
1976 -- Get currency information from the x_to_currency
1977 get_info ( x_to_currency, x_conversion_date, to_rate, mau, to_type );
1978
1979 -- Calculate the conversion rate according to both currency types
1980 IF ( from_type = 'EMU' ) THEN
1981 IF ( to_type = 'EMU' ) THEN
1982 return( to_rate );
1983
1984 ELSIF ( to_type = 'EURO' ) THEN
1985 return( 1 );
1986
1987 ELSIF ( to_type = 'OTHER' ) THEN
1988 -- Find out conversion rate from EURO to x_to_currency
1989 euro_code := get_euro_code;
1990 other_rate := get_other_closest_rate( euro_code,
1991 x_to_currency,
1992 x_conversion_date,
1993 x_conversion_type,
1994 x_max_roll_days );
1998 ELSIF ( from_type = 'EURO' ) THEN
1995 return( other_rate );
1996 END IF;
1997
1999 IF ( to_type = 'EMU' ) THEN
2000 return( to_rate );
2001
2002 ELSIF ( to_type = 'EURO' ) THEN
2003 -- We should never comes to this case as it should be
2004 -- caught when we check if both to and from currency
2005 -- is the same at the beginning of this function
2006 return( 1 );
2007
2008 ELSIF ( to_type = 'OTHER' ) THEN
2009 other_rate := get_other_closest_rate( x_from_currency,
2010 x_to_currency,
2011 x_conversion_date,
2012 x_conversion_type,
2013 x_max_roll_days );
2014 return( other_rate );
2015 END IF;
2016
2017 ELSIF ( from_type = 'OTHER' ) THEN
2018 IF ( to_type = 'EMU' ) THEN
2019 -- Find out conversion rate from x_from_currency to EURO
2020 euro_code := get_euro_code;
2021 other_rate := get_other_closest_rate( x_from_currency,
2022 euro_code,
2023 x_conversion_date,
2024 x_conversion_type,
2025 x_max_roll_days );
2026
2027 -- Get conversion rate by converting OTHER -> EURO -> EMU
2028 return( other_rate * to_rate );
2029
2030 ELSIF ( to_type = 'EURO' ) THEN
2031 other_rate := get_other_closest_rate( x_from_currency,
2032 x_to_currency,
2033 x_conversion_date,
2034 x_conversion_type,
2035 x_max_roll_days );
2036 return( other_rate );
2037
2038 ELSIF ( to_type = 'OTHER' ) THEN
2039 other_rate := get_other_closest_rate( x_from_currency,
2040 x_to_currency,
2041 x_conversion_date,
2042 x_conversion_type,
2043 x_max_roll_days );
2044 return( other_rate );
2045 END IF;
2046 END IF;
2047
2048 EXCEPTION
2049 WHEN NO_RATE THEN
2050 return( -1 );
2051
2052 WHEN INVALID_CURRENCY THEN
2053 return( -2 );
2054
2055 END get_closest_rate_numerator_sql;
2056
2057 --
2058 -- Function
2059 -- get_closest_rate_numerator_sql
2060 --
2061 -- Purpose
2062 -- Returns the numerator we should use to get the conversion rate
2063 -- between the from currency and the functional currency of the
2064 -- ledgers.
2065 --
2066 -- History
2067 -- 11-MAY-98 W Wong Created
2068 --
2069 -- Arguments
2070 -- x_set_of_books_id Ledger id
2071 -- x_from_currency From currency
2072 -- x_conversion_date Conversion date
2073 -- x_conversion_type Conversion type
2074 -- x_max_roll_days Number of days to rollback for a rate
2075 --
2076 FUNCTION get_closest_rate_numerator_sql (
2077 x_set_of_books_id NUMBER,
2078 x_from_currency VARCHAR2,
2079 x_conversion_date DATE,
2080 x_conversion_type VARCHAR2 DEFAULT NULL,
2081 x_max_roll_days NUMBER) RETURN NUMBER IS
2082
2083 to_currency VARCHAR2(15);
2084 numerator NUMBER;
2085
2086 BEGIN
2087 -- Get to_currency from GL_LEDGERS, i.e. the functional currency
2088 SELECT currency_code
2089 INTO to_currency
2090 FROM GL_LEDGERS
2091 WHERE ledger_id = x_set_of_books_id;
2092
2093 -- Call get_closest_rate() with the to_currency we get from the Ledger
2094 numerator := get_closest_rate_numerator_sql( x_from_currency,
2095 to_currency,
2096 x_conversion_date,
2097 x_conversion_type,
2098 x_max_roll_days );
2099 return( numerator );
2100
2101 EXCEPTION
2102 WHEN NO_RATE THEN
2103 return( -1 );
2104
2105 WHEN INVALID_CURRENCY THEN
2106 return( -2 );
2107
2108 END get_closest_rate_numerator_sql;
2109
2110 --
2111 -- Function
2112 -- get_closest_rate_denom_sql
2113 --
2114 -- Purpose
2115 -- Returns the denominator we should use between the two currencies for
2116 -- a given conversion date and conversion type.
2117 --
2118 -- Return -1 if the NO_RATE exception is raised.
2119 -- -2 if the INVALID_CURRENCY exception is raised.
2120 --
2121 -- History
2122 -- 11-MAY-98 W Wong Created
2123 --
2124 -- Arguments
2125 -- x_from_currency From currency
2126 -- x_to_currency To currency
2127 -- x_conversion_date Conversion date
2128 -- x_conversion_type Conversion type
2129 -- x_max_roll_days Number of days to rollback for a rate
2130 --
2131 FUNCTION get_closest_rate_denom_sql (
2132 x_from_currency VARCHAR2,
2133 x_to_currency VARCHAR2,
2134 x_conversion_date DATE,
2135 x_conversion_type VARCHAR2 DEFAULT NULL,
2136 x_max_roll_days NUMBER) RETURN NUMBER IS
2137
2138 euro_code VARCHAR2(15);
2139 to_type VARCHAR2(8);
2140 from_type VARCHAR2(8);
2141 to_rate NUMBER;
2142 from_rate NUMBER;
2143 other_rate NUMBER;
2144 mau NUMBER; -- Value ignored in this function
2145
2146 BEGIN
2150 END IF;
2147 -- Check if both currencies are identical
2148 IF ( x_from_currency = x_to_currency ) THEN
2149 return( 1 );
2151
2152 -- Get currency information from the x_from_currency
2153 get_info ( x_from_currency, x_conversion_date, from_rate, mau,
2154 from_type );
2155
2156 -- Calculate the conversion rate according to both currency types
2157 IF ( from_type = 'EMU' ) THEN
2158 return( from_rate );
2159
2160 ELSE
2161
2162 return( 1 );
2163 END IF;
2164
2165 EXCEPTION
2166 WHEN NO_RATE THEN
2167 return( -1 );
2168
2169 WHEN INVALID_CURRENCY THEN
2170 return( -2 );
2171
2172 END get_closest_rate_denom_sql;
2173
2174 --
2175 -- Function
2176 -- get_closest_rate_denom_sql
2177 --
2178 -- Purpose
2179 -- Returns the denominator we should use to get the conversion rate
2180 -- between the from currency and the functional currency of the
2181 -- ledgers.
2182 --
2183 -- History
2184 -- 11-MAY-98 W Wong Created
2185 --
2186 -- Arguments
2187 -- x_set_of_books_id ledger id
2188 -- x_from_currency From currency
2189 -- x_conversion_date Conversion date
2190 -- x_conversion_type Conversion type
2191 -- x_max_roll_days Number of days to rollback for a rate
2192 --
2193 FUNCTION get_closest_rate_denom_sql (
2194 x_set_of_books_id NUMBER,
2195 x_from_currency VARCHAR2,
2196 x_conversion_date DATE,
2197 x_conversion_type VARCHAR2 DEFAULT NULL,
2198 x_max_roll_days NUMBER) RETURN NUMBER IS
2199
2200 to_currency VARCHAR2(15);
2201 denominator NUMBER;
2202
2203 BEGIN
2204 -- Get to_currency from GL_LEDGERS, i.e. the functional currency
2205 SELECT currency_code
2206 INTO to_currency
2207 FROM GL_LEDGERS
2208 WHERE ledger_id = x_set_of_books_id;
2209
2210 -- Call get_closest_rate_denom_sql() with the to_currency
2211 -- we get from the Ledger
2212 denominator := get_closest_rate_denom_sql( x_from_currency,
2213 to_currency,
2214 x_conversion_date,
2215 x_conversion_type,
2216 x_max_roll_days );
2217
2218 return( denominator );
2219
2220 END get_closest_rate_denom_sql;
2221
2222 --
2223 -- Procedure
2224 -- get_closest_triangulation_rate
2225 --
2226 -- Purpose
2227 -- Returns the numerator, denominator and the conversion rate between
2228 -- the two currencies for a given conversion date and conversion type.
2229 --
2230 -- History
2231 -- 11-MAY-98 W Wong Created
2232 --
2233 -- Arguments
2234 -- x_from_currency From currency
2235 -- x_to_currency To currency
2236 -- x_conversion_date Conversion date
2237 -- x_conversion_type Conversion type
2238 -- x_max_roll_days Number of days to rollback for a rate
2239 -- x_denominator Denominator to get conversion rate
2240 -- x_numerator Numerator to get conversion rate
2241 -- x_rate Conversion rate
2242 --
2243 PROCEDURE get_closest_triangulation_rate (
2244 x_from_currency VARCHAR2,
2245 x_to_currency VARCHAR2,
2246 x_conversion_date DATE,
2247 x_conversion_type VARCHAR2 DEFAULT NULL,
2248 x_max_roll_days NUMBER,
2249 x_denominator IN OUT NOCOPY NUMBER,
2250 x_numerator IN OUT NOCOPY NUMBER,
2251 x_rate IN OUT NOCOPY NUMBER ) IS
2252 BEGIN
2253 -- Get value of numerator and denominator
2254 x_numerator := get_closest_rate_numerator_sql( x_from_currency,
2255 x_to_currency,
2256 x_conversion_date,
2257 x_conversion_type,
2258 x_max_roll_days );
2259
2260 x_denominator := get_closest_rate_denom_sql ( x_from_currency,
2261 x_to_currency,
2262 x_conversion_date,
2263 x_conversion_type,
2264 x_max_roll_days );
2265
2266 -- Get conversion rate by using the x_numerator and x_denominator
2267 IF (( x_numerator > 0 ) AND ( x_denominator > 0 )) THEN
2268 x_rate := x_numerator / x_denominator;
2269
2270 ELSE
2271 IF (( x_numerator = -2 ) OR (x_denominator = -2 )) THEN
2272 raise INVALID_CURRENCY;
2273 ELSE
2274 raise NO_RATE;
2275 END IF;
2276 END IF;
2277 END get_closest_triangulation_rate;
2278
2279 --
2280 -- Procedure
2281 -- get_closest_triangulation_rate
2282 --
2283 -- Purpose
2284 -- Returns the numerator, denominator and the conversion rate
2285 -- between the from currency and the functional currency of the
2286 -- ledgers.
2287 --
2288 -- History
2289 -- 11-MAY-98 W Wong Created
2290 --
2291 -- Arguments
2292 -- x_set_of_books_id Ledger id
2293 -- x_from_currency From currency
2294 -- x_conversion_date Conversion date
2295 -- x_conversion_type Conversion type
2296 -- x_max_roll_days Number of days to rollback for a rate
2297 -- x_denominator Denominator to get conversion rate
2301 PROCEDURE get_closest_triangulation_rate (
2298 -- x_numerator Numerator to get conversion rate
2299 -- x_rate Conversion rate
2300 --
2302 x_set_of_books_id NUMBER,
2303 x_from_currency VARCHAR2,
2304 x_conversion_date DATE,
2305 x_conversion_type VARCHAR2 DEFAULT NULL,
2306 x_max_roll_days NUMBER,
2307 x_denominator IN OUT NOCOPY NUMBER,
2308 x_numerator IN OUT NOCOPY NUMBER,
2309 x_rate IN OUT NOCOPY NUMBER) IS
2310
2311 to_currency VARCHAR2(15);
2312
2313 BEGIN
2314 -- Get to_currency from GL_LEDGERS, i.e. the functional currency
2315 SELECT currency_code
2316 INTO to_currency
2317 FROM GL_LEDGERS
2318 WHERE ledger_id = x_set_of_books_id;
2319
2320 -- Get value of numerator and denominator
2321 x_numerator := get_closest_rate_numerator_sql( x_from_currency,
2322 to_currency,
2323 x_conversion_date,
2324 x_conversion_type,
2325 x_max_roll_days );
2326
2327 x_denominator := get_closest_rate_denom_sql( x_from_currency,
2328 to_currency,
2329 x_conversion_date,
2330 x_conversion_type,
2331 x_max_roll_days );
2332
2333 -- Get conversion rate by using the x_numerator and x_denominator
2334 IF (( x_numerator > 0 ) AND ( x_denominator > 0 )) THEN
2335 x_rate := x_numerator / x_denominator;
2336
2337 ELSE
2338 IF (( x_numerator = -2 ) OR (x_denominator = -2 )) THEN
2339 raise INVALID_CURRENCY;
2340 ELSE
2341 raise NO_RATE;
2342 END IF;
2343 END IF;
2344
2345 END get_closest_triangulation_rate;
2346
2347
2348 --
2349 -- Procedure
2350 -- convert_amount
2351 --
2352 -- Purpose
2353 -- Returns the numerator and denominator we should use to calculate
2354 -- the conversion rate between the two currencies, the actual
2355 -- conversion rate for a given conversion date and conversion type,
2356 -- and the amount converted from the from currency into the
2357 -- to currency for a given conversion date and conversion type.
2358 --
2359 -- History
2360 -- 02-JUN-98 W Wong Created
2361 --
2362 -- Arguments
2363 -- x_from_currency From currency
2364 -- x_to_currency To currency
2365 -- x_conversion_date Conversion date
2366 -- x_conversion_type Conversion type
2367 -- x_amount Amount to be converted from the from currency
2371 -- x_rate Conversion rate
2368 -- into the to currency
2369 -- x_denominator Denominator to get conversion rate
2370 -- x_numerator Numerator to get conversion rate
2372 -- x_converted_amount Converted amount
2373 --
2374 PROCEDURE convert_amount(
2375 x_from_currency VARCHAR2,
2376 x_to_currency VARCHAR2,
2377 x_conversion_date DATE,
2378 x_conversion_type VARCHAR2 DEFAULT NULL,
2379 x_amount NUMBER,
2380 x_converted_amount IN OUT NOCOPY NUMBER,
2381 x_denominator IN OUT NOCOPY NUMBER,
2382 x_numerator IN OUT NOCOPY NUMBER,
2383 x_rate IN OUT NOCOPY NUMBER ) IS
2384
2385 to_rate NUMBER;
2386 to_mau NUMBER;
2387 to_type VARCHAR2(8);
2388
2389 BEGIN
2390 -- Get currency information from the to_currency ( for use in rounding )
2391 get_info ( x_to_currency, x_conversion_date, to_rate, to_mau, to_type );
2392
2393 -- Get the conversion information
2394 get_triangulation_rate( x_from_currency,
2395 x_to_currency,
2396 x_conversion_date,
2397 x_conversion_type,
2398 x_denominator,
2399 x_numerator,
2400 x_rate );
2401
2402 -- Calculate the converted amount using triangulation method
2403 x_converted_amount := ( x_amount / x_denominator ) * x_numerator;
2404
2405 -- Rounding to the correct precision and minumum accountable units
2406 x_converted_amount := round( x_converted_amount / to_mau ) * to_mau;
2407
2408 END convert_amount;
2409
2410
2411 --
2412 -- Procedure
2413 -- convert_amount
2414 --
2415 -- Purpose
2416 -- Returns the numerator and denominator we should use to calculate
2417 -- the conversion rate, and the actual conversion rate between the
2418 -- from currency and the functional currency of the ledgers,
2419 -- and the amount converted from the from currency into the
2420 -- functional currency of that ledgers.
2421 --
2422 -- History
2423 -- 02-JUN-98 W Wong Created
2424 --
2425 -- Arguments
2426 -- x_set_of_books_id Ledger id
2427 -- x_from_currency From currency
2428 -- x_conversion_date Conversion date
2429 -- x_conversion_type Conversion type
2430 -- x_amount Amount to be converted from the from currency
2431 -- into the to currency
2432 -- x_denominator Denominator to get conversion rate
2433 -- x_numerator Numerator to get conversion rate
2434 -- x_rate Conversion rate
2435 -- x_converted_amount Converted amount
2436 --
2437 PROCEDURE convert_amount(
2438 x_set_of_books_id NUMBER,
2439 x_from_currency VARCHAR2,
2440 x_conversion_date DATE,
2441 x_conversion_type VARCHAR2 DEFAULT NULL,
2442 x_amount NUMBER,
2443 x_converted_amount IN OUT NOCOPY NUMBER,
2444 x_denominator IN OUT NOCOPY NUMBER,
2445 x_numerator IN OUT NOCOPY NUMBER,
2446 x_rate IN OUT NOCOPY NUMBER ) IS
2447
2448 to_currency VARCHAR2(15);
2449 to_rate NUMBER;
2450 to_mau NUMBER;
2451 to_type VARCHAR2(8);
2452
2453 BEGIN
2454 -- Get to_currency from GL_LEDGERS, i.e. the functional currency
2455 SELECT currency_code
2456 INTO to_currency
2457 FROM GL_LEDGERS
2458 WHERE ledger_id = x_set_of_books_id;
2459
2460 -- Get currency information from the to_currency ( for use in rounding )
2461 get_info ( to_currency, x_conversion_date, to_rate, to_mau, to_type );
2462
2463 -- Get the conversion information
2464 get_triangulation_rate( x_from_currency,
2465 to_currency,
2466 x_conversion_date,
2467 x_conversion_type,
2468 x_denominator,
2469 x_numerator,
2470 x_rate );
2471
2472 -- Calculate the converted amount using triangulation method
2473 x_converted_amount := ( x_amount / x_denominator ) * x_numerator;
2474
2475 -- Rounding to the correct precision and minumum accountable units
2476 x_converted_amount := round( x_converted_amount / to_mau ) * to_mau;
2477
2478 END convert_amount;
2479
2480
2481 --
2482 -- Function
2483 -- convert_closest_amount_sql
2484 --
2485 -- Purpose
2486 -- Returns the amount converted from the from currency into the
2487 -- to currency for a given conversion date and conversion type.
2488 -- The amount returned is rounded to the precision and minimum
2489 -- account unit of the to currency.
2490 --
2491 -- If x_conversion_type = 'User', and the relationship between the
2492 -- two currencies is not fixed, x_user_rate will be used as the
2493 -- conversion rate to convert the amount.
2494 --
2495 -- If there is a fixed relationship between the two currencies,
2496 -- the fixed rate will be used instead of the x_user_rate.
2497 --
2498 -- If x_convserion_type is not 'User', the routine will try to
2499 -- find the conversion rate using the given x_conversion_date and
2500 -- x_conversion_type.
2501 --
2502 -- If such a rate is not defined for the specified conversion_date, it
2503 -- searches backward for a rate defined for the same currencies and
2504 -- conversion type. It searches backward up to x_max_roll_days prior
2505 -- to the specified x_conversion_date.
2506 --
2507 -- Return -1 if the NO_RATE exception is raised.
2508 -- -2 if the INVALID_CURRENCY exception is raised.
2509 --
2510 -- History
2511 -- 10-SEP-98 W Wong Created
2512 --
2513 -- Arguments
2514 -- x_from_currency From currency
2515 -- x_to_currency To currency
2516 -- x_conversion_date Conversion date
2520 -- into the to currency
2517 -- x_conversion_type Conversion type
2518 -- x_user_rate User conversion rate
2519 -- x_amount Amount to be converted from the from currency
2521 -- x_max_roll_days Number of days to rollback for a rate
2522 --
2523 FUNCTION convert_closest_amount_sql (
2524 x_from_currency VARCHAR2,
2525 x_to_currency VARCHAR2,
2526 x_conversion_date DATE,
2527 x_conversion_type VARCHAR2 DEFAULT NULL,
2528 x_user_rate NUMBER,
2529 x_amount NUMBER,
2530 x_max_roll_days NUMBER ) RETURN NUMBER IS
2531
2532 to_rate NUMBER;
2533 to_mau NUMBER;
2534 to_type VARCHAR2(8);
2535 denominator NUMBER;
2536 numerator NUMBER;
2537 converted_amount NUMBER;
2538
2539 BEGIN
2540
2541 -- Check if both currencies are identical
2542 IF ( x_from_currency = x_to_currency ) THEN
2543 converted_amount := x_amount;
2544 return( converted_amount );
2545 END IF;
2546
2547 -- Get currency information from the to_currency ( for use in rounding )
2548 get_info ( x_to_currency, x_conversion_date, to_rate, to_mau, to_type );
2549
2550 --
2551 -- Find out the conversion rate that should be used.
2552 --
2553 IF ( x_conversion_type = 'User' ) THEN
2554 IF ( is_fixed_rate( x_from_currency, x_to_currency,
2555 x_conversion_date ) = 'N' ) THEN
2556 --
2557 -- Conversion type is 'User' and the relationship between both
2558 -- currencies is not a fixed relationship. The given user rate
2559 -- is used for the conversion.
2560 --
2561 denominator := 1;
2562 numerator := x_user_rate;
2563
2564 -- Calculate the converted amount using triangulation method
2565 converted_amount := ( x_amount / denominator ) * numerator;
2566
2567 -- Rounding to the correct precision and minumum accountable units
2568 converted_amount := round( converted_amount / to_mau ) * to_mau;
2569 return( converted_amount );
2570
2571 END IF;
2572 END IF;
2573
2574 --
2575 -- Conversion type is not 'User', or
2576 -- there is a fixed relationship between the currencies.
2577 -- Find out the conversion rate using the given conversion type
2578 -- and conversion date.
2579 --
2580 denominator := get_closest_rate_denom_sql( x_from_currency,
2581 x_to_currency,
2582 x_conversion_date,
2583 x_conversion_type,
2584 x_max_roll_days );
2585
2586 numerator := get_closest_rate_numerator_sql( x_from_currency,
2587 x_to_currency,
2588 x_conversion_date,
2589 x_conversion_type,
2590 x_max_roll_days );
2591
2592 IF (( numerator > 0 ) AND ( denominator > 0 )) THEN
2593 --
2594 -- We have a conversion rate to convert the amount
2595 --
2596
2597 -- Calculate the converted amount using triangulation method
2598 converted_amount := ( x_amount / denominator ) * numerator;
2599
2600 -- Rounding to the correct precision and minumum accountable units
2601 converted_amount := round( converted_amount / to_mau ) * to_mau;
2602 return( converted_amount );
2603
2604 ELSE
2605 IF (( numerator = -2 ) OR ( denominator = -2 )) THEN
2606 -- Either the x_from_currency or x_to_currency is invalid
2607 converted_amount := -2;
2608 return( converted_amount );
2609
2610 ELSE
2611 -- No conversion rate was found between the two currencies with
2612 -- the given conversion type and conversion date
2613 converted_amount := -1;
2614 return( converted_amount );
2615 END IF;
2616 END IF;
2617
2618 EXCEPTION
2619 WHEN INVALID_CURRENCY THEN
2620 converted_amount := -2;
2621 return( converted_amount );
2622
2623 END convert_closest_amount_sql;
2624
2625
2626 --
2627 -- Procedure
2628 -- convert_closest_amount
2629 --
2630 -- Purpose
2631 -- Returns the rate denominator, rate numerator and conversion rate
2632 -- the routine has used to convert the given amount. Also returns
2633 -- the converted amount.
2634 --
2635 -- If x_conversion_type = 'User', and the relationship between the
2636 -- two currencies is not fixed, x_user_rate will be used as the
2637 -- conversion rate to convert the amount.
2638 --
2639 -- If there is a fixed relationship between the two currencies,
2640 -- the fixed rate will be used instead of the x_user_rate.
2641 --
2642 -- If x_convserion_type is not 'User', the routine will try to
2643 -- find the conversion rate using the given x_conversion_date and
2644 -- x_conversion_type.
2645 --
2646 -- If such a rate is not defined for the specified conversion_date, it
2647 -- searches backward for a rate defined for the same currencies and
2648 -- conversion type. It searches backward up to x_max_roll_days prior
2649 -- to the specified x_conversion_date.
2650 --
2651 -- History
2652 -- 10-SEP-98 W Wong Created
2653 --
2654 -- Arguments
2655 -- x_from_currency From currency
2656 -- x_to_currency To currency
2657 -- x_conversion_date Conversion date
2658 -- x_conversion_type Conversion type
2659 -- x_user_rate User conversion rate
2660 -- x_amount Amount to be converted from the from currency
2661 -- into the to currency
2662 -- x_max_roll_days Number of days to rollback for a rate
2663 -- x_converted_amount Converted amount
2664 -- x_denominator Denominator to get conversion rate
2665 -- x_numerator Numerator to get conversion rate
2666 -- x_rate Conversion rate
2667 --
2668 PROCEDURE convert_closest_amount(
2669 x_from_currency VARCHAR2,
2670 x_to_currency VARCHAR2,
2671 x_conversion_date DATE,
2672 x_conversion_type VARCHAR2 DEFAULT NULL,
2673 x_user_rate NUMBER,
2674 x_amount NUMBER,
2675 x_max_roll_days NUMBER,
2676 x_converted_amount IN OUT NOCOPY NUMBER,
2677 x_denominator IN OUT NOCOPY NUMBER,
2678 x_numerator IN OUT NOCOPY NUMBER,
2679 x_rate IN OUT NOCOPY NUMBER ) IS
2680 to_rate NUMBER;
2681 to_mau NUMBER;
2682 to_type VARCHAR2(8);
2683 denominator NUMBER;
2684 numerator NUMBER;
2685 rate NUMBER;
2686 converted_amount NUMBER;
2687
2688 BEGIN
2689
2690 -- Check if both currencies are identical
2691 IF ( x_from_currency = x_to_currency ) THEN
2692 x_converted_amount := x_amount;
2693 x_denominator := 1;
2694 x_numerator := 1;
2695 x_rate := 1;
2696 return;
2697 END IF;
2698
2699 -- Get currency information from the to_currency ( for use in rounding )
2700 get_info ( x_to_currency, x_conversion_date, to_rate, to_mau, to_type );
2701
2702 --
2703 -- Find out the conversion rate that should be used.
2704 --
2705 IF ( x_conversion_type = 'User' ) THEN
2706 IF ( is_fixed_rate( x_from_currency, x_to_currency,
2707 x_conversion_date ) = 'N' ) THEN
2708 --
2709 -- Conversion type is 'USER' and the relationship between both
2710 -- currencies is not a fixed relationship. The given user rate
2711 -- is used for the conversion.
2712 --
2713 x_denominator := 1;
2714 x_numerator := x_user_rate;
2715 x_rate := x_user_rate;
2716
2717 -- Calculate the converted amount using triangulation method
2718 x_converted_amount := ( x_amount / x_denominator ) * x_numerator;
2719
2720 -- Rounding to the correct precision and minumum accountable units
2721 x_converted_amount := round( x_converted_amount / to_mau ) * to_mau;
2722 return;
2723
2724 END IF;
2725 END IF;
2726
2727 --
2728 -- Conversion type is not 'User', or
2729 -- there is a fixed relationship between the currencies.
2730 -- Find out the conversion rate using the given conversion type
2731 -- and conversion date.
2732 --
2733 get_closest_triangulation_rate( x_from_currency,
2734 x_to_currency,
2735 x_conversion_date,
2736 x_conversion_type,
2737 x_max_roll_days,
2738 denominator,
2739 numerator,
2740 rate );
2741
2742 -- Assign conversion info to output variables
2743 x_denominator := denominator;
2744 x_numerator := numerator;
2745 x_rate := rate;
2746
2747 -- Calculate the converted amount using triangulation method
2748 x_converted_amount := ( x_amount / x_denominator ) * x_numerator;
2749
2750 -- Rounding to the correct precision and minumum accountable units
2751 x_converted_amount := round( x_converted_amount / to_mau ) * to_mau;
2752
2753 END convert_closest_amount;
2754
2755 END gl_currency_api;
2756