moolah 5.1.0 → 5.5.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a2da115bb4dda298972fa96865bb4ed3fc1d19804a0cf8c958c5b42af3136dfa
4
- data.tar.gz: 662d6e21e8e2fdbd51d08f5dc87d657e667a45d261c1327259e96ff9c4106df0
3
+ metadata.gz: e1d1a1e892be6a4317fb014f59b05ab26db3b9e1d38272b89e59fe76bb005c9a
4
+ data.tar.gz: b60ac538ac82a63ffa21afdf643d41e7da02144e3ffa01b211caa003379374c0
5
5
  SHA512:
6
- metadata.gz: 6bda8b4e7dffbf8ac27d0595436c73a598376ee217190a4a2741e4873bfe4c2c1b475d4102aa7e5c8e1181185fa2803e8a0186e995311d3e7721dbbde55014e6
7
- data.tar.gz: 3482d8f55571ec7a0d7f08c8c64d97eca27c2b8d60e42c0f9de5daf90c2901eb9d925367b3f30eaa75ae682b70ab4c6f4ee59b2a5941404269d60d508e390c64
6
+ metadata.gz: cc2acc4608c640be60f8833ecfedee7d56a41fe8fca58b21c521052b47d85c4ac93fa1bab37333eb8ce4c26fce7e189eaf65a679bf5fbd8606f4a52a1b079547
7
+ data.tar.gz: 31728aa78f418380e551a2be5dfbbe7b9e6bf3ba889663d5522fb00af5b254e2a2cfde8e2a94b8c64481b2a8c78e87674476606b8add8814cc014d22eb533116
data/README.md CHANGED
@@ -1,13 +1,9 @@
1
1
  # Moolah
2
2
 
3
- Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/moolah`. To experiment with that code, run `bin/console` for an interactive prompt.
4
-
5
- TODO: Delete this and the text above, and describe your gem
3
+ Moolah is a Money gem that deals with Currency and FX_RATE. It is being used in multiple repos in Hotels/Bookings.
6
4
 
7
5
  ## Installation
8
6
 
9
- Add this line to your application's Gemfile:
10
-
11
7
  ```ruby
12
8
  gem 'moolah'
13
9
  ```
@@ -20,9 +16,48 @@ Or install it yourself as:
20
16
 
21
17
  $ gem install moolah
22
18
 
19
+ ### How to upgrade to version 5
20
+
21
+ For version 5, `fx_rate` is a must field while initializing a Moolah::Money object with different currency other than AUD.
22
+ When you initialize Moolah::Money with AUD as the currency, the fx_rate will be default to 1.0
23
+
24
+ This will break projects that are using older Moolah version expect the project is using AUD as the main currency.
25
+
26
+ ```ruby
27
+ gem 'moolah', -> '5.3'
28
+ ```
29
+
30
+ ```
31
+ $ bundle update moolah
32
+ ```
33
+
23
34
  ## Usage
24
35
 
25
- TODO: Write usage instructions here
36
+ ### To create a new Moolah::Money object
37
+ ```ruby
38
+ Moolah::Money.new(amount: '10', currency: 'AUD', fx_rate: '1.0000')
39
+ ```
40
+
41
+ ### To create a AUD dollar Moolah::Money object
42
+ ```ruby
43
+ Moolah::Money.in_aud('10')
44
+ ```
45
+
46
+ ### To create a zero dollar Moolah::Money object
47
+ ```ruby
48
+ Moolah::Money.zero(currency: 'AUD', fx_rate: '1.0000')
49
+ ```
50
+
51
+ ### To display a json format of the Moolah::Money object
52
+ ```ruby
53
+ money = Moolah::Money.new(amount: '10', currency: 'AUD', fx_rate: '1.0000')
54
+ money.as_json
55
+ => {
56
+ 'amount' => '10.00',
57
+ 'currency' => 'AUD',
58
+ 'fx_rate' => '1.0000'
59
+ }
60
+ ```
26
61
 
27
62
  ## Development
28
63
 
@@ -9,7 +9,7 @@ module Moolah
9
9
  def load_csv(file)
10
10
  currencies = {}
11
11
 
12
- CSV.foreach(file, headers: true, header_converters: :symbol, encoding: 'ISO-8859-1') do |row|
12
+ CSV.foreach(file, headers: true, header_converters: :symbol, encoding: 'UTF-8') do |row|
13
13
  code = row[:code]
14
14
  currencies[code] = Currency.new(
15
15
  name: row[:currency],
@@ -14,7 +14,7 @@ module Moolah
14
14
  end
15
15
 
16
16
  def format_fx_rate
17
- ('%.2f' % money.fx_rate)
17
+ sprintf('%.4f', money.fx_rate)
18
18
  end
19
19
 
20
20
  private
data/lib/moolah/money.rb CHANGED
@@ -1,30 +1,55 @@
1
1
  require 'anemic/model'
2
2
  require 'bigdecimal'
3
+ require 'active_support'
3
4
 
4
5
  module Moolah
5
6
  class Money
6
7
  include Anemic::Model
7
8
  include Comparable
8
9
 
10
+ delegate :zero?, :positive?, :negative?, to: :amount
11
+
9
12
  attribute :amount, BigDecimal, default: BigDecimal(0)
10
13
  attribute :currency, String
11
14
  attribute :fx_rate, BigDecimal
12
15
 
13
16
  def initialize(args = {})
14
- args[:currency] = 'AUD' if args[:currency].nil? || args[:currency] == ''
15
- args[:fx_rate] = 1.0 if args[:currency] == 'AUD'
17
+ args[:currency] = 'AUD' if args[:currency].blank?
18
+ args[:fx_rate] = '1.0000' if args[:currency] == 'AUD'
16
19
 
17
- raise ArgumentError.new('missing keyword: :fx_rate') unless args[:fx_rate]
20
+ if args[:fx_rate].nil?
21
+ # So fx_rate appears as nil as part of the error message
22
+ args[:fx_rate] = nil
23
+ raise ArgumentError, "missing keyword: :fx_rate in #{self.class.name} (#{args.sort.to_h})"
24
+ end
18
25
 
19
26
  super(args)
20
27
  end
21
28
 
22
29
  def self.in_aud(amount)
23
- Money.new(currency: 'AUD', amount: amount)
30
+ new(amount: amount)
31
+ end
32
+
33
+ def self.zero(currency = 'AUD', fx_rate = nil)
34
+ new(currency: currency, amount: 0, fx_rate: fx_rate)
35
+ end
36
+
37
+ def to_aud
38
+ return Money.new if fx_rate.zero?
39
+
40
+ Money.new(amount: amount / fx_rate)
24
41
  end
25
42
 
26
- def self.zero(currency='AUD', fx_rate=1)
27
- Money.new(currency: currency, amount: 0, fx_rate: fx_rate)
43
+ def convert_to(other)
44
+ money = other.is_a?(Money) ? other : Money.new(other)
45
+
46
+ converted = Money.new(
47
+ amount: to_aud.amount * money.fx_rate,
48
+ currency: money.currency,
49
+ fx_rate: money.fx_rate
50
+ )
51
+
52
+ converted.bankers_rounded
28
53
  end
29
54
 
30
55
  def formatted(symbol: true, delimit: true)
@@ -35,6 +60,10 @@ module Moolah
35
60
  formatter.format(symbol: false, delimit: false)
36
61
  end
37
62
 
63
+ def formatted_fx_rate
64
+ formatter.format_fx_rate
65
+ end
66
+
38
67
  def amount_in_cents
39
68
  (bankers_rounded.amount * 100).to_i
40
69
  end
@@ -55,27 +84,31 @@ module Moolah
55
84
  "#{self.class.name} (#{as_json})"
56
85
  end
57
86
 
58
- def +(money)
59
- return self unless money
60
- raise ArgumentError, 'Cannot add two Money objects with different currencies' if currency != money.currency
61
- raise ArgumentError, 'Cannot add two Money objects with different fx rates' if fx_rate != money.fx_rate
87
+ def +(other)
88
+ return self if other.nil?
89
+
90
+ money = other.is_a?(Money) ? other : Money.new(other)
91
+ raise ArgumentError, "Cannot add currency: #{currency} with given currency: #{money.currency}" if currency != money.currency
92
+ raise ArgumentError, "Cannot add fx rate: #{formatter.format_fx_rate} with given fx rate: #{money.formatted_fx_rate}" if fx_rate != money.fx_rate
62
93
 
63
94
  Money.new(amount: amount + money.amount, currency: currency, fx_rate: fx_rate)
64
95
  end
65
96
 
66
- def -(money)
67
- return self unless money
68
- raise ArgumentError, 'Cannot subtract two Money objects with different currencies' if currency != money.currency
69
- raise ArgumentError, 'Cannot subtract two Money objects with different fx rates' if fx_rate != money.fx_rate
97
+ def -(other)
98
+ return self if other.nil?
99
+
100
+ money = other.is_a?(Money) ? other : Money.new(other)
101
+ raise ArgumentError, "Cannot subtract currency: #{currency} with given currency: #{money.currency}" if currency != money.currency
102
+ raise ArgumentError, "Cannot subtract fx rate: #{formatter.format_fx_rate} with given fx rate: #{money.formatted_fx_rate}" if fx_rate != money.fx_rate
70
103
 
71
104
  Money.new(amount: amount - money.amount, currency: currency, fx_rate: fx_rate)
72
105
  end
73
106
 
74
- def *(_money)
107
+ def *(_other)
75
108
  raise ArgumentError, 'Cannot multiply Money objects due to rounding issues'
76
109
  end
77
110
 
78
- def /(_money)
111
+ def /(_other)
79
112
  raise ArgumentError, 'Cannot divide Money objects due to rounding issues'
80
113
  end
81
114
 
@@ -83,21 +116,15 @@ module Moolah
83
116
  Money.new(amount: -amount, currency: currency, fx_rate: fx_rate)
84
117
  end
85
118
 
86
- def <=>(money)
87
- raise ArgumentError, 'Cannot compare two Money objects with different currencies' if currency != money.currency
88
- raise ArgumentError, 'Cannot compare two Money objects with different fx rates' if fx_rate != money.fx_rate
89
-
90
- amount <=> money.amount
119
+ def <=>(other)
120
+ money = other.is_a?(Money) ? other : Money.new(other)
121
+ to_aud.amount <=> money.to_aud.amount
91
122
  end
92
123
 
93
124
  def bankers_rounded
94
125
  Rounder.new(self).bankers_rounded
95
126
  end
96
127
 
97
- def zero?
98
- amount.zero?
99
- end
100
-
101
128
  def negate
102
129
  negated_amount = amount * -1
103
130
  negated_amount = 0 if negated_amount.to_s == '-0.0'
@@ -1,6 +1,6 @@
1
1
  module Moolah
2
2
  MAJOR = 5
3
- MINOR = 1
3
+ MINOR = 5
4
4
  PATCH = ENV['PATCH_VERSION'] || 0
5
5
 
6
6
  private_constant :MAJOR, :MINOR, :PATCH
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: moolah
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.1.0
4
+ version: 5.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Marc Lee
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: exe
11
11
  cert_chain: []
12
- date: 2022-07-14 00:00:00.000000000 Z
12
+ date: 2022-09-02 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: bundler