latinum 1.4.2 → 1.7.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/latinum.rb +2 -0
- data/lib/latinum/bank.rb +66 -21
- data/lib/latinum/collection.rb +33 -10
- data/lib/latinum/currencies/global.rb +29 -1
- data/{spec/latinum/comparison_spec.rb → lib/latinum/error.rb} +8 -18
- data/lib/latinum/formatters.rb +58 -26
- data/lib/latinum/resource.rb +68 -35
- data/lib/latinum/version.rb +3 -1
- metadata +25 -45
- data/.rspec +0 -3
- data/.travis.yml +0 -20
- data/Gemfile +0 -3
- data/README.md +0 -276
- data/Rakefile +0 -6
- data/latinum.gemspec +0 -22
- data/spec/latinum/bank_spec.rb +0 -83
- data/spec/latinum/collection_spec.rb +0 -140
- data/spec/latinum/formatters_spec.rb +0 -93
- data/spec/latinum/integrals_spec.rb +0 -45
- data/spec/latinum/resource_spec.rb +0 -130
- data/spec/spec_helper.rb +0 -11
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1d47aa25865b0ac4f8a71378e34f3ab3d2747cbcc53028aa39cf5db59ee7c283
|
4
|
+
data.tar.gz: 73244a39809482164e21800ac18a18831cd57c625e9a98d4036fc9a13e02ec71
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: af1494045eaecbf9ca00635bd7f9e02355554116d4227dc4fc8ef61326ab0be480b8891624352ad5f89639db482a0d7ed101e38ec47276523f93ab66d30059e1
|
7
|
+
data.tar.gz: f03166e50246ff382aa4423c3e1438d5fbfefb66f5da4c6cd043a40e7f64282e37eb1c27e424c0f290f9aa30f790746bf0d9813eec3b21818e5be65c3350f1e9
|
data/lib/latinum.rb
CHANGED
data/lib/latinum/bank.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# Copyright, 2015, by Samuel G. D. Williams. <http://www.codeotaku.com>
|
2
4
|
#
|
3
5
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
@@ -21,19 +23,31 @@
|
|
21
23
|
require 'latinum/resource'
|
22
24
|
|
23
25
|
module Latinum
|
26
|
+
# A basic exchange rate for a named resource.
|
24
27
|
class ExchangeRate
|
28
|
+
# @parameter input [String] The name of the input resource.
|
29
|
+
# @parameter output [String] The name of the output resource.
|
30
|
+
# @parameter factor [Numeric] The rate of exchange.
|
25
31
|
def initialize(input, output, factor)
|
26
32
|
@input = input
|
27
33
|
@output = output
|
28
34
|
@factor = factor.to_d
|
29
35
|
end
|
30
36
|
|
37
|
+
# The name of the input resource.
|
38
|
+
# @attribute [String]
|
31
39
|
attr :input
|
40
|
+
|
41
|
+
# The name of the output resource.
|
42
|
+
# @attribute [String]
|
32
43
|
attr :output
|
44
|
+
|
45
|
+
# The rate of exchange.
|
46
|
+
# @attribute [String]
|
33
47
|
attr :factor
|
34
48
|
end
|
35
49
|
|
36
|
-
# A bank defines exchange rates and formatting rules for resources. It is a centralised location for resource
|
50
|
+
# A bank defines exchange rates and formatting rules for resources. It is a centralised location for resource formatting and metadata.
|
37
51
|
class Bank
|
38
52
|
# Imports all given currencies.
|
39
53
|
def initialize(*imports)
|
@@ -60,7 +74,7 @@ module Latinum
|
|
60
74
|
@currencies[name] = config
|
61
75
|
|
62
76
|
# Create a formatter:
|
63
|
-
@formatters[name] = config[:formatter].new(config)
|
77
|
+
@formatters[name] = config[:formatter].new(**config)
|
64
78
|
|
65
79
|
if config[:symbol]
|
66
80
|
symbols = (@symbols[config[:symbol]] ||= [])
|
@@ -71,16 +85,23 @@ module Latinum
|
|
71
85
|
end
|
72
86
|
|
73
87
|
# Look up a currency by name.
|
74
|
-
def []
|
88
|
+
def [](name)
|
75
89
|
@currencies[name]
|
76
90
|
end
|
77
91
|
|
78
92
|
attr :rates
|
93
|
+
|
94
|
+
# A map of all recognised symbols ordered by priority.
|
95
|
+
# @attribute [Hash(String, Tuple(Integer, Name))]
|
79
96
|
attr :symbols
|
97
|
+
|
98
|
+
# The supported currents and assocaited formatting details.
|
99
|
+
# @attribute [Hash(String, Hash)]
|
80
100
|
attr :currencies
|
81
101
|
|
82
102
|
# Add an exchange rate to the bank.
|
83
|
-
|
103
|
+
# @parameter rate [ExchangeRate] The exchange rate to add.
|
104
|
+
def <<(rate)
|
84
105
|
@rates << rate
|
85
106
|
|
86
107
|
@exchange[rate.input] ||= {}
|
@@ -89,12 +110,13 @@ module Latinum
|
|
89
110
|
|
90
111
|
# Exchange one resource for another using internally specified rates.
|
91
112
|
def exchange(resource, for_name)
|
92
|
-
rate = @exchange
|
93
|
-
|
113
|
+
unless rate = @exchange.dig(resource.name, for_name)
|
114
|
+
raise ArgumentError.new("Rate #{rate} unavailable")
|
115
|
+
end
|
94
116
|
|
95
117
|
config = self[for_name]
|
96
118
|
|
97
|
-
resource.exchange(rate.factor, for_name, config[:precision])
|
119
|
+
return resource.exchange(rate.factor, for_name, config[:precision])
|
98
120
|
end
|
99
121
|
|
100
122
|
# Parse a string according to the loaded currencies.
|
@@ -102,35 +124,55 @@ module Latinum
|
|
102
124
|
parts = string.strip.split(/\s+/, 2)
|
103
125
|
|
104
126
|
if parts.size == 2
|
105
|
-
|
127
|
+
return parse_named_resource(parts[1], parts[0])
|
106
128
|
else
|
107
129
|
# Lookup the named symbol, e.g. '$', and get the highest priority name:
|
108
|
-
symbol = @symbols.fetch(string.gsub(/[\-\.,0-9]/, ''), []).last
|
130
|
+
symbol = @symbols.fetch(string.gsub(/[\-\.,0-9]/, ''), []).last
|
109
131
|
|
110
132
|
if symbol
|
111
|
-
|
133
|
+
name = symbol.last.to_s
|
134
|
+
elsif default_name
|
135
|
+
name = default_name
|
112
136
|
else
|
113
|
-
raise ArgumentError
|
137
|
+
raise ArgumentError, "Could not parse #{string}, could not determine resource name!"
|
114
138
|
end
|
139
|
+
|
140
|
+
return parse_named_resource(name, string)
|
115
141
|
end
|
116
142
|
end
|
117
143
|
|
144
|
+
private def parse_named_resource(name, value)
|
145
|
+
if formatter = @formatters[name]
|
146
|
+
return Resource.new(formatter.parse(value), name)
|
147
|
+
else
|
148
|
+
raise ArgumentError, "No formatter found for #{name}!"
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
# Rounds the specified resource to the maximum precision as specified by the formatter. Whe computing things like tax, you often get fractional amounts which are unpayable because they are smaller than the minimum discrete unit of the currency. This method helps to round a currency to a payable amount.
|
153
|
+
# @parameter resource [Resource] The resource to round.
|
154
|
+
# @returns [Resource] A copy of the resource with the amount rounded as per the formatter.
|
118
155
|
def round(resource)
|
119
|
-
formatter = @formatters[resource.name]
|
120
|
-
|
156
|
+
unless formatter = @formatters[resource.name]
|
157
|
+
raise ArgumentError.new("No formatter found for #{resource.name}")
|
158
|
+
end
|
121
159
|
|
122
|
-
|
160
|
+
return Resource.new(formatter.round(resource.amount), resource.name)
|
123
161
|
end
|
124
162
|
|
125
163
|
# Format a resource as a string according to the loaded currencies.
|
126
|
-
|
127
|
-
|
128
|
-
|
164
|
+
# @parameter resource [Resource] The resource to format.
|
165
|
+
def format(resource, *arguments, **options)
|
166
|
+
unless formatter = @formatters[resource.name]
|
167
|
+
raise ArgumentError.new("No formatter found for #{resource.name}")
|
168
|
+
end
|
129
169
|
|
130
|
-
formatter.format(resource.amount, *
|
170
|
+
formatter.format(resource.amount, *arguments, **options)
|
131
171
|
end
|
132
172
|
|
133
173
|
# Convert the resource to an integral representation based on the currency's precision.
|
174
|
+
# @parameter resource [Resource] The resource to convert.
|
175
|
+
# @returns [Integer] The integer representation.
|
134
176
|
def to_integral(resource)
|
135
177
|
formatter = @formatters[resource.name]
|
136
178
|
|
@@ -138,10 +180,13 @@ module Latinum
|
|
138
180
|
end
|
139
181
|
|
140
182
|
# Convert the resource from an integral representation based on the currency's precision.
|
141
|
-
|
142
|
-
|
183
|
+
# @parameter amount [Integer] The integral resource amount.
|
184
|
+
# @parameter name [String] The resource name.
|
185
|
+
# @returns [Resource] The converted resource.
|
186
|
+
def from_integral(amount, name)
|
187
|
+
formatter = @formatters[name]
|
143
188
|
|
144
|
-
Resource.new(formatter.from_integral(amount),
|
189
|
+
Resource.new(formatter.from_integral(amount), name)
|
145
190
|
end
|
146
191
|
end
|
147
192
|
end
|
data/lib/latinum/collection.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# Copyright, 2015, by Samuel G. D. Williams. <http://www.codeotaku.com>
|
2
4
|
#
|
3
5
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
@@ -22,29 +24,34 @@ require 'bigdecimal'
|
|
22
24
|
require 'set'
|
23
25
|
|
24
26
|
module Latinum
|
25
|
-
# Aggregates a set of resources, typically used for summing values.
|
27
|
+
# Aggregates a set of resources, typically used for summing values to compute a total.
|
26
28
|
class Collection
|
27
29
|
include Enumerable
|
28
30
|
|
29
31
|
# Initialize the collection with a given set of resource names.
|
30
32
|
def initialize(names = Set.new)
|
31
33
|
@names = names
|
32
|
-
@resources = Hash.new {|hash, key| @names << key; BigDecimal(
|
34
|
+
@resources = Hash.new {|hash, key| @names << key; BigDecimal(0)}
|
33
35
|
end
|
34
36
|
|
35
|
-
# All resource names which have been added to the collection
|
37
|
+
# All resource names which have been added to the collection.
|
38
|
+
# e.g. `['NZD', 'USD']`.
|
39
|
+
# @attribute [Set]
|
36
40
|
attr :names
|
37
41
|
|
38
|
-
#
|
42
|
+
# Keeps track of all added resources.
|
43
|
+
# @attribute [Hash(String, BigDecimal)]
|
39
44
|
attr :resources
|
40
45
|
|
41
46
|
# Add a resource into the totals.
|
42
|
-
|
47
|
+
# @parameter resource [Resource] The resource to add.
|
48
|
+
def add(resource)
|
43
49
|
@resources[resource.name] += resource.amount
|
44
50
|
end
|
45
51
|
|
46
52
|
# Add a resource, an array of resources, or another collection into this one.
|
47
|
-
|
53
|
+
# @parameter object [Resource | Array(Resource) | Collection] The resource(s) to add.
|
54
|
+
def <<(object)
|
48
55
|
case object
|
49
56
|
when Resource
|
50
57
|
add(object)
|
@@ -65,7 +72,8 @@ module Latinum
|
|
65
72
|
self << -other
|
66
73
|
end
|
67
74
|
|
68
|
-
# Allow negation of all values within the collection
|
75
|
+
# Allow negation of all values within the collection.
|
76
|
+
# @returns [Collection] A new collection with the inverted values.
|
69
77
|
def -@
|
70
78
|
collection = self.class.new
|
71
79
|
|
@@ -76,16 +84,23 @@ module Latinum
|
|
76
84
|
return collection
|
77
85
|
end
|
78
86
|
|
79
|
-
#
|
87
|
+
# @returns [Resource | Nil] A resource for the specified name.
|
80
88
|
def [] key
|
81
|
-
|
89
|
+
if amount = @resources[key]
|
90
|
+
Resource.new(@resources[key], key)
|
91
|
+
end
|
82
92
|
end
|
83
93
|
|
84
|
-
# Set
|
94
|
+
# Set the amount for the specified resource name.
|
95
|
+
# @parameter key [String] The resource name.
|
96
|
+
# @parameter value [BigDecimal] The resource amount.
|
85
97
|
def []= key, amount
|
86
98
|
@resources[key] = amount
|
87
99
|
end
|
88
100
|
|
101
|
+
# Iterates over all the resources.
|
102
|
+
# @yields {|resource| ...} The resources if a block is given.
|
103
|
+
# @parameter resource [Resource]
|
89
104
|
def each
|
90
105
|
return to_enum(:each) unless block_given?
|
91
106
|
|
@@ -94,15 +109,20 @@ module Latinum
|
|
94
109
|
end
|
95
110
|
end
|
96
111
|
|
112
|
+
# Whether the collection is empty.
|
113
|
+
# @returns [Boolean]
|
97
114
|
def empty?
|
98
115
|
@resources.empty?
|
99
116
|
end
|
100
117
|
|
118
|
+
# Whether the collection contains the specified resource (may be zero).
|
119
|
+
# @returns [Boolean]
|
101
120
|
def include?(key)
|
102
121
|
@resources.include?(key)
|
103
122
|
end
|
104
123
|
|
105
124
|
# Generate a new collection but ignore zero values.
|
125
|
+
# @returns [Collection] A new collection.
|
106
126
|
def compact
|
107
127
|
collection = self.class.new
|
108
128
|
|
@@ -115,6 +135,9 @@ module Latinum
|
|
115
135
|
return collection
|
116
136
|
end
|
117
137
|
|
138
|
+
# A human readable representation of the collection.
|
139
|
+
# e.g. `"5.0 NZD; 10.0 USD"`
|
140
|
+
# @returns [String]
|
118
141
|
def to_s
|
119
142
|
@resources.map{|name, amount| "#{amount.to_s('F')} #{name}"}.join("; ")
|
120
143
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# encoding: UTF-8
|
2
4
|
#
|
3
5
|
# Copyright, 2015, by Samuel G. D. Williams. <http://www.codeotaku.com>
|
@@ -26,6 +28,8 @@ module Latinum
|
|
26
28
|
module Currencies
|
27
29
|
Global = {}
|
28
30
|
|
31
|
+
# @name Global[:NZD]
|
32
|
+
# @attribute [Hash] The New Zealand Dollar configuration.
|
29
33
|
Global[:NZD] = {
|
30
34
|
:precision => 2,
|
31
35
|
:symbol => '$',
|
@@ -34,6 +38,8 @@ module Latinum
|
|
34
38
|
:formatter => Formatters::DecimalCurrencyFormatter,
|
35
39
|
}
|
36
40
|
|
41
|
+
# @name Global[:GBP]
|
42
|
+
# @attribute [Hash] The Great British Pound configuration.
|
37
43
|
Global[:GBP] = {
|
38
44
|
:precision => 2,
|
39
45
|
:symbol => '£',
|
@@ -42,6 +48,8 @@ module Latinum
|
|
42
48
|
:formatter => Formatters::DecimalCurrencyFormatter,
|
43
49
|
}
|
44
50
|
|
51
|
+
# @name Global[:AUD]
|
52
|
+
# @attribute [Hash] The Australian Dollar configuration.
|
45
53
|
Global[:AUD] = {
|
46
54
|
:precision => 2,
|
47
55
|
:symbol => '$',
|
@@ -50,6 +58,8 @@ module Latinum
|
|
50
58
|
:formatter => Formatters::DecimalCurrencyFormatter,
|
51
59
|
}
|
52
60
|
|
61
|
+
# @name Global[:USD]
|
62
|
+
# @attribute [Hash] The United States Dollar configuration.
|
53
63
|
Global[:USD] = {
|
54
64
|
:precision => 2,
|
55
65
|
:symbol => '$',
|
@@ -58,16 +68,20 @@ module Latinum
|
|
58
68
|
:formatter => Formatters::DecimalCurrencyFormatter,
|
59
69
|
}
|
60
70
|
|
71
|
+
# @name Global[:EUR]
|
72
|
+
# @attribute [Hash] The Euro configuration.
|
61
73
|
Global[:EUR] = {
|
62
74
|
:precision => 2,
|
63
75
|
:symbol => '€',
|
64
76
|
:name => 'EUR',
|
65
77
|
:description => 'Euro',
|
66
78
|
:formatter => Formatters::DecimalCurrencyFormatter,
|
67
|
-
#:
|
79
|
+
#:delimiter => '.',
|
68
80
|
#:separator => ','
|
69
81
|
}
|
70
82
|
|
83
|
+
# @name Global[:JPY]
|
84
|
+
# @attribute [Hash] The Japanese Yen configuration.
|
71
85
|
Global[:JPY] = {
|
72
86
|
:precision => 0,
|
73
87
|
:symbol => '¥',
|
@@ -76,6 +90,20 @@ module Latinum
|
|
76
90
|
:formatter => Formatters::DecimalCurrencyFormatter
|
77
91
|
}
|
78
92
|
|
93
|
+
# @name Global[:BRL]
|
94
|
+
# @attribute [Hash] The Brazilian Real configuration.
|
95
|
+
Global[:BRL] = {
|
96
|
+
:precision => 2,
|
97
|
+
:symbol => 'R$',
|
98
|
+
:name => 'BRL',
|
99
|
+
:description => 'Brazilian Real',
|
100
|
+
:formatter => Formatters::DecimalCurrencyFormatter,
|
101
|
+
:delimiter => '.',
|
102
|
+
:separator => ','
|
103
|
+
}
|
104
|
+
|
105
|
+
# @name Global[:BTC]
|
106
|
+
# @attribute [Hash] The Bitcoin configuration.
|
79
107
|
Global[:BTC] = {
|
80
108
|
:precision => 8,
|
81
109
|
:symbol => 'B⃦',
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# Copyright, 2015, by Samuel G. D. Williams. <http://www.codeotaku.com>
|
2
4
|
#
|
3
5
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
@@ -18,23 +20,11 @@
|
|
18
20
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
21
|
# THE SOFTWARE.
|
20
22
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
expect(resource).to be < 20
|
28
|
-
expect(resource).to be > 5
|
29
|
-
expect(resource).to be == 10
|
30
|
-
end
|
31
|
-
|
32
|
-
it "should compare with nil" do
|
33
|
-
a = Latinum::Resource.load("10 NZD")
|
34
|
-
|
35
|
-
expect{a <=> nil}.to_not raise_exception
|
36
|
-
expect{a == nil}.to_not raise_exception
|
37
|
-
expect(a <=> nil).to be == nil
|
38
|
-
expect(a == nil).to be == false
|
23
|
+
module Latinum
|
24
|
+
# Represents an error when trying to perform arithmetic on differently named resources.
|
25
|
+
class DifferentResourceNameError < ArgumentError
|
26
|
+
def initialize
|
27
|
+
super "Cannot operate on different currencies!"
|
28
|
+
end
|
39
29
|
end
|
40
30
|
end
|
data/lib/latinum/formatters.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# Copyright, 2015, by Samuel G. D. Williams. <http://www.codeotaku.com>
|
2
4
|
#
|
3
5
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
@@ -20,77 +22,107 @@
|
|
20
22
|
|
21
23
|
module Latinum
|
22
24
|
module Formatters
|
23
|
-
|
24
|
-
:format => :full
|
25
|
-
}
|
26
|
-
|
25
|
+
# Formats a currency using a standard decimal notation.
|
27
26
|
class PlainFormatter
|
28
27
|
def initialize(name:)
|
29
28
|
@name = name
|
30
29
|
end
|
31
30
|
|
31
|
+
# Parse a string into an amount.
|
32
|
+
# @returns [BigDecimal] The parsed amount.
|
33
|
+
def parse(string)
|
34
|
+
BigDecimal(string)
|
35
|
+
end
|
36
|
+
|
37
|
+
# Formats the amount using a general notation.
|
38
|
+
# e.g. "5.0 NZD".
|
39
|
+
# @returns [String] The formatted string.
|
32
40
|
def format(amount)
|
33
41
|
"#{amount.to_s('F')} #{@name}"
|
34
42
|
end
|
35
43
|
|
44
|
+
# Converts the amount directly to an integer, truncating any decimal part.
|
45
|
+
# @parameter amount [BigDecimal] The amount to convert to an integral.
|
46
|
+
# @returns [Integer] The converted whole number integer.
|
36
47
|
def to_integral(amount)
|
37
48
|
amount.to_i
|
38
49
|
end
|
39
50
|
|
51
|
+
# Converts the amount to a decimal.
|
52
|
+
# @parameter amount [Integer] The amount to convert to a decimal.
|
53
|
+
# @returns [BigDecimal] The converted amount.
|
40
54
|
def from_integral(amount)
|
41
55
|
amount.to_d
|
42
56
|
end
|
43
57
|
end
|
44
|
-
|
58
|
+
|
59
|
+
# Formats a currency using a standard decimal notation.
|
45
60
|
class DecimalCurrencyFormatter
|
46
|
-
def initialize(options
|
61
|
+
def initialize(**options)
|
47
62
|
@symbol = options[:symbol] || '$'
|
48
63
|
@separator = options[:separator] || '.'
|
49
|
-
@
|
64
|
+
@delimiter = options[:delimiter] || ','
|
50
65
|
@places = options[:precision] || 2
|
51
66
|
@zero = options[:zero] || '0'
|
52
|
-
|
67
|
+
|
53
68
|
@name = options[:name]
|
54
69
|
end
|
55
|
-
|
70
|
+
|
56
71
|
def round(amount)
|
57
72
|
return amount.round(@places)
|
58
73
|
end
|
59
|
-
|
60
|
-
|
74
|
+
|
75
|
+
# Parse a string into an amount using the configured separator and delimiter.
|
76
|
+
# @returns [BigDecimal] The parsed amount.
|
77
|
+
def parse(string)
|
78
|
+
BigDecimal(
|
79
|
+
string.gsub(/[^\-0-9#{@separator}]/, '').gsub(@separator, '.')
|
80
|
+
)
|
81
|
+
end
|
82
|
+
|
83
|
+
# Formats the amount using the configured symbol, separator, delimiter, and places.
|
84
|
+
# e.g. "$5,000.00 NZD". Rounds the amount to the specified number of decimal places.
|
85
|
+
# @returns [String] The formatted string.
|
86
|
+
def format(amount, places: @places, **options)
|
61
87
|
# Round to the desired number of places. Truncation used to be the default.
|
62
|
-
amount = amount.round(
|
88
|
+
amount = amount.round(places).to_d
|
89
|
+
|
90
|
+
integral, fraction = amount.abs.to_s('F').split(/\./, 2)
|
63
91
|
|
64
|
-
fix, frac = amount.abs.to_s('F').split(/\./, 2)
|
65
|
-
|
66
92
|
# The sign of the number
|
67
93
|
sign = '-' if amount < 0
|
68
|
-
|
94
|
+
|
69
95
|
# Decimal places, e.g. the '.00' in '$10.00'
|
70
|
-
|
71
|
-
|
96
|
+
fraction = fraction[0...places].ljust(places, @zero)
|
97
|
+
|
72
98
|
# Grouping, e.g. the ',' in '$10,000.00'
|
73
|
-
remainder =
|
74
|
-
groups =
|
75
|
-
groups.unshift(
|
76
|
-
|
99
|
+
remainder = integral.size % 3
|
100
|
+
groups = integral[remainder..-1].scan(/.{3}/).to_a
|
101
|
+
groups.unshift(integral[0...remainder]) if remainder > 0
|
102
|
+
|
77
103
|
symbol = options.fetch(:symbol, @symbol)
|
78
|
-
value = "#{sign}#{symbol}#{groups.join(@
|
79
|
-
|
104
|
+
value = "#{sign}#{symbol}#{groups.join(@delimiter)}"
|
105
|
+
|
80
106
|
name = options.fetch(:name, @name)
|
81
107
|
suffix = name ? " #{name}" : ''
|
82
|
-
|
83
|
-
if
|
84
|
-
"#{value}#{@separator}#{
|
108
|
+
|
109
|
+
if places > 0
|
110
|
+
"#{value}#{@separator}#{fraction}#{suffix}"
|
85
111
|
else
|
86
112
|
"#{value}#{suffix}"
|
87
113
|
end
|
88
114
|
end
|
89
115
|
|
116
|
+
# Converts the amount directly to an integer, truncating any decimal part, taking into account the number of specified decimal places.
|
117
|
+
# @parameter amount [BigDecimal] The amount to convert to an integral.
|
118
|
+
# @returns [Integer] The converted whole number integer.
|
90
119
|
def to_integral(amount)
|
91
120
|
(amount * 10**@places).to_i
|
92
121
|
end
|
93
122
|
|
123
|
+
# Converts the amount to a decimal, taking into account the number of specified decimal places.
|
124
|
+
# @parameter amount [Integer] The amount to convert to a decimal.
|
125
|
+
# @returns [BigDecimal] The converted amount.
|
94
126
|
def from_integral(amount)
|
95
127
|
(amount.to_d / 10**@places)
|
96
128
|
end
|