Class: MoreMoney::Price
- Inherits:
-
Object
- Object
- MoreMoney::Price
- Includes:
- Comparable
- Defined in:
- lib/more_money/price.rb,
lib/more_money/price.rb
Overview
class methods for price
Constant Summary collapse
- TAXES =
{}
Instance Attribute Summary collapse
-
#money ⇒ Object
readonly
Returns the value of attribute money.
-
#tax ⇒ Object
readonly
Returns the value of attribute tax.
-
#tax_amounts ⇒ Object
readonly
Returns the value of attribute tax_amounts.
-
#tax_code ⇒ Object
readonly
Returns the value of attribute tax_code.
-
#tax_inclusive ⇒ Object
readonly
Returns the value of attribute tax_inclusive.
Class Method Summary collapse
-
.add_tax(tax) ⇒ Object
adds a tax to the set of available ones.
- .check_tax(tax_code) ⇒ Object
-
.default_inclusive ⇒ Object
show if by default prices are tax inclusive/exclusive.
-
.default_inclusive=(default_inclusive) ⇒ Object
set if by default prices are tax inclusive.
-
.default_tax ⇒ Object
the current default tax.
-
.default_tax=(tax_code) ⇒ Object
set the default tax MoreMoney::Money.default_tax_rate = ‘GBP’.
-
.partial_sum(*args) ⇒ Object
returns an array with the sum of the given arguments grouped by tax code it can only sum.
- .sum(*args) ⇒ Object
Instance Method Summary collapse
-
#*(fixnum) ⇒ Object
multiply money by fixnum.
- #-@ ⇒ Object
-
#/(fixnum) ⇒ Object
divide money by fixnum.
- #<=>(other_price) ⇒ Object
- #cents ⇒ Object
-
#currency ⇒ Object
currency.
-
#eql?(other_price) ⇒ Boolean
Do two money objects equal? Only works if both objects are of the same currency.
-
#format(*rules) ⇒ Object
Format the price according rules.
-
#gross ⇒ Object
returns a Money object with the gross amount.
-
#initialize(cents, currency = Money.default_currency, tax = Price.default_tax, tax_inclusive = Price.default_inclusive) ⇒ Price
constructor
Creates a new price object.
-
#net ⇒ Object
returns a Money object with the net amount.
-
#no_cost? ⇒ Boolean
Test if the price is zero.
- #tax_inclusive? ⇒ Boolean
-
#to_price ⇒ Object
Conversation to self.
-
#to_s ⇒ Object
Money.new(100, ‘USD’).to_s => “1.00”.
-
#zero? ⇒ Boolean
Test if the price is zero.
Constructor Details
#initialize(cents, currency = Money.default_currency, tax = Price.default_tax, tax_inclusive = Price.default_inclusive) ⇒ Price
Creates a new price object.
Price.new(100)
79 80 81 82 83 84 85 86 87 |
# File 'lib/more_money/price.rb', line 79 def initialize(cents, currency = Money.default_currency, tax = Price.default_tax, tax_inclusive = Price.default_inclusive) @money = Money.new(cents, currency) self.class.check_tax(tax) @tax = TAXES[tax] @tax_code = tax @tax_amounts = [] @tax_inclusive = tax_inclusive @tax_inclusive ? discount_tax : apply_tax end |
Instance Attribute Details
#money ⇒ Object (readonly)
Returns the value of attribute money.
73 74 75 |
# File 'lib/more_money/price.rb', line 73 def money @money end |
#tax ⇒ Object (readonly)
Returns the value of attribute tax.
73 74 75 |
# File 'lib/more_money/price.rb', line 73 def tax @tax end |
#tax_amounts ⇒ Object (readonly)
Returns the value of attribute tax_amounts.
73 74 75 |
# File 'lib/more_money/price.rb', line 73 def tax_amounts @tax_amounts end |
#tax_code ⇒ Object (readonly)
Returns the value of attribute tax_code.
73 74 75 |
# File 'lib/more_money/price.rb', line 73 def tax_code @tax_code end |
#tax_inclusive ⇒ Object (readonly)
Returns the value of attribute tax_inclusive.
73 74 75 |
# File 'lib/more_money/price.rb', line 73 def tax_inclusive @tax_inclusive end |
Class Method Details
.add_tax(tax) ⇒ Object
adds a tax to the set of available ones.
MoreMoney::Price.add_tax(tax_obj)
a tax object is a generic ruby object that responds to the methods
* apply -> lamba that applies the tax to a net value
* discount -> lambda that drops the tax from the gross value
* code -> short code for the tax
* formatted code -> code for display purpouse
56 57 58 59 60 61 62 63 64 65 66 67 |
# File 'lib/more_money/price.rb', line 56 def self.add_tax(tax) case tax when Hash TAXES[tax[:code]] = tax[:taxes].map { |t| TAXES[t] } else mandatory_methods = [:apply, :discount, :code, :formatted_code] mandatory_methods.each do |m| raise TaxMissingMethod, "#{m} method is not defined by #{tax.inspect}" unless tax.respond_to? m end TAXES[tax.code] = tax end end |
.check_tax(tax_code) ⇒ Object
69 70 71 |
# File 'lib/more_money/price.rb', line 69 def self.check_tax(tax_code) raise PriceInvalidTax, "#{tax_code} is not defined as a tax" unless TAXES.key?(tax_code) end |
.default_inclusive ⇒ Object
show if by default prices are tax inclusive/exclusive
35 36 37 |
# File 'lib/more_money/price.rb', line 35 def self.default_inclusive @default_inclusive end |
.default_inclusive=(default_inclusive) ⇒ Object
set if by default prices are tax inclusive
40 41 42 43 |
# File 'lib/more_money/price.rb', line 40 def self.default_inclusive=(default_inclusive) raise ArgumentError, "default inclusive can be only true or false" unless [TrueClass, FalseClass].member?(default_inclusive.class) @default_inclusive = default_inclusive end |
.default_tax ⇒ Object
the current default tax
22 23 24 |
# File 'lib/more_money/price.rb', line 22 def self.default_tax @default_tax end |
.default_tax=(tax_code) ⇒ Object
30 31 32 |
# File 'lib/more_money/price.rb', line 30 def self.default_tax=(tax_code) @default_tax = tax_code end |
.partial_sum(*args) ⇒ Object
returns an array with the sum of the given arguments grouped by tax code it can only sum
220 221 222 223 224 225 |
# File 'lib/more_money/price.rb', line 220 def self.partial_sum(*args) return nil if (to_sum = args.flatten.compact).size == 0 raise PricesWithDifferentInclusiveClause unless to_sum.collect { |p| p.tax_inclusive }.uniq.size == 1 same_tax_groups = to_sum.collect { |p| p.tax }.uniq.map { |tax| to_sum.select { |p| p.tax == tax } } same_tax_group_sums = same_tax_groups.map { |g| g.inject(Price.new(0, g.first.currency, g.first.tax_code, g.first.tax_inclusive)) { |tot, p| tot + p } } end |
.sum(*args) ⇒ Object
227 228 229 230 231 232 |
# File 'lib/more_money/price.rb', line 227 def self.sum(*args) return nil if args.flatten.size == 0 type = args.last.is_a?(Symbol) ? args.pop : :gross partial = [true, false].map { |t| partial_sum(args.flatten.select { |a| a.tax_inclusive == t }) }.flatten.compact partial.inject(Money.new(0, partial.first.currency)) { |tot, p| tot + p.send(type == :gross ? :gross : :net) } end |
Instance Method Details
#*(fixnum) ⇒ Object
multiply money by fixnum
144 145 146 |
# File 'lib/more_money/price.rb', line 144 def *(fixnum) Price.new(money.cents * fixnum, currency, tax_code, tax_inclusive) end |
#-@ ⇒ Object
139 140 141 |
# File 'lib/more_money/price.rb', line 139 def -@ self.class.new(-cents, currency, tax_code, tax_inclusive) end |
#/(fixnum) ⇒ Object
divide money by fixnum
149 150 151 |
# File 'lib/more_money/price.rb', line 149 def /(fixnum) Price.new(money.cents / fixnum, currency, tax_code, tax_inclusive) end |
#<=>(other_price) ⇒ Object
118 119 120 121 |
# File 'lib/more_money/price.rb', line 118 def <=>(other_price) raise_different_tax(other_price) net <=> other_price.net end |
#cents ⇒ Object
103 104 105 |
# File 'lib/more_money/price.rb', line 103 def cents money.cents end |
#currency ⇒ Object
currency
108 109 110 |
# File 'lib/more_money/price.rb', line 108 def currency money.currency end |
#eql?(other_price) ⇒ Boolean
Do two money objects equal? Only works if both objects are of the same currency
113 114 115 116 |
# File 'lib/more_money/price.rb', line 113 def eql?(other_price) raise_different_tax(other_price) net == other_price.net end |
#format(*rules) ⇒ Object
Format the price according rules
Currently supported are :with_tax_inclusion, :with_tax All the extra rules specified will be passed to the money object
168 169 170 171 172 173 174 |
# File 'lib/more_money/price.rb', line 168 def format(*rules) rules = rules.flatten price_string = [] price_string << (tax.formatted_code) if rules.delete(:with_tax) price_string << (tax_inclusive ? 'inc.' : 'exc.') if rules.delete(:with_tax_inclusion) ([money.format(rules)] + price_string).join(' ') end |
#gross ⇒ Object
returns a Money object with the gross amount
99 100 101 |
# File 'lib/more_money/price.rb', line 99 def gross tax_inclusive ? money : tax_amounts.inject(net) { |sum, a| sum + a[1] } end |
#net ⇒ Object
returns a Money object with the net amount
94 95 96 |
# File 'lib/more_money/price.rb', line 94 def net tax_inclusive ? tax_amounts.inject(gross) { |sum, a| sum - a[1] } : money end |
#no_cost? ⇒ Boolean
Test if the price is zero
159 160 161 |
# File 'lib/more_money/price.rb', line 159 def no_cost? return (money.zero? || money.cents.nil?) end |
#tax_inclusive? ⇒ Boolean
89 90 91 |
# File 'lib/more_money/price.rb', line 89 def tax_inclusive? tax_inclusive end |
#to_price ⇒ Object
Conversation to self
182 183 184 |
# File 'lib/more_money/price.rb', line 182 def to_price self end |
#to_s ⇒ Object
Money.new(100, ‘USD’).to_s => “1.00”
177 178 179 |
# File 'lib/more_money/price.rb', line 177 def to_s cents.nil? ? '' : sprintf("%.2f", money.cents.to_f / 100 ) end |
#zero? ⇒ Boolean
Test if the price is zero
154 155 156 |
# File 'lib/more_money/price.rb', line 154 def zero? return money.zero? end |