amount 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (5) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +31 -0
  3. data/lib/amount/version.rb +18 -0
  4. data/lib/amount.rb +157 -0
  5. 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: []