money_extensions 0.1.0 → 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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 4d04889e7bd94edc4a6d9d405d7e9bc0ea76ac42
4
- data.tar.gz: b6981f399bab4e9c5678bd70bb2ab439ab451034
2
+ SHA256:
3
+ metadata.gz: 664c218fac6464fdf5789d5a301bd50d5ab9b4270dc537c199f451a4c1c8da1c
4
+ data.tar.gz: e824d3b3e10bde7a5c20c26c9668db8ca4b09d2f513adddf82466909d14702c1
5
5
  SHA512:
6
- metadata.gz: 70ba70b3afa207cdd486dfefe8f8585030fc6eefaa907afbf53f71ec8840d5efbc7de70dcac03413b11d1e58550f7e2112aa4d466d59c09cbe05940039e97c0c
7
- data.tar.gz: aef1df6411294b67265c82bd2e294e8e4ce8845a37c69c1e14f06d5a1808e0b3a13e6a593d667130b854d71714e1c64bc14b75c623111a31fd454c4b3327a715
6
+ metadata.gz: dbd0b0d8a7f25d7601bea3006156e8324b0a211155431ea2bcfa65a3ce62c24efbfee701429ce544765cf80a1f77bd75518fce0e90647a5000be26a4de6b2b0c
7
+ data.tar.gz: 6828b8a3401ea874852b0804c695b06f97b107830d610c25f0ad99aed9d1b29db7c91b5594fec8782fe3233173e66fbd84377b7b98c398bae5a599a4c220c3c4
data/.gitignore CHANGED
@@ -2,3 +2,5 @@ pkg
2
2
  coverage
3
3
  Gemfile.lock
4
4
  tmp
5
+ vendor
6
+ .bundle
@@ -0,0 +1 @@
1
+ 2.6.3
@@ -1,22 +1,18 @@
1
1
  language: ruby
2
2
  rvm:
3
- - 2.2.2
4
- - 2.3.0
5
3
  - 2.4
4
+ - 2.5
5
+ - 2.6
6
6
  matrix:
7
- fast_finish: true
8
7
  exclude:
9
8
  - rvm: 2.4
10
- gemfile: gemfiles/rails3.gemfile
9
+ gemfile: gemfiles/rails6.gemfile
10
+
11
+ script: "bundle exec rake spec"
11
12
  gemfile:
12
- - gemfiles/rails3.gemfile
13
- - gemfiles/rails4.gemfile
14
13
  - gemfiles/rails5.gemfile
15
- script: "bundle exec rake spec"
16
- notifications:
17
- email:
18
- - support@travellink.com.au
19
- flowdock:
20
- secure: A0Fr9j0kvKPEWuPbJu/DPMYPvx98UI8k43adKN9UjTB6FRVAQM3kXmKJIL3A495scc2Civrg2KHDkbwNwVThY+HdLeU7q71Bm6obP6ZkCe43MIoc9NiVJymCNguku6+tLEyusdWIceFiBW7P5p/sU1QU66GFj1t4wNTpVq9A4Kw=
14
+ - gemfiles/rails6.gemfile
21
15
  sudo: false
22
16
  cache: bundler
17
+ before_install:
18
+ - gem install bundler
@@ -1,6 +1,8 @@
1
1
  # Changelog
2
2
 
3
- ## Unreleased
3
+ ## 1.0.0
4
+
5
+ * [TT-5845] Update to support money gems >= 6
4
6
 
5
7
  ## 0.1.0
6
8
 
@@ -2,5 +2,6 @@ source 'https://rubygems.org'
2
2
  gemspec :path => '../'
3
3
 
4
4
  group :development, :test do
5
- gem 'activerecord', '~> 5.0'
5
+ gem 'activerecord', '~> 5'
6
+ gem 'activesupport', '~> 5'
6
7
  end
@@ -1,8 +1,7 @@
1
1
  source 'https://rubygems.org'
2
2
  gemspec :path => '../'
3
3
 
4
- gem 'money', '< 5.1', :platform => :ruby_18
5
-
6
4
  group :development, :test do
7
- gem 'activerecord', '~> 4.0'
5
+ gem 'activerecord', '~> 6.0rc2'
6
+ gem 'activesupport', '~> 6.0rc2'
8
7
  end
@@ -1,9 +1,9 @@
1
1
  module MoneyExtensions
2
2
  require 'money'
3
3
  require 'money_extensions/array'
4
- require 'money_extensions/big_decimal'
5
4
  require 'money_extensions/integer'
6
- require 'money_extensions/extensions'
5
+ require 'money_extensions/split_between'
6
+ require 'money_extensions/html_format'
7
7
  require 'money_extensions/money_field'
8
8
  require 'money_extensions/numeric'
9
9
  require 'money_extensions/string'
@@ -14,4 +14,3 @@ module MoneyExtensions
14
14
  end
15
15
 
16
16
  end
17
-
@@ -1,6 +1,7 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module Extensions
3
-
4
5
  def self.included(base)
5
6
  base.extend(ClassMethods)
6
7
  end
@@ -18,20 +19,14 @@ module ActiveRecord
18
19
 
19
20
  field_name = "#{attr_name}_iso_code"
20
21
 
21
- composed_of attr_name, :class_name => "Money::Currency",
22
- :mapping => [field_name, 'iso_code'],
23
- :allow_nil => true,
24
- :constructor => Proc.new{|value| Money::Currency.new(value) unless value.blank?}
22
+ composed_of attr_name, class_name: 'Money::Currency',
23
+ mapping: [field_name, 'iso_code'],
24
+ allow_nil: true,
25
+ constructor: proc { |value| Money::Currency.new(value) unless value.blank? }
25
26
 
26
- if Rails.version > '3'
27
- scope :for_currency, lambda{ |currency|
28
- where(:currency_iso_code => currency.iso_code)
27
+ scope :for_currency, lambda { |currency|
28
+ where(currency_iso_code: currency.iso_code)
29
29
  }
30
- else
31
- named_scope :for_currency, lambda{ |currency|
32
- {:conditions => {:currency_iso_code => currency.iso_code}}
33
- }
34
- end
35
30
 
36
31
  if options[:default]
37
32
  before_validation :set_default_currency
@@ -43,13 +38,9 @@ module ActiveRecord
43
38
  METHOD
44
39
  end
45
40
 
46
- if options[:required]
47
- validates_presence_of :currency_iso_code
48
- end
41
+ validates_presence_of :currency_iso_code if options[:required]
49
42
  end
50
-
51
43
  end
52
-
53
44
  end
54
45
  end
55
46
 
@@ -1,6 +1,8 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Array
2
4
  # Returns sum as a money - and returns 0 for empty arrays
3
5
  def total_money
4
6
  empty? ? ::Money.new(0) : inject(:+)
5
7
  end
6
- end
8
+ end
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'active_support/core_ext/string/output_safety'
4
+
5
+ module HtmlFormat
6
+ def format(**rules)
7
+ html_wrap = rules.delete(:html_wrap)
8
+ return html_wrap(super(**rules)) if html_wrap
9
+
10
+ super(**rules)
11
+ end
12
+
13
+ def as_html(**rules)
14
+ rules[:html_wrap] = true
15
+ format(**rules).html_safe
16
+ end
17
+
18
+ private
19
+
20
+ def html_wrap(str)
21
+ "<span class=\"money #{direction_class}\">#{str}</span>"
22
+ end
23
+
24
+ def direction_class
25
+ if cents > 0
26
+ 'positive'
27
+ elsif cents < 0
28
+ 'negative'
29
+ else
30
+ 'zero'
31
+ end
32
+ end
33
+ end
34
+
35
+ class Money
36
+ prepend HtmlFormat
37
+ end
@@ -1,5 +1,7 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Integer
2
- #Returns self as a money (treated as cents)
4
+ # Returns self as a money (treated as cents)
3
5
  def total_money
4
6
  zero? ? ::Money.new(0) : ::Money.new(self)
5
7
  end
@@ -1,5 +1,6 @@
1
- module MoneyField
1
+ # frozen_string_literal: true
2
2
 
3
+ module MoneyField
3
4
  def self.included(base)
4
5
  base.extend(ClassMethods)
5
6
  end
@@ -23,12 +24,10 @@ module MoneyField
23
24
  METHOD
24
25
  end
25
26
 
26
-
27
27
  def money_fields(*attributes)
28
- attributes.each {|a| self.money_field(a)}
28
+ attributes.each { |a| money_field(a) }
29
29
  end
30
30
 
31
-
32
31
  def money(*fields)
33
32
  fields.each do |field|
34
33
  class_eval <<-METHOD
@@ -38,7 +37,5 @@ module MoneyField
38
37
  METHOD
39
38
  end
40
39
  end
41
-
42
40
  end
43
-
44
- end
41
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Numeric
2
4
  # Converts this numeric to a Money object in the default currency. It
3
5
  # multiplies the numeric value by 100 and treats that as cents.
@@ -11,6 +13,6 @@ class Numeric
11
13
  # require 'bigdecimal'
12
14
  # BigDecimal.new('100').to_money => #<Money @cents=10000>
13
15
  def to_money(currency = nil)
14
- ::Money.new((self * 100).round, currency)
16
+ ::Money.new((self * 100).round, currency || Money.default_currency)
15
17
  end
16
- end
18
+ end
@@ -0,0 +1,54 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SplitBetween
4
+ # Override division -- should not do it, but use split_between
5
+ def /(*_params)
6
+ raise "Division of money NOT allowed - use 'split_between' to avoid rounding errors"
7
+ end
8
+
9
+ # Split the money between the specified number - and return an array of money
10
+ # Remainder in splits are given to the highest value e.g.
11
+ # $2.00 splits [40, 81, 40] into [49, 102, 49]
12
+ # $1.01 splits [ 1, 1, 1] into [35, 33, 33]
13
+ def split_between(params)
14
+ # if just a number is passed in, then money is split equally
15
+ if params.is_a?(Integer)
16
+ divisor = params
17
+ raise ArgumentError, 'Can only split up over a positive number' if divisor < 1
18
+
19
+ rounded_split = lossy_divide(divisor)
20
+ results = Array.new(divisor, rounded_split) # Create with 'divisor' num elements
21
+
22
+ # if an array of monies is passed in, then split in proportions
23
+ elsif params.is_a?(Array)
24
+
25
+ raise ArgumentError, 'Can only split up over at least one ration' if params.empty? && !zero?
26
+
27
+ results = params.map { |p| p.is_a?(::Money) ? p.cents : p }
28
+
29
+ total = results.inject(:+)
30
+ if total.zero?
31
+ return Array.new(results.size, ::Money.new(0)) if zero?
32
+
33
+ raise ArgumentError, "Total of ratios should not be zero! You sent in: #{params.inspect}"
34
+ end
35
+
36
+ results.map! do |ratio|
37
+ ::Money.new((cents * (ratio.to_f / total)).round)
38
+ end
39
+ else
40
+ raise 'Either a Integer or array has to be passed in for splitting money'
41
+ end
42
+
43
+ # Distribute rounding to max absolute to avoid a $0 amount getting the rounding
44
+ biggest_value_index = results.index(results.max_by(&:abs))
45
+ results[biggest_value_index] += self - results.total_money
46
+
47
+ results
48
+ end
49
+ end
50
+
51
+ class Money
52
+ alias lossy_divide /
53
+ include SplitBetween
54
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class String
2
4
  # Converts this string to a float and then to a Money object in the default currency.
3
5
  # It multiplies the converted numeric value by 100 and treats that as cents.
@@ -9,6 +11,6 @@ class String
9
11
  # '100'.to_money => #<Money @cents=10000>
10
12
  # '100.37'.to_money => #<Money @cents=10037>
11
13
  def to_money(currency = nil)
12
- Money.new((self.to_f * 100).round, currency)
14
+ Money.new((to_f * 100).round, currency)
13
15
  end
14
- end
16
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module MoneyExtensions
2
- VERSION = '0.1.0'
4
+ VERSION = '1.0.0'
3
5
  end
@@ -19,8 +19,12 @@ Gem::Specification.new do |spec|
19
19
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
20
20
  spec.require_paths = ["lib"]
21
21
 
22
- spec.add_dependency 'money', '>= 3.0.0', '< 6.0.0'
22
+ spec.add_dependency 'money', '>= 6.0.0'
23
+ spec.add_dependency 'activesupport', '>= 5'
24
+
23
25
  spec.add_development_dependency 'rake'
26
+ spec.add_development_dependency 'pry'
27
+ spec.add_development_dependency 'rubocop'
24
28
  spec.add_development_dependency 'rspec'
25
29
  spec.add_development_dependency 'coverage-kit'
26
30
  spec.add_development_dependency 'simplecov-rcov'
@@ -3,15 +3,15 @@ require 'spec_helper'
3
3
  describe BigDecimal do
4
4
 
5
5
  it "should allow verifying if it's a positive value" do
6
- expect(BigDecimal.new('-1')).to_not be_positive
7
- expect(BigDecimal.new('0')).to_not be_positive
8
- expect(BigDecimal.new('1')).to be_positive
6
+ expect(BigDecimal('-1')).to_not be_positive
7
+ expect(BigDecimal('0')).to_not be_positive
8
+ expect(BigDecimal('1')).to be_positive
9
9
  end
10
10
 
11
11
  it "should allow verifying if it's a negative value" do
12
- expect(BigDecimal.new('-1')).to be_negative
13
- expect(BigDecimal.new('0')).to_not be_negative
14
- expect(BigDecimal.new('1')).to_not be_negative
12
+ expect(BigDecimal('-1')).to be_negative
13
+ expect(BigDecimal('0')).to_not be_negative
14
+ expect(BigDecimal('1')).to_not be_negative
15
15
  end
16
16
 
17
17
  end
@@ -0,0 +1,48 @@
1
+ require 'money'
2
+ require 'money_extensions/string'
3
+ require 'money_extensions/html_format'
4
+
5
+ RSpec.describe Money do
6
+ before { Money.locale_backend = nil }
7
+ after { Money.locale_backend = :legacy }
8
+
9
+ let(:money_positive) { Money.new(100) }
10
+ let(:money_negative) { Money.new(-100) }
11
+ let(:money_zero) { Money.new(0) }
12
+
13
+ subject { money_positive.format(*rules) }
14
+
15
+ it "should format the output correctly" do
16
+ expect(money_negative.format(html_wrap: true, sign_before_symbol: true)).to eq "<span class=\"money negative\">-$1.00</span>"
17
+ expect(money_positive.format(html_wrap: true)).to eq "<span class=\"money positive\">$1.00</span>"
18
+ expect(money_zero.format(html_wrap: true)).to eq "<span class=\"money zero\">$0.00</span>"
19
+
20
+ expect(money_positive.format(html_wrap: true)).to eq "<span class=\"money positive\">$1.00</span>"
21
+ expect(money_negative.format(html_wrap: true, sign_before_symbol: true)).to eq "<span class=\"money negative\">-$1.00</span>"
22
+ expect(money_zero.format(html_wrap: true)).to eq "<span class=\"money zero\">$0.00</span>"
23
+
24
+ expect(money_positive.format(signed: true, sign_positive: true, sign_before_symbol: true)).to eq "+$1.00"
25
+ expect(money_negative.format(signed: true, sign_before_symbol: true)).to eq "-$1.00"
26
+ expect(money_zero.format(signed: true)).to eq "$0.00"
27
+
28
+ expect(money_positive.format(separator: '~')).to eq "$1~00"
29
+ end
30
+
31
+ it 'should work with as_html' do
32
+ expect(money_negative.as_html(sign_before_symbol: true)).to eq "<span class=\"money negative\">-$1.00</span>"
33
+ expect(money_positive.as_html).to eq "<span class=\"money positive\">$1.00</span>"
34
+ expect(money_zero.as_html).to eq "<span class=\"money zero\">$0.00</span>"
35
+
36
+ expect(money_positive.as_html).to eq "<span class=\"money positive\">$1.00</span>"
37
+ expect(money_negative.as_html(sign_before_symbol: true)).to eq "<span class=\"money negative\">-$1.00</span>"
38
+ expect(money_zero.as_html).to eq "<span class=\"money zero\">$0.00</span>"
39
+ end
40
+
41
+ it 'should format cents where appropriate' do
42
+ expect('1.50'.to_money.format(no_cents: true)).to eq '$1'
43
+ expect('1.00'.to_money.format(no_cents: true)).to eq '$1'
44
+
45
+ expect('1.50'.to_money.format(no_cents_if_whole: true)).to eq '$1.50'
46
+ expect('1.00'.to_money.format(no_cents_if_whole: true)).to eq '$1'
47
+ end
48
+ end
@@ -1,23 +1,6 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Money do
4
- it "should get correct direction class" do
5
- expect(Money.new(-1).direction_class).to eq 'negative'
6
- expect(Money.new(0).direction_class).to eq 'zero'
7
- expect(Money.new(1).direction_class).to eq 'positive'
8
- end
9
-
10
- it "should round correctly" do
11
- money = Money.new(511)
12
- expect(money.round.cents).to eq 500
13
- expect(money.round(10).cents).to eq 510
14
- expect(money.round(1).cents).to eq 511
15
-
16
- expect(money.round(100, 'up').cents).to eq 600
17
- expect(money.round(100, 'down').cents).to eq 500
18
- expect(money.round(100, 'nearest').cents).to eq 500
19
- end
20
-
21
4
  it "should deny division of money (to prevent rounding errors)" do
22
5
  expect { Money.new(50)/10 }.to raise_error(RuntimeError)
23
6
  end
@@ -38,7 +21,7 @@ describe Money do
38
21
  expect(money.split_between([1,2])).to eq [33,67].map{ |i| Money.new(i)}
39
22
 
40
23
  money_negative = Money.new(-100)
41
- expect(money_negative.split_between(3)).to eq [-32,-34,-34].map{ |i| Money.new(i)}
24
+ expect(money_negative.split_between(3)).to eq [-34,-33,-33].map{ |i| Money.new(i)}
42
25
  expect(money_negative.split_between([1,2,2,5])).to eq [-10,-20,-20,-50].map{ |i| Money.new(i)}
43
26
  expect(money_negative.split_between([1,2])).to eq [-33,-67].map{ |i| Money.new(i)}
44
27
 
@@ -60,14 +43,14 @@ describe Money do
60
43
 
61
44
  it "should return a nice, Big Decimal if so converted" do
62
45
  money = Money.new(1428)
63
- bigdecimal = BigDecimal.new("14.28")
46
+ bigdecimal = BigDecimal("14.28")
64
47
  expect(money.to_d).to eq bigdecimal
65
48
  end
66
49
 
67
50
  it "should be createable from strings and numbers" do
68
51
  money = Money.new(100)
69
52
  expect("1".to_money.cents).to eq money.cents
70
- expect(BigDecimal.new('1').to_money.cents).to eq money.cents
53
+ expect(BigDecimal('1').to_money.cents).to eq money.cents
71
54
  expect(100.total_money.cents).to eq money.cents
72
55
  end
73
56
 
@@ -89,29 +72,4 @@ describe Money do
89
72
  expect(money_negative.abs).to eq money_positive
90
73
  expect(money_zero.abs).to eq money_zero
91
74
  end
92
-
93
- it "should format the output correctly" do
94
- expect(money_positive.format).to eq "<span class=\"money positive\">$1.00</span>"
95
- expect(money_negative.format).to eq "<span class=\"money negative\">-$1.00</span>"
96
- expect(money_zero.format).to eq "<span class=\"money zero\">$0.00</span>"
97
-
98
- expect(money_positive.format(:html)).to eq "<span class=\"money positive\">$1.00</span>"
99
- expect(money_negative.format(:html)).to eq "<span class=\"money negative\">-$1.00</span>"
100
- expect(money_zero.format(:html)).to eq "<span class=\"money zero\">$0.00</span>"
101
-
102
- expect(money_positive.format(:signed)).to eq "+$1.00"
103
- expect(money_negative.format(:signed)).to eq "-$1.00"
104
- expect(money_zero.format(:signed)).to eq "$0.00"
105
-
106
- expect("1.50".to_money.format(:separator => '~')).to eq "$1~50"
107
- end
108
-
109
- it 'should format cents where appropriate' do
110
- expect('1.50'.to_money.format(:no_cents)).to eq '$1'
111
- expect('1.00'.to_money.format(:no_cents)).to eq '$1'
112
-
113
- expect('1.50'.to_money.format(:hide_zero_cents)).to eq '$1.50'
114
- expect('1.00'.to_money.format(:hide_zero_cents)).to eq '$1'
115
- end
116
-
117
75
  end
@@ -1,4 +1,4 @@
1
1
  require 'simplecov-rcov'
2
2
  require 'coveralls'
3
3
  require 'coverage/kit'
4
- Coverage::Kit.setup(minimum_coverage: 84.2)
4
+ Coverage::Kit.setup(minimum_coverage: 86.6)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: money_extensions
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Michael Noack
@@ -9,16 +9,13 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2018-05-18 00:00:00.000000000 Z
12
+ date: 2019-08-09 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: money
16
16
  requirement: !ruby/object:Gem::Requirement
17
17
  requirements:
18
18
  - - ">="
19
- - !ruby/object:Gem::Version
20
- version: 3.0.0
21
- - - "<"
22
19
  - !ruby/object:Gem::Version
23
20
  version: 6.0.0
24
21
  type: :runtime
@@ -26,11 +23,22 @@ dependencies:
26
23
  version_requirements: !ruby/object:Gem::Requirement
27
24
  requirements:
28
25
  - - ">="
29
- - !ruby/object:Gem::Version
30
- version: 3.0.0
31
- - - "<"
32
26
  - !ruby/object:Gem::Version
33
27
  version: 6.0.0
28
+ - !ruby/object:Gem::Dependency
29
+ name: activesupport
30
+ requirement: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - ">="
33
+ - !ruby/object:Gem::Version
34
+ version: '5'
35
+ type: :runtime
36
+ prerelease: false
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - ">="
40
+ - !ruby/object:Gem::Version
41
+ version: '5'
34
42
  - !ruby/object:Gem::Dependency
35
43
  name: rake
36
44
  requirement: !ruby/object:Gem::Requirement
@@ -45,6 +53,34 @@ dependencies:
45
53
  - - ">="
46
54
  - !ruby/object:Gem::Version
47
55
  version: '0'
56
+ - !ruby/object:Gem::Dependency
57
+ name: pry
58
+ requirement: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ version: '0'
63
+ type: :development
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - ">="
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ - !ruby/object:Gem::Dependency
71
+ name: rubocop
72
+ requirement: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - ">="
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ type: :development
78
+ prerelease: false
79
+ version_requirements: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - ">="
82
+ - !ruby/object:Gem::Version
83
+ version: '0'
48
84
  - !ruby/object:Gem::Dependency
49
85
  name: rspec
50
86
  requirement: !ruby/object:Gem::Requirement
@@ -151,28 +187,29 @@ extra_rdoc_files: []
151
187
  files:
152
188
  - ".gitignore"
153
189
  - ".rspec"
190
+ - ".ruby-version"
154
191
  - ".travis.yml"
155
192
  - CHANGELOG.md
156
193
  - Gemfile
157
194
  - LICENSE
158
195
  - README.md
159
196
  - Rakefile
160
- - gemfiles/rails3.gemfile
161
- - gemfiles/rails4.gemfile
162
197
  - gemfiles/rails5.gemfile
198
+ - gemfiles/rails6.gemfile
163
199
  - lib/money_extensions.rb
164
200
  - lib/money_extensions/active_record/extensions.rb
165
201
  - lib/money_extensions/array.rb
166
- - lib/money_extensions/big_decimal.rb
167
- - lib/money_extensions/extensions.rb
202
+ - lib/money_extensions/html_format.rb
168
203
  - lib/money_extensions/integer.rb
169
204
  - lib/money_extensions/money_field.rb
170
205
  - lib/money_extensions/numeric.rb
206
+ - lib/money_extensions/split_between.rb
171
207
  - lib/money_extensions/string.rb
172
208
  - lib/money_extensions/version.rb
173
209
  - money_extensions.gemspec
174
210
  - rails/init.rb
175
211
  - spec/big_decimal_spec.rb
212
+ - spec/html_format_spec.rb
176
213
  - spec/money_field_spec.rb
177
214
  - spec/money_spec.rb
178
215
  - spec/schema.rb
@@ -197,13 +234,13 @@ required_rubygems_version: !ruby/object:Gem::Requirement
197
234
  - !ruby/object:Gem::Version
198
235
  version: '0'
199
236
  requirements: []
200
- rubyforge_project:
201
- rubygems_version: 2.6.14.1
237
+ rubygems_version: 3.0.3
202
238
  signing_key:
203
239
  specification_version: 4
204
240
  summary: Set of extensions to the money gem used by TravelLink Technology.
205
241
  test_files:
206
242
  - spec/big_decimal_spec.rb
243
+ - spec/html_format_spec.rb
207
244
  - spec/money_field_spec.rb
208
245
  - spec/money_spec.rb
209
246
  - spec/schema.rb
@@ -1,8 +0,0 @@
1
- source 'https://rubygems.org'
2
- gemspec :path => "../"
3
-
4
- gem 'money', '< 5.1', :platform => :ruby_18
5
-
6
- group :development, :test do
7
- gem 'activerecord', '~> 3.2.0'
8
- end
@@ -1,12 +0,0 @@
1
- class BigDecimal
2
-
3
- def negative?
4
- self < BigDecimal.new('0')
5
- end
6
-
7
- def positive?
8
- self > BigDecimal.new('0')
9
- end
10
-
11
- end
12
-
@@ -1,189 +0,0 @@
1
- require 'money'
2
-
3
- module Extensions
4
-
5
- def self.included(base)
6
- base.class_eval do
7
- alias_method :to_s_without_currency_hack, :to_s
8
- alias_method :to_s, :to_s_with_currency_hack
9
- alias_method :to_d_without_currency_hack, :to_d
10
- alias_method :to_d, :to_d_with_currency_hack
11
- end
12
- end
13
-
14
- # Override division -- should not do it, but use split_between
15
- def /(*params)
16
- raise "Division of money NOT allowed - use 'split_between' to avoid rounding errors"
17
- end
18
-
19
- def to_d_with_currency_hack
20
- BigDecimal.new("#{cents/100.0}")
21
- end
22
-
23
- # Split the money between the specified number - and return an array of money
24
- # Remainder in splits are given to the highest value e.g.
25
- # $2.00 splits [40, 81, 40] into [49, 102, 49]
26
- # $1.01 splits [ 1, 1, 1] into [35, 33, 33]
27
- def split_between(params)
28
- #if just a number is passed in, then money is split equally
29
- if params.is_a?(Integer)
30
- divisor = params
31
- raise ArgumentError, "Can only split up over a positive number" if divisor < 1
32
-
33
- rounded_split = self.lossy_divide(divisor)
34
- results = Array.new(divisor, rounded_split) # Create with 'divisor' num elements
35
-
36
- #if an array of monies is passed in, then split in proportions
37
- elsif params.is_a?(Array)
38
-
39
- raise ArgumentError, "Can only split up over at least one ration" if params.empty? && !self.zero?
40
-
41
-
42
- results = params.map { |p| p.is_a?(::Money) ? p.cents : p }
43
-
44
- total = results.inject(:+)
45
- if total.zero?
46
- return Array.new(results.size, ::Money.new(0)) if self.zero?
47
- raise ArgumentError, "Total of ratios should not be zero! You sent in: #{params.inspect}"
48
- end
49
-
50
- results.map! do |ratio|
51
- ::Money.new((self.cents * (ratio.to_f / total)).round)
52
- end
53
- else
54
- raise "Either a Integer or array has to be passed in for splitting money"
55
- end
56
-
57
- # Distribute rounding to max absolute to avoid a $0 amount getting the rounding
58
- biggest_value_index = results.index(results.max_by(&:abs))
59
- results[biggest_value_index] += self - results.total_money
60
-
61
- return results
62
- end
63
-
64
-
65
- DEFAULT_FORMAT_RULES = [:html]
66
- # HACK COZ WE ARE PRETENDING WE DON'T HAVE CURRENCY!!!
67
- #
68
- # TODO: Make this not a hack...
69
- def to_s_with_currency_hack
70
- sprintf("%.2f", cents.to_f / 100) #currency.subunit_to_unit)
71
- end
72
-
73
- def inspect
74
- inbuilt_inspect_style_id = '%x' % (object_id << 1)
75
- "\#<Money:0x#{inbuilt_inspect_style_id} $#{self}>"
76
- end
77
-
78
- # Money's default formatted is not flexible enought.
79
- # - we don't want it to say 'free' when 0 (not correct for 'discounts' and such)
80
- def format(*rules)
81
- rules = rules.empty? ? DEFAULT_FORMAT_RULES.dup : rules.flatten
82
-
83
- options = {}
84
- rules.each do |rule|
85
- if rule.is_a? Hash
86
- options = rule
87
- end
88
- end
89
-
90
- html_wrap = rules.include?(:html)
91
-
92
- options[:delimiter] ||= ','
93
- options[:separator] ||= '.'
94
-
95
- ''.tap do |formatted|
96
- formatted << "<span class=\"money #{direction_class}\">" if html_wrap
97
-
98
- rules << :signed if cents < 0
99
-
100
- if rules.include?(:signed)
101
- formatted << if cents > 0
102
- '+'
103
- elsif cents < 0
104
- '-'
105
- else
106
- ''
107
- end
108
- end
109
-
110
- no_cents = rules.include?(:no_cents) ||
111
- (rules.include?(:hide_zero_cents) && cents % 100 == 0)
112
- format_string = no_cents ? "$%d" : "$%.2f"
113
- amount = format_string % (cents.abs.to_f / 100)
114
- amount.gsub!('.', options[:separator])
115
- amount.gsub!(/(\d)(?=(\d\d\d)+(?!\d))/, "\\1#{options[:delimiter]}")
116
- formatted << amount
117
-
118
- formatted << "</span>" if html_wrap
119
- end
120
- end
121
-
122
- def direction_class
123
- if cents > 0
124
- 'positive'
125
- elsif cents < 0
126
- 'negative'
127
- else
128
- 'zero'
129
- end
130
- end
131
-
132
- def mark_up(mark_up_definition)
133
- mark_up_cents = mark_up_definition.cents || 0
134
- rounding_direction = mark_up_definition.rounding_direction.try(:to_sym)
135
- multiplier = ((100 + mark_up_definition.percent)/100.0)
136
- (self * multiplier).round(mark_up_definition.rounding_cents, rounding_direction) + ::Money.new(mark_up_cents)
137
- end
138
-
139
- # money = Money.new(501)
140
- # money.round
141
- # => 500
142
- # money.round(10)
143
- # => 510
144
- # money.round(1)
145
- # => 511
146
-
147
- # money.round(100, 'up')
148
- # => 600
149
- # money.round(100, 'down')
150
- # => 500
151
- # money.round(100, 'nearest')
152
- # => 500
153
- def round(round_to_cents = 100, direction = :nearest)
154
- round_to_cents = 100 if round_to_cents.nil?
155
- case direction.to_sym
156
- when :nearest
157
- rounded_cents = (cents + round_to_cents/2) / round_to_cents * round_to_cents
158
- when :up
159
- rounded_cents = (cents + round_to_cents) / round_to_cents * round_to_cents
160
- when :down
161
- rounded_cents = (cents) / round_to_cents * round_to_cents
162
- else
163
- end
164
- ::Money.new(rounded_cents)
165
- end
166
-
167
- def abs
168
- if cents >= 0
169
- self.clone
170
- else
171
- ::Money.new(0 - cents)
172
- end
173
- end
174
-
175
- def positive?
176
- cents > 0
177
- end
178
-
179
- def negative?
180
- cents < 0
181
- end
182
-
183
- end
184
-
185
- ::Money.class_eval do
186
- alias_method :lossy_divide, :/
187
- end
188
-
189
- ::Money.send(:include, Extensions)