mgd_money 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/lib/mgd_money.rb +178 -0
- metadata +45 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA1:
|
|
3
|
+
metadata.gz: c4c10d10675064445a34fb24ab6efeb6e30146b9
|
|
4
|
+
data.tar.gz: aa2d1e3d3cd53bd2c690b06656e2c8cb44c837fe
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 18b054083240cbf6538d0d52f4ddf4ad6192646807ef6b15fbccd55334c5cace2bd64df1c2d0678c070e04722a444f6a1b5bf13e743d7ce64916f234363cd1a6
|
|
7
|
+
data.tar.gz: d961cc6071bf268f2ba391b28d6d9169fc440ea898e4004ad5059fac6f08e413524fc4a4e5a7f2b3e9d1fd6d59d9fabbf13963ea39dc32b3a52ba05369c97fb6
|
data/lib/mgd_money.rb
ADDED
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
class MGDMoney
|
|
2
|
+
include Comparable # for implementing custom comparing methods for MGDMoney objects
|
|
3
|
+
|
|
4
|
+
# initialize the instance variables for the singleton class.
|
|
5
|
+
# this allows the user to configure the desired conversion rates
|
|
6
|
+
# with respect to a base currency
|
|
7
|
+
class << self
|
|
8
|
+
attr_accessor :base_currency, :conversion_factors
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
attr_reader :amount, :currency # each MGDMoney object will have these attributes
|
|
12
|
+
|
|
13
|
+
# instantiate new MGDMoney objects.
|
|
14
|
+
# @param [Numeric] amount, the amount of the given currency
|
|
15
|
+
# @param [String] currency, the user-defined currency string
|
|
16
|
+
# @return [MGDMoney] the resulting MGDMoney object
|
|
17
|
+
# @example fifty_eur = MGDMoney.new(50, 'EUR') #=> 50 EUR
|
|
18
|
+
def initialize(amount, currency)
|
|
19
|
+
unless amount.is_a?(Numeric) # the amount entered wasn't empty, but we still have to make sure it's a number
|
|
20
|
+
raise UnknownObjectError, 'Amount must be a number'
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
if currency.empty?
|
|
24
|
+
raise InvalidDeclarationError, 'Currency must be specified'
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
@amount = amount # input is OK, so set the attributes
|
|
28
|
+
@currency = currency
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# configure the currency rates on the singleton class with respect to a base currency
|
|
32
|
+
# @param [String] base_currency, the currency used to determine conversion rates
|
|
33
|
+
# @param [Hash] conversion_factors, the conversion rates for supported currencies
|
|
34
|
+
# @return [nil]
|
|
35
|
+
# @example
|
|
36
|
+
# MGDMoney.conversion_rates("EUR", {
|
|
37
|
+
# "USD" => 1.11,
|
|
38
|
+
# "Bitcoin" => 0.0047
|
|
39
|
+
# })
|
|
40
|
+
def self.conversion_rates(base_currency, conversion_factors)
|
|
41
|
+
self.base_currency = base_currency
|
|
42
|
+
self.conversion_factors = conversion_factors
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# convert to a different currency, returning a new MGDMoney object.
|
|
46
|
+
# requires both source and destination currency to be defined by
|
|
47
|
+
# MGDMoney.conversion_rates (otherwise rate not known)
|
|
48
|
+
# @param [String] currency, the desired currency after conversion
|
|
49
|
+
# @return [MGDMoney] the new MGDMoney object representing the converted currency
|
|
50
|
+
# @example fifty_eur.convert_to('USD') # => 55.50 USD
|
|
51
|
+
def convert_to(currency)
|
|
52
|
+
if currency == self.currency # source and destination currencies match
|
|
53
|
+
self # no conversion needed
|
|
54
|
+
else
|
|
55
|
+
factors = MGDMoney.conversion_factors # get the user-specified conversion rates
|
|
56
|
+
|
|
57
|
+
if self.currency == MGDMoney.base_currency # user specified this currency as the base currency
|
|
58
|
+
if factors.keys.include?(currency) # ensures user did actually specify this conversion
|
|
59
|
+
conversion_factor = factors["#{currency}"] # look up the conversion rate from the Hash
|
|
60
|
+
MGDMoney.new(self.amount*conversion_factor, currency) # return the converted value as a new MGDMoney object
|
|
61
|
+
else # conversion rate wasn't specified, so raise an error
|
|
62
|
+
raise UnknownConversionError, 'Conversion rate not specified for this currency'
|
|
63
|
+
end
|
|
64
|
+
elsif currency == MGDMoney.base_currency # user specified desired currency as the base currency
|
|
65
|
+
if factors.keys.include?(self.currency) # look for the source currency in the user-specified Hash
|
|
66
|
+
conversion_factor = 1 / factors["#{self.currency}"] # if found, invert that b/c the Hash is specified in opposite way
|
|
67
|
+
MGDMoney.new(self.amount*conversion_factor, currency) # return the converted value as a new MGDMoney object
|
|
68
|
+
else # conversion rate wasn't specified, so raise an error
|
|
69
|
+
raise UnknownConversionError, 'Conversion rate not specified for this currency'
|
|
70
|
+
end
|
|
71
|
+
else
|
|
72
|
+
if factors.keys.include?(currency) # neither source nor desired currency are the base currency
|
|
73
|
+
conversion_factor = factors["#{self.currency}"] * factors["#{currency}"] # compare them to each other
|
|
74
|
+
MGDMoney.new(self.amount*conversion_factor, currency) # return the converted value as a new MGDMoney object
|
|
75
|
+
else # conversion rate wasn't specified, so raise an error
|
|
76
|
+
raise UnknownConversionError, 'Conversion rate not specified for this currency'
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
# get amount and currency of MGDMoney object
|
|
83
|
+
# @example
|
|
84
|
+
# fifty_eur.amount => 50
|
|
85
|
+
# fifty_eur.currency => 'EUR'
|
|
86
|
+
# fifty_eur.inspect => "50.00 EUR"
|
|
87
|
+
def amount
|
|
88
|
+
@amount
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def currency
|
|
92
|
+
@currency
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
# format the default output string format
|
|
96
|
+
def inspect
|
|
97
|
+
"#{(convert_to_float(@amount)).to_s + " " + currency}"
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
# convert the given number to its float representation.
|
|
101
|
+
# this makes all the arithmetic possible
|
|
102
|
+
# @param [Numeric] amount, the amount to convert
|
|
103
|
+
# @return [BigDecimal]
|
|
104
|
+
# @example convert_to_float(twenty_dollars.amount)
|
|
105
|
+
def convert_to_float(amount)
|
|
106
|
+
if amount.to_s.empty? # entered amount was "" (empty string), return 0
|
|
107
|
+
0
|
|
108
|
+
else
|
|
109
|
+
'%.2f' % amount
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
# perform arithmetic operations in two different currencies
|
|
114
|
+
# @param [MGDMoney] other_object, the MGDMoney object we're doing the operation with
|
|
115
|
+
# @return [MGDMoney]
|
|
116
|
+
# @example fifty_eur + twenty_dollars = 68.02 EUR
|
|
117
|
+
# @example fifty_eur / 2 = 25 EUR
|
|
118
|
+
def +(other_object)
|
|
119
|
+
if other_object.is_a?(MGDMoney)
|
|
120
|
+
other_object = other_object.convert_to(currency)
|
|
121
|
+
self.class.new(amount + other_object.amount, currency)
|
|
122
|
+
else
|
|
123
|
+
raise UnsupportedOperationError, '#{other_object} must be of type MGDMoney to compute a sum'
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
def -(other_object)
|
|
128
|
+
if other_object.is_a?(MGDMoney)
|
|
129
|
+
other_object = other_object.convert_to(currency)
|
|
130
|
+
self.class.new(amount - other_object.amount, currency)
|
|
131
|
+
else
|
|
132
|
+
raise UnsupportedOperationError, '#{other_object} must be of type MGDMoney to compute a difference'
|
|
133
|
+
end
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
def *(val)
|
|
137
|
+
if val.is_a?(Numeric)
|
|
138
|
+
self.class.new(amount * val, currency)
|
|
139
|
+
else
|
|
140
|
+
raise UnsupportedOperationError, 'Can only multiply an MGDMoney object by a number'
|
|
141
|
+
end
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
def /(val)
|
|
145
|
+
if val.is_a?(Numeric)
|
|
146
|
+
self.class.new(amount / val, currency)
|
|
147
|
+
else
|
|
148
|
+
raise UnsupportedOperationError, 'Can only divide an MGDMoney object by a number'
|
|
149
|
+
end
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
# compare different currencies (using Comparable)
|
|
153
|
+
# in this case, we only care about comparing the amounts of each MGDMoney object
|
|
154
|
+
# @param [MGDMoney] other_object, the object to compare to
|
|
155
|
+
# @return [FixNum]
|
|
156
|
+
# @example twenty_dollars == MGDMoney.new(20, 'USD') # => true
|
|
157
|
+
# @example twenty_dollars == MGDMoney.new(30, 'USD') # => false
|
|
158
|
+
# @example fifty_eur_in_usd = fifty_eur.convert_to('USD')
|
|
159
|
+
# @example fifty_eur_in_usd == fifty_eur => true
|
|
160
|
+
def <=>(other_object)
|
|
161
|
+
if other_object.is_a?(MGDMoney)
|
|
162
|
+
other_object = other_object.convert_to(currency)
|
|
163
|
+
amount <=> other_object.amount
|
|
164
|
+
else
|
|
165
|
+
raise UnknownObjectError, 'Unknown destination object type (must be type MGDMoney)'
|
|
166
|
+
end
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
# provide some useful error messages to the user
|
|
170
|
+
class UnknownConversionError < StandardError
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
class UnknownObjectError < StandardError
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
class UnsupportedOperationError < StandardError
|
|
177
|
+
end
|
|
178
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: mgd_money
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.0.2
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Matt Davis
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: bin
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2018-04-06 00:00:00.000000000 Z
|
|
12
|
+
dependencies: []
|
|
13
|
+
description: A simple gem to enable conversion and arithmetic operations between different
|
|
14
|
+
currencies
|
|
15
|
+
email: davismattg@gmail.com
|
|
16
|
+
executables: []
|
|
17
|
+
extensions: []
|
|
18
|
+
extra_rdoc_files: []
|
|
19
|
+
files:
|
|
20
|
+
- lib/mgd_money.rb
|
|
21
|
+
homepage: http://www.mattgdavis.com
|
|
22
|
+
licenses:
|
|
23
|
+
- MIT
|
|
24
|
+
metadata: {}
|
|
25
|
+
post_install_message:
|
|
26
|
+
rdoc_options: []
|
|
27
|
+
require_paths:
|
|
28
|
+
- lib
|
|
29
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
30
|
+
requirements:
|
|
31
|
+
- - '>='
|
|
32
|
+
- !ruby/object:Gem::Version
|
|
33
|
+
version: '0'
|
|
34
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
35
|
+
requirements:
|
|
36
|
+
- - '>='
|
|
37
|
+
- !ruby/object:Gem::Version
|
|
38
|
+
version: '0'
|
|
39
|
+
requirements: []
|
|
40
|
+
rubyforge_project:
|
|
41
|
+
rubygems_version: 2.0.14.1
|
|
42
|
+
signing_key:
|
|
43
|
+
specification_version: 4
|
|
44
|
+
summary: MGDMoney
|
|
45
|
+
test_files: []
|