Class: Money
- Inherits:
-
Object
- Object
- Money
- Includes:
- Comparable
- Defined in:
- lib/bd_money/rails.rb,
lib/bd_money/bd_money.rb
Defined Under Namespace
Classes: MoneyError
Constant Summary collapse
- ROUND_MODES =
{ :ceiling => BigDecimal::ROUND_CEILING, :down => BigDecimal::ROUND_DOWN, :floor => BigDecimal::ROUND_FLOOR, :half_down => BigDecimal::ROUND_HALF_DOWN, :half_even => BigDecimal::ROUND_HALF_EVEN, :half_up => BigDecimal::ROUND_HALF_UP, :up => BigDecimal::ROUND_UP, }
- FORMATS =
{ :default => { :unit => "$", :spacer => " ", :delimiter => ",", :separator => ".", :precision => 2, :last => "" }, :no_cents => { :unit => "$", :spacer => " ", :delimiter => ",", :separator => ".", :precision => 0, :last => "" }, :no_commas => { :unit => "$", :spacer => " ", :delimiter => "", :separator => ".", :precision => 2, :last => "" }, :general => { :unit => "", :spacer => "", :delimiter => "", :separator => ".", :precision => 2, :last => "" }, }
- REMOVE_RE =
%r{[$,_ ]}
- VALID_RE =
%r{^(-)?(\d)+(\.\d*(e-\d{1,10})?)?$}
- YAML_TYPE_ROOT =
'npadv.com,2012-03-12'
- YAML_TYPE_NAME =
'money'
Class Method Summary collapse
- .[](value) ⇒ Object
- .clean(value) ⇒ Object
- .convert(value, precision = nil, round_mode = nil) ⇒ Object
- .format ⇒ Object
- .format=(value) ⇒ Object
- .precision ⇒ Object
- .precision=(value) ⇒ Object
- .round_mode ⇒ Object
- .round_mode=(value) ⇒ Object
- .valid?(value) ⇒ Boolean
- .zero ⇒ Object
Instance Method Summary collapse
- #%(other) ⇒ Object
- #*(other) ⇒ Object
- #**(other) ⇒ Object
- #+(other) ⇒ Object
- #-(other) ⇒ Object
- #/(other) ⇒ Object
- #<=>(other) ⇒ Object
- #^(other) ⇒ Object
- #amount ⇒ Object
- #amount=(value) ⇒ Object
-
#as_json(options = nil) ⇒ Object
For better json decoding.
- #convert(value, this_precision = precision, this_round_mode = round_mode) ⇒ Object
- #credit? ⇒ Boolean
- #debit? ⇒ Boolean
- #eql?(other) ⇒ Boolean
- #format ⇒ Object
- #format=(value) ⇒ Object
- #formatted(*args) ⇒ Object
-
#initialize(value, precision = nil, round_mode = nil, format = nil) ⇒ Money
constructor
A new instance of Money.
- #method_missing(meth, *args, &blk) ⇒ Object
- #precision ⇒ Object
- #precision=(value) ⇒ Object
-
#quoted_id ⇒ Object
Terrible hack to allow to quote money correctly.
- #respond_to?(meth) ⇒ Boolean
- #round(this_precision = precision, this_round_mode = round_mode) ⇒ Object
- #round_amount(this_precision = precision, this_round_mode = round_mode) ⇒ Object
- #round_mode ⇒ Object
- #round_mode=(value) ⇒ Object
- #to_big_decimal ⇒ Object
- #to_credit ⇒ Object
- #to_credit! ⇒ Object
-
#to_d ⇒ Object
This will help to save money objects correctly.
- #to_debit ⇒ Object
- #to_debit! ⇒ Object
- #to_f(this_precision = precision, this_round_mode = round_mode) ⇒ Object
- #to_i(this_round_mode = round_mode) ⇒ Object
- #to_json(options = nil) ⇒ Object
- #to_money ⇒ Object
- #to_s(this_precision = precision, this_round_mode = round_mode) ⇒ Object (also: #inspect)
- #to_yaml(options = { }) ⇒ Object
- #to_yaml_type ⇒ Object
- #zero? ⇒ Boolean
Constructor Details
#initialize(value, precision = nil, round_mode = nil, format = nil) ⇒ Money
Returns a new instance of Money.
34 35 36 37 38 39 |
# File 'lib/bd_money/bd_money.rb', line 34 def initialize(value, precision = nil, round_mode = nil, format = nil) self.amount = value self.precision = precision if precision self.round_mode = round_mode if round_mode self.format = format if format end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(meth, *args, &blk) ⇒ Object
226 227 228 229 230 231 232 233 |
# File 'lib/bd_money/bd_money.rb', line 226 def method_missing(meth, *args, &blk) if amount.respond_to? meth result = amount.send meth, *args, &blk result.is_a?(::BigDecimal) ? convert(result) : result else super end end |
Class Method Details
.[](value) ⇒ Object
295 296 297 |
# File 'lib/bd_money/bd_money.rb', line 295 def [](value) new value end |
.clean(value) ⇒ Object
283 284 285 |
# File 'lib/bd_money/bd_money.rb', line 283 def clean(value) value.to_s.gsub REMOVE_RE, '' end |
.convert(value, precision = nil, round_mode = nil) ⇒ Object
279 280 281 |
# File 'lib/bd_money/bd_money.rb', line 279 def convert(value, precision = nil, round_mode = nil) new value, precision, round_mode end |
.format ⇒ Object
275 276 277 |
# File 'lib/bd_money/bd_money.rb', line 275 def format @format || :default end |
.format=(value) ⇒ Object
270 271 272 273 |
# File 'lib/bd_money/bd_money.rb', line 270 def format=(value) raise "Unknown format options [#{value}]" unless FORMATS.key?(value) @format = value end |
.precision ⇒ Object
257 258 259 |
# File 'lib/bd_money/bd_money.rb', line 257 def precision @precision || 2 end |
.precision=(value) ⇒ Object
252 253 254 255 |
# File 'lib/bd_money/bd_money.rb', line 252 def precision=(value) raise "Unknown precision [#{value}]" unless value.is_a?(Integer) @precision = value end |
.round_mode ⇒ Object
266 267 268 |
# File 'lib/bd_money/bd_money.rb', line 266 def round_mode @round_mode || :half_up end |
.round_mode=(value) ⇒ Object
261 262 263 264 |
# File 'lib/bd_money/bd_money.rb', line 261 def round_mode=(value) raise "Unknown rounding mode [#{value}]" unless ROUND_MODES.key?(value) @round_mode = value end |
.valid?(value) ⇒ Boolean
287 288 289 |
# File 'lib/bd_money/bd_money.rb', line 287 def valid?(value) !!value.to_s.match(VALID_RE) end |
.zero ⇒ Object
291 292 293 |
# File 'lib/bd_money/bd_money.rb', line 291 def zero new 0 end |
Instance Method Details
#%(other) ⇒ Object
116 117 118 |
# File 'lib/bd_money/bd_money.rb', line 116 def %(other) convert amount % convert(other).amount end |
#*(other) ⇒ Object
104 105 106 |
# File 'lib/bd_money/bd_money.rb', line 104 def *(other) convert amount * convert(other).amount end |
#**(other) ⇒ Object
112 113 114 |
# File 'lib/bd_money/bd_money.rb', line 112 def **(other) convert amount ** convert(other).amount.to_i end |
#+(other) ⇒ Object
96 97 98 |
# File 'lib/bd_money/bd_money.rb', line 96 def +(other) convert amount + convert(other).amount end |
#-(other) ⇒ Object
100 101 102 |
# File 'lib/bd_money/bd_money.rb', line 100 def -(other) convert amount - convert(other).amount end |
#/(other) ⇒ Object
108 109 110 |
# File 'lib/bd_money/bd_money.rb', line 108 def /(other) convert amount / convert(other).amount end |
#<=>(other) ⇒ Object
92 93 94 |
# File 'lib/bd_money/bd_money.rb', line 92 def <=>(other) amount <=> convert(other).amount end |
#^(other) ⇒ Object
120 121 122 |
# File 'lib/bd_money/bd_money.rb', line 120 def ^(other) convert amount ^ convert(other).amount end |
#amount ⇒ Object
53 54 55 |
# File 'lib/bd_money/bd_money.rb', line 53 def amount @amount end |
#amount=(value) ⇒ Object
41 42 43 44 45 46 47 48 49 50 51 |
# File 'lib/bd_money/bd_money.rb', line 41 def amount=(value) if value.respond_to?(:to_big_decimal) @amount = value.to_big_decimal elsif value.is_a?(BigDecimal) @amount = value else str = self.class.clean value raise MoneyError, "Invalid value [#{str}] (#{value.class.name})" unless self.class.valid?(str) @amount = BigDecimal.new str.gsub REMOVE_RE, '' end end |
#as_json(options = nil) ⇒ Object
For better json decoding
16 17 18 |
# File 'lib/bd_money/rails.rb', line 16 def as_json( = nil) to_s end |
#convert(value, this_precision = precision, this_round_mode = round_mode) ⇒ Object
84 85 86 |
# File 'lib/bd_money/bd_money.rb', line 84 def convert(value, this_precision = precision, this_round_mode = round_mode) self.class.convert value, this_precision, this_round_mode end |
#credit? ⇒ Boolean
133 134 135 |
# File 'lib/bd_money/bd_money.rb', line 133 def credit? amount >= 0 end |
#debit? ⇒ Boolean
146 147 148 |
# File 'lib/bd_money/bd_money.rb', line 146 def debit? amount < 0 end |
#eql?(other) ⇒ Boolean
88 89 90 |
# File 'lib/bd_money/bd_money.rb', line 88 def eql?(other) amount == convert(other).amount end |
#format ⇒ Object
80 81 82 |
# File 'lib/bd_money/bd_money.rb', line 80 def format @format || self.class.format end |
#format=(value) ⇒ Object
75 76 77 78 |
# File 'lib/bd_money/bd_money.rb', line 75 def format=(value) raise "Unknown format options [#{value}]" unless FORMATS.key?(value) @format = value end |
#formatted(*args) ⇒ Object
197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 |
# File 'lib/bd_money/bd_money.rb', line 197 def formatted(*args) defaults = args.first.is_a?(::Symbol) ? FORMATS[args.shift] : FORMATS[:default] = args.last.is_a?(::Hash) ? args.pop : { } unit = [:unit] || defaults[:unit] spacer = [:spacer] || defaults[:spacer] spacer = '' if unit.to_s.empty? delimiter = [:delimiter] || defaults[:delimiter] separator = [:separator] || defaults[:separator] separator = '' if precision == 0 precision = [:precision] || defaults[:precision] last = [:last] || defaults[:last] number = to_s precision return number if number == 'NaN' begin parts = number.to_s.split('.') parts[0].gsub!(/(\d)(?=(\d\d\d)+(?!\d))/, "\\1#{delimiter}") number = parts.join(separator) "#{unit}#{spacer}#{number}#{last}" rescue number end end |
#precision ⇒ Object
62 63 64 |
# File 'lib/bd_money/bd_money.rb', line 62 def precision @precision || self.class.precision end |
#precision=(value) ⇒ Object
57 58 59 60 |
# File 'lib/bd_money/bd_money.rb', line 57 def precision=(value) raise "Unknown precision [#{value}]" unless value.is_a?(Integer) @precision = value end |
#quoted_id ⇒ Object
Terrible hack to allow to quote money correctly
6 7 8 |
# File 'lib/bd_money/rails.rb', line 6 def quoted_id amount end |
#respond_to?(meth) ⇒ Boolean
222 223 224 |
# File 'lib/bd_money/bd_money.rb', line 222 def respond_to?(meth) amount.respond_to?(meth) || super end |
#round(this_precision = precision, this_round_mode = round_mode) ⇒ Object
167 168 169 |
# File 'lib/bd_money/bd_money.rb', line 167 def round(this_precision = precision, this_round_mode = round_mode) convert round_amount(this_precision, this_round_mode) end |
#round_amount(this_precision = precision, this_round_mode = round_mode) ⇒ Object
162 163 164 165 |
# File 'lib/bd_money/bd_money.rb', line 162 def round_amount(this_precision = precision, this_round_mode = round_mode) this_round_mode = BigDecimal.const_get("ROUND_#{this_round_mode.to_s.upcase}") if this_round_mode.is_a?(Symbol) amount.round this_precision, this_round_mode end |
#round_mode ⇒ Object
71 72 73 |
# File 'lib/bd_money/bd_money.rb', line 71 def round_mode @round_mode || self.class.round_mode end |
#round_mode=(value) ⇒ Object
66 67 68 69 |
# File 'lib/bd_money/bd_money.rb', line 66 def round_mode=(value) raise "Unknown rounding mode [#{value}]" unless ROUND_MODES.key?(value) @round_mode = value end |
#to_big_decimal ⇒ Object
158 159 160 |
# File 'lib/bd_money/bd_money.rb', line 158 def to_big_decimal amount end |
#to_credit ⇒ Object
124 125 126 |
# File 'lib/bd_money/bd_money.rb', line 124 def to_credit convert amount.abs end |
#to_credit! ⇒ Object
128 129 130 131 |
# File 'lib/bd_money/bd_money.rb', line 128 def to_credit! self.amount = amount.abs self end |
#to_d ⇒ Object
This will help to save money objects correctly
11 12 13 |
# File 'lib/bd_money/rails.rb', line 11 def to_d amount end |
#to_debit ⇒ Object
137 138 139 |
# File 'lib/bd_money/bd_money.rb', line 137 def to_debit convert amount.abs * -1 end |
#to_debit! ⇒ Object
141 142 143 144 |
# File 'lib/bd_money/bd_money.rb', line 141 def to_debit! self.amount = amount.abs * -1 self end |
#to_f(this_precision = precision, this_round_mode = round_mode) ⇒ Object
175 176 177 |
# File 'lib/bd_money/bd_money.rb', line 175 def to_f(this_precision = precision, this_round_mode = round_mode) round_amount(this_precision, this_round_mode).to_f end |
#to_i(this_round_mode = round_mode) ⇒ Object
171 172 173 |
# File 'lib/bd_money/bd_money.rb', line 171 def to_i(this_round_mode = round_mode) round_amount(0, this_round_mode).to_i end |
#to_json(options = nil) ⇒ Object
193 194 195 |
# File 'lib/bd_money/bd_money.rb', line 193 def to_json( = nil) to_s end |
#to_money ⇒ Object
154 155 156 |
# File 'lib/bd_money/bd_money.rb', line 154 def to_money self end |
#to_s(this_precision = precision, this_round_mode = round_mode) ⇒ Object Also known as: inspect
179 180 181 182 183 184 185 186 187 188 189 |
# File 'lib/bd_money/bd_money.rb', line 179 def to_s(this_precision = precision, this_round_mode = round_mode) amount_str = round_amount(this_precision, this_round_mode).to_s('F') return amount_str if amount_str == "NaN" dollars, cents = amount_str.split('.') return dollars if this_precision == 0 || cents.nil? if cents.size >= this_precision "#{dollars}.#{cents[0, this_precision]}" else "#{dollars}.#{cents}#{'0' * (this_precision - cents.size)}" end end |
#to_yaml(options = { }) ⇒ Object
239 240 241 242 243 244 245 246 247 248 |
# File 'lib/bd_money/bd_money.rb', line 239 def to_yaml( = { }) YAML.quick_emit(self.object_id, ) do |out| out.map(taguri, to_yaml_style) do |map| map.add 'amount', amount.to_s('F') map.add 'precision', @precision unless @precision.nil? map.add 'round_mode', @round_mode unless @round_mode.nil? map.add 'format', @format unless @format.nil? end end end |
#to_yaml_type ⇒ Object
235 236 237 |
# File 'lib/bd_money/bd_money.rb', line 235 def to_yaml_type "!#{YAML_TYPE_ROOT}/#{YAML_TYPE_NAME}" end |
#zero? ⇒ Boolean
150 151 152 |
# File 'lib/bd_money/bd_money.rb', line 150 def zero? amount == 0 end |