amount 1.0.0
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/README.md +31 -0
- data/lib/amount/version.rb +18 -0
- data/lib/amount.rb +157 -0
- metadata +62 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 13044725c9fe6a8d41d0b7984ad962deec866d8a3674031bd9de40a91cdaa5be
|
4
|
+
data.tar.gz: 7e433ccc610c7b8e943f9ef60c7d8a36d9d3d8152d5ff190e351de6001e27a48
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 60e119fe8ed12781242f6e6125f54d22503af83120d329eb42424332fe96b9d7a71bc96883d5fbcc0d1c2fc877fa5cce8c10716416dde2113b0355bb3b91c267
|
7
|
+
data.tar.gz: cf975eb171b90104205856acd2bb3a1f7e047d3296136067bc9a602ca4f96bd298b5d8735c6e5c62f5d321cd9c8cd5ee21cce7674485f8a97329797d1baa01d0
|
data/README.md
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
# Amount
|
2
|
+
|
3
|
+
The amount gem provides a class called `Amount` that represents an amount of money with currency and 18-digit precision. It extends the functionality of the fixed gem and adds currency support to handle monetary values accurately.
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
```ruby
|
10
|
+
gem 'amount'
|
11
|
+
```
|
12
|
+
|
13
|
+
And then execute:
|
14
|
+
|
15
|
+
$ bundle install
|
16
|
+
|
17
|
+
Or install it yourself as:
|
18
|
+
|
19
|
+
$ gem install amount
|
20
|
+
|
21
|
+
## Usage
|
22
|
+
|
23
|
+
TODO: Write usage instructions here
|
24
|
+
|
25
|
+
## Contributing
|
26
|
+
|
27
|
+
Bug reports and pull requests are welcome on GitHub at [https://github.com/akuhn/amount](https://github.com/akuhn/amount). This project encourages collaboration and appreciates contributions. Feel free to contribute to the project by reporting bugs or submitting pull requests.
|
28
|
+
|
29
|
+
## License
|
30
|
+
|
31
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Amount < Fixed
|
4
|
+
VERSION = "1.0.0"
|
5
|
+
end
|
6
|
+
|
7
|
+
|
8
|
+
__END__
|
9
|
+
|
10
|
+
# Major version bump when breaking changes or new features
|
11
|
+
# Minor version bump when backward-compatible changes or enhancements
|
12
|
+
# Patch version bump when backward-compatible bug fixes, security updates etc
|
13
|
+
|
14
|
+
1.0.0
|
15
|
+
|
16
|
+
- Extends the fixed gem
|
17
|
+
- Adds currency support to handle monetary values
|
18
|
+
- Convenient constructors for creating money amounts
|
data/lib/amount.rb
ADDED
@@ -0,0 +1,157 @@
|
|
1
|
+
require 'fixed'
|
2
|
+
require 'amount/version'
|
3
|
+
|
4
|
+
# An amount of money with currency and 18-digit precision.
|
5
|
+
|
6
|
+
|
7
|
+
class Amount < Fixed
|
8
|
+
|
9
|
+
attr_reader :currency
|
10
|
+
|
11
|
+
|
12
|
+
#------- constructors ---------------------------------------------
|
13
|
+
|
14
|
+
private_class_method :new
|
15
|
+
|
16
|
+
def initialize(currency, fractions)
|
17
|
+
raise unless Symbol === currency
|
18
|
+
@currency = currency
|
19
|
+
super fractions
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.create(value, currency = nil)
|
23
|
+
if currency.nil?
|
24
|
+
case value
|
25
|
+
when Amount
|
26
|
+
return value
|
27
|
+
when String
|
28
|
+
return self.parse(value)
|
29
|
+
when Hash
|
30
|
+
case value.size
|
31
|
+
when 1
|
32
|
+
currency, value = value.first
|
33
|
+
when 2
|
34
|
+
return Amount.create value.fetch(:amount), value.fetch(:currency)
|
35
|
+
else
|
36
|
+
raise ArgumentError, "expected amount, got #{value.inspect}"
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
case value
|
42
|
+
when String
|
43
|
+
new currency.to_sym, string_as_fractions(value)
|
44
|
+
when Fixed
|
45
|
+
new currency.to_sym, value.fractions
|
46
|
+
when Numeric
|
47
|
+
new currency.to_sym, number_as_fractions(value)
|
48
|
+
else
|
49
|
+
raise ArgumentError, "expected amount, got #{[value,currency].inspect}"
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def self.parse(string)
|
54
|
+
raise "expect amount and currency, got #{string.inspect}" unless string =~ /\A(\S+)\s+(\S+)\Z/
|
55
|
+
new $2.to_sym, string_as_fractions($1)
|
56
|
+
end
|
57
|
+
|
58
|
+
def self.from_number(currency, units)
|
59
|
+
new currency, number_as_fractions(units)
|
60
|
+
end
|
61
|
+
|
62
|
+
def self.from_fractions(currency, fractions, precision: nil)
|
63
|
+
if precision
|
64
|
+
raise unless (0..18) === precision
|
65
|
+
fractions = fractions * (10 ** (18 - precision))
|
66
|
+
end
|
67
|
+
|
68
|
+
new currency, fractions
|
69
|
+
end
|
70
|
+
|
71
|
+
def self.smallest(currency)
|
72
|
+
new currency, 1
|
73
|
+
end
|
74
|
+
|
75
|
+
def self.zero(currency)
|
76
|
+
new currency, 0
|
77
|
+
end
|
78
|
+
|
79
|
+
#------- arithmetics ----------------------------------------------
|
80
|
+
|
81
|
+
def +(amount)
|
82
|
+
raise "expected curreny #{self.currency}, got #{amount.currency}" unless self.currency == amount.currency
|
83
|
+
super
|
84
|
+
end
|
85
|
+
|
86
|
+
def -(amount)
|
87
|
+
raise "expected curreny #{self.currency}, got #{amount.currency}" unless self.currency == amount.currency
|
88
|
+
super
|
89
|
+
end
|
90
|
+
|
91
|
+
def *(number)
|
92
|
+
raise "expected curreny #{self.currency}, got #{number.currency}" unless self.currency == number.currency if Amount === number
|
93
|
+
super
|
94
|
+
end
|
95
|
+
|
96
|
+
def /(number)
|
97
|
+
raise "expected curreny #{self.currency}, got #{number.currency}" unless self.currency == number.currency if Amount === number
|
98
|
+
super
|
99
|
+
end
|
100
|
+
|
101
|
+
|
102
|
+
# ------- comparing -----------------------------------------------
|
103
|
+
|
104
|
+
def dollar?
|
105
|
+
self.currency == :USD
|
106
|
+
end
|
107
|
+
|
108
|
+
def ==(amount)
|
109
|
+
Amount === amount && self.currency == amount.currency && self.fractions == amount.fractions
|
110
|
+
end
|
111
|
+
|
112
|
+
|
113
|
+
# ------- printing ------------------------------------------------
|
114
|
+
|
115
|
+
def inspect
|
116
|
+
"#{super} #{currency}"
|
117
|
+
end
|
118
|
+
|
119
|
+
def format(precision = 8)
|
120
|
+
"#{super precision} #{currency}"
|
121
|
+
end
|
122
|
+
|
123
|
+
|
124
|
+
# ------- helpers -------------------------------------------------
|
125
|
+
|
126
|
+
def to_amount
|
127
|
+
self
|
128
|
+
end
|
129
|
+
|
130
|
+
def eps
|
131
|
+
self.fractions
|
132
|
+
end
|
133
|
+
|
134
|
+
def without_currency
|
135
|
+
Fixed.from_fractions self.fractions
|
136
|
+
end
|
137
|
+
|
138
|
+
protected
|
139
|
+
|
140
|
+
def make(new_fractions)
|
141
|
+
Amount.from_fractions self.currency, new_fractions
|
142
|
+
end
|
143
|
+
|
144
|
+
end
|
145
|
+
|
146
|
+
module Kernel
|
147
|
+
def Amount(value, currency = nil)
|
148
|
+
Amount.create value, currency
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
class String
|
153
|
+
def to_amount
|
154
|
+
Amount.parse self
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
metadata
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: amount
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Adrian Kuhn
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2023-05-28 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: fixed
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.0'
|
27
|
+
description:
|
28
|
+
email:
|
29
|
+
- akuhn@iam.unibe.ch
|
30
|
+
executables: []
|
31
|
+
extensions: []
|
32
|
+
extra_rdoc_files: []
|
33
|
+
files:
|
34
|
+
- README.md
|
35
|
+
- lib/amount.rb
|
36
|
+
- lib/amount/version.rb
|
37
|
+
homepage: https://github.com/akuhn/amount
|
38
|
+
licenses: []
|
39
|
+
metadata:
|
40
|
+
homepage_uri: https://github.com/akuhn/amount
|
41
|
+
source_code_uri: https://github.com/akuhn/amount
|
42
|
+
changelog_uri: https://github.com/akuhn/amount/blob/master/lib/amount/version.rb
|
43
|
+
post_install_message:
|
44
|
+
rdoc_options: []
|
45
|
+
require_paths:
|
46
|
+
- lib
|
47
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
48
|
+
requirements:
|
49
|
+
- - ">="
|
50
|
+
- !ruby/object:Gem::Version
|
51
|
+
version: 2.6.0
|
52
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
53
|
+
requirements:
|
54
|
+
- - ">="
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
version: '0'
|
57
|
+
requirements: []
|
58
|
+
rubygems_version: 3.1.6
|
59
|
+
signing_key:
|
60
|
+
specification_version: 4
|
61
|
+
summary: An amount of money with currency and 18-digit precision.
|
62
|
+
test_files: []
|