6
6
7
7
class Money
8
8
def exchange_to ( to_currency , date = nil )
9
- other_currency = Currency . wrap ( to_currency )
10
9
bank = Bank ::TcmbCurrency . new
11
- bank . exchange_with ( self , to_currency , date )
10
+ bank . exchange_with! ( self , to_currency , date )
12
11
end
13
12
14
13
module Bank
15
14
class TcmbCurrency < Money ::Bank ::VariableExchange
16
-
17
15
class CrossRate < ActiveRecord ::Base
18
-
19
16
end
20
17
21
18
class CurrencyType < ActiveRecord ::Base
22
-
23
19
end
24
20
25
21
attr_reader :rates
26
22
27
- def flush_rates
28
- @mutex . synchronize {
29
- @rates = { }
30
- }
31
- end
32
-
33
-
34
- def flush_rate ( from , to )
35
- key = rate_key_for ( from , to )
36
- @mutex . synchronize {
37
- @rates . delete ( key )
38
- }
39
- end
40
-
41
- def exchange_with ( *args )
42
- from , to_currency , date = args [ 0 ] , args [ 1 ] , args [ 2 ]
23
+ def exchange_with! ( *args )
24
+ from = args [ 0 ]
25
+ to_currency = args [ 1 ]
26
+ date = args [ 2 ]
43
27
return from if same_currency? ( from . currency , to_currency )
44
- rate = get_rate ( from . currency , to_currency , date )
28
+ rate = fetch_rate! ( from . currency , to_currency , date )
45
29
unless rate
46
- raise UnknownRate , "No conversion rate known for '#{ from . currency . iso_code } ' -> '#{ to_currency } '"
30
+ raise UnknownRate , "No conversion rate known for
31
+ '#{ from . currency . iso_code } ' -> '#{ to_currency } '"
47
32
end
48
- _to_currency_ = Currency . wrap ( to_currency )
49
- fractional = BigDecimal . new ( from . fractional . to_s ) / ( BigDecimal . new ( from . currency . subunit_to_unit . to_s ) / BigDecimal . new ( _to_currency_ . subunit_to_unit . to_s ) )
33
+ wrap_to_currency_ = Currency . wrap ( to_currency )
34
+ fractional = get_fractional ( from , wrap_to_currency_ )
50
35
ex = ( fractional * BigDecimal . new ( rate . to_s ) ) . to_f
51
36
ex = if block_given?
52
37
yield ex
@@ -55,31 +40,37 @@ def exchange_with(*args)
55
40
else
56
41
ex . to_s . to_i
57
42
end
58
- Money . new ( ex , _to_currency_ )
59
- end
60
-
61
- def get_rate ( from , to , date )
62
- @mutex . synchronize {
63
- @rates [ rate_key_for ( from , to ) ] ||= fetch_rate ( from , to , date )
64
- }
43
+ Money . new ( ex , wrap_to_currency_ )
65
44
end
66
45
67
46
private
68
47
69
- def fetch_rate ( from , to , date )
70
- from , to = Currency . wrap ( from ) , Currency . wrap ( to )
48
+ def get_fractional ( from , to_currency )
49
+ bd_from_fractional = BigDecimal . new ( from . fractional . to_s )
50
+ bd_from_currency = BigDecimal . new ( from . currency . subunit_to_unit . to_s )
51
+ bd_to_currency = BigDecimal . new ( to_currency . subunit_to_unit . to_s )
52
+ bd_from_fractional / ( bd_from_currency / bd_to_currency )
53
+ end
54
+
55
+ def fetch_rate! ( from , to , date )
56
+ from_to_s = Money ::Currency . wrap ( from ) . to_s
57
+ to_to_s = Money ::Currency . wrap ( to ) . to_s
58
+ from_rate = 1.0
59
+ to_rate = 1.0
60
+ froms = Money ::Bank ::TcmbCurrency ::CrossRate . where ( code : from_to_s )
61
+ tos = Money ::Bank ::TcmbCurrency ::CrossRate . where ( code : to_to_s )
71
62
if date . nil?
72
- f = CrossRate . where ( code : from . to_s ) . last
73
- t = CrossRate . where ( code : to . to_s ) . last
63
+ from_rate = froms . last . rate . to_f unless from_to_s == 'USD'
64
+ to_rate = tos . last . rate . to_f unless to_to_s == 'USD'
74
65
else
75
- f = CrossRate . where ( code : from . to_s , date : date ) . last
76
- t = CrossRate . where ( code : to . to_s , date : date ) . last
66
+ unless Money ::Bank ::TcmbCurrency ::CrossRate . where ( date : date ) . present?
67
+ raise 'There is no record in that date.'
68
+ end
69
+ from_rate = froms . where ( date : date ) . last . rate . to_f unless from_to_s == 'USD'
70
+ to_rate = tos . where ( date : date ) . last . rate . to_f unless to_to_s == 'USD'
77
71
end
78
-
79
- return rate = t . rate . to_f /f . rate . to_f
72
+ to_rate / from_rate
80
73
end
81
-
82
74
end
83
75
end
84
76
end
85
-
0 commit comments