money_extensions 0.1.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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)