brdinheiro-lite 0.0.1
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.
- data/CHANGELOG +1 -0
- data/MIT-LICENSE +20 -0
- data/README +3 -0
- data/Rakefile +66 -0
- data/lib/brdinheiro_lite/dinheiro.rb +286 -0
- data/lib/brdinheiro_lite/dinheiro_util.rb +51 -0
- data/lib/brdinheiro_lite/excecoes.rb +13 -0
- data/lib/brdinheiro_lite/extenso.rb +101 -0
- data/lib/brdinheiro_lite/extenso_real.rb +60 -0
- data/lib/brdinheiro_lite/nil_class.rb +24 -0
- data/lib/brdinheiro_lite/version.rb +9 -0
- data/lib/brdinheiro_lite.rb +19 -0
- data/test/dinheiro_test.rb +496 -0
- data/test/extenso_test.rb +356 -0
- data/test/nil_class_test.rb +29 -0
- data/test/test_helper.rb +22 -0
- metadata +74 -0
data/CHANGELOG
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
Version 0.0.1 -> Versão alpha da gem.
|
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2008 [name of plugin creator]
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README
ADDED
data/Rakefile
ADDED
@@ -0,0 +1,66 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'rake'
|
5
|
+
require 'rake/testtask'
|
6
|
+
require 'rake/rdoctask'
|
7
|
+
require 'rake/packagetask'
|
8
|
+
require 'rake/gempackagetask'
|
9
|
+
|
10
|
+
require File.join(File.dirname(__FILE__), 'lib', 'brdinheiro_lite', 'version')
|
11
|
+
|
12
|
+
PKG_BUILD = ENV['PKG_BUILD'] ? '.' + ENV['PKG_BUILD'] : ''
|
13
|
+
PKG_NAME = 'brdinheiro-lite'
|
14
|
+
PKG_VERSION = BrDinheiro::VERSION::STRING + PKG_BUILD
|
15
|
+
PKG_FILE_NAME = "#{PKG_NAME}-#{PKG_VERSION}"
|
16
|
+
|
17
|
+
RELEASE_NAME = "REL #{PKG_VERSION}"
|
18
|
+
|
19
|
+
desc "Default Task"
|
20
|
+
task :default => [ :test ]
|
21
|
+
|
22
|
+
# Run the unit tests
|
23
|
+
Rake::TestTask.new { |t|
|
24
|
+
t.libs << "test"
|
25
|
+
t.pattern = 'test/*_test.rb'
|
26
|
+
t.verbose = true
|
27
|
+
t.warning = false
|
28
|
+
}
|
29
|
+
|
30
|
+
#Generate the RDoc documentation
|
31
|
+
Rake::RDocTask.new { |rdoc|
|
32
|
+
rdoc.rdoc_dir = 'doc'
|
33
|
+
rdoc.title = "brdinheiro-lite"
|
34
|
+
rdoc.options << '--line-numbers' << '--inline-source' << '-A cattr_accessor=object'
|
35
|
+
rdoc.options << '--charset' << 'utf-8'
|
36
|
+
rdoc.template = "#{ENV['template']}.rb" if ENV['template']
|
37
|
+
rdoc.rdoc_files.include('README', 'CHANGELOG')
|
38
|
+
rdoc.rdoc_files.include('lib/**/*')
|
39
|
+
}
|
40
|
+
|
41
|
+
# Create compressed packages
|
42
|
+
spec = Gem::Specification.new do |s|
|
43
|
+
s.platform = Gem::Platform::RUBY
|
44
|
+
s.name = PKG_NAME
|
45
|
+
s.summary = "brdinheiro-lite é uma versão simplificada da gem brdinheiro do Brazilian Rails"
|
46
|
+
s.description = %q{brdinheiro-lite é uma versão simplificada da gem brdinheiro do Brazilian Rails}
|
47
|
+
s.version = PKG_VERSION
|
48
|
+
|
49
|
+
s.authors = ["Marcos Tapajós", "Celestino Gomes", "Andre Kupkosvki", "Vinícius Teles", "Rafael Souza"]
|
50
|
+
s.email = "me@rafaelss.com"
|
51
|
+
s.rubyforge_project = "brdinheiro-lite"
|
52
|
+
s.homepage = "http://rafaelss.com/brdinheiro-lite"
|
53
|
+
|
54
|
+
s.has_rdoc = true
|
55
|
+
s.require_path = 'lib'
|
56
|
+
|
57
|
+
s.files = [ "Rakefile", "README", "CHANGELOG", "MIT-LICENSE" ]
|
58
|
+
s.files = s.files + Dir.glob( "lib/**/*" ).delete_if { |item| item.include?( "\.svn" ) }
|
59
|
+
s.files = s.files + Dir.glob( "test/**/*" ).delete_if { |item| item.include?( "\.svn" ) }
|
60
|
+
end
|
61
|
+
|
62
|
+
Rake::GemPackageTask.new(spec) do |p|
|
63
|
+
p.gem_spec = spec
|
64
|
+
p.need_tar = true
|
65
|
+
p.need_zip = true
|
66
|
+
end
|
@@ -0,0 +1,286 @@
|
|
1
|
+
class Dinheiro
|
2
|
+
include Comparable
|
3
|
+
|
4
|
+
attr_reader :quantia
|
5
|
+
|
6
|
+
FORMATO_VALIDO_BR = /^([R|r]\$\s*)?(([+-]?\d{1,3}(\.?\d{3})*))?(\,\d{0,2})?$/
|
7
|
+
FORMATO_VALIDO_EUA = /^([R|r]\$\s*)?(([+-]?\d{1,3}(\,?\d{3})*))?(\.\d{0,2})?$/
|
8
|
+
SEPARADOR_MILHAR = "."
|
9
|
+
SEPARADOR_FRACIONARIO = ","
|
10
|
+
QUANTIDADE_DIGITOS = 3
|
11
|
+
PRECISAO_DECIMAL = 100
|
12
|
+
|
13
|
+
def initialize(quantia)
|
14
|
+
self.quantia = quantia
|
15
|
+
end
|
16
|
+
|
17
|
+
# Retorna o valor armazenado em string.
|
18
|
+
#
|
19
|
+
# Exemplo:
|
20
|
+
# 1000.to_s ==> '1.000,00'
|
21
|
+
def to_s
|
22
|
+
inteiro_com_milhar(parte_inteira) + parte_decimal
|
23
|
+
end
|
24
|
+
|
25
|
+
# Compara com outro dinheiro se eh igual.
|
26
|
+
#
|
27
|
+
# Exemplo:
|
28
|
+
# um_real = Dinheiro.new(1)
|
29
|
+
# um_real == Dinheiro.new(1) ==> true
|
30
|
+
# um_real == Dinheiro.new(2) ==> false
|
31
|
+
def ==(outro_dinheiro)
|
32
|
+
begin
|
33
|
+
outro_dinheiro = Dinheiro.new(outro_dinheiro) unless outro_dinheiro.kind_of?(Dinheiro)
|
34
|
+
rescue
|
35
|
+
return false
|
36
|
+
end
|
37
|
+
@quantia == outro_dinheiro.quantia
|
38
|
+
end
|
39
|
+
|
40
|
+
# Compara com outro dinheiro se eh maior ou menor.
|
41
|
+
#
|
42
|
+
# Exemplo:
|
43
|
+
# 1.real < 2.reais ==> true
|
44
|
+
# 1.real > 2.reais ==> false
|
45
|
+
# 2.real < 1.reais ==> false
|
46
|
+
# 2.real > 1.reais ==> true
|
47
|
+
def <=>(outro_dinheiro)
|
48
|
+
outro_dinheiro = Dinheiro.new(outro_dinheiro) unless outro_dinheiro.kind_of?(Dinheiro)
|
49
|
+
@quantia <=> outro_dinheiro.quantia
|
50
|
+
end
|
51
|
+
|
52
|
+
# Retorna a adicao entre dinheiros.
|
53
|
+
#
|
54
|
+
# Exemplo:
|
55
|
+
# 1.real + 1.real == 2.reais
|
56
|
+
# 1.real + 1 == 2.reais
|
57
|
+
def +(outro)
|
58
|
+
Dinheiro.new(transforma_em_string_que_represente_a_quantia(@quantia + quantia_de(outro)))
|
59
|
+
end
|
60
|
+
|
61
|
+
# Retorna a subtracao entre dinheiros.
|
62
|
+
#
|
63
|
+
# Exemplo:
|
64
|
+
# 10.reais - 2.reais == 8.reais
|
65
|
+
# 10.reais - 2 == 8.reais
|
66
|
+
def -(outro)
|
67
|
+
Dinheiro.new(transforma_em_string_que_represente_a_quantia(@quantia - quantia_de(outro)))
|
68
|
+
end
|
69
|
+
|
70
|
+
# Retorna a multiplicacao entre dinheiros.
|
71
|
+
#
|
72
|
+
# Exemplo:
|
73
|
+
# 5.reais * 2 == 10.reais
|
74
|
+
# 5.reais * 2.reais == 10.reais
|
75
|
+
def *(outro)
|
76
|
+
return Dinheiro.new(to_f * outro) unless outro.kind_of? Dinheiro
|
77
|
+
outro * to_f
|
78
|
+
end
|
79
|
+
|
80
|
+
# Retorna a divisao entre dinheiros.
|
81
|
+
#
|
82
|
+
# Exemplo:
|
83
|
+
# 5.reais / 2 == (2.5).reais
|
84
|
+
# 5.reais / 2.reais == DivisaPorNaoEscalarError
|
85
|
+
# 5.reais / 0 == ZeroDivisionError
|
86
|
+
#
|
87
|
+
# Veja também o método parcelar
|
88
|
+
def /(outro)
|
89
|
+
raise DivisaPorNaoEscalarError unless outro.kind_of?(Numeric)
|
90
|
+
return @quantia/outro if outro == 0
|
91
|
+
Dinheiro.new(to_f / outro.to_f)
|
92
|
+
end
|
93
|
+
|
94
|
+
# Retorna um array de dinheiro com as parcelas
|
95
|
+
#
|
96
|
+
# Exemplo:
|
97
|
+
# 6.reais.parcelar(2) == [3.reais, 3.reais]
|
98
|
+
# 6.reais.parcelar(2.reais) == DisivaPorNaoEscalarError
|
99
|
+
# 6.reais.parcelar(0) == ZeroDivisionError
|
100
|
+
def parcelar(numero_de_parcelar)
|
101
|
+
raise DivisaPorNaoEscalarError unless numero_de_parcelar.kind_of?(Integer)
|
102
|
+
resto = @quantia % numero_de_parcelar
|
103
|
+
valor_menor = Dinheiro.new((@quantia/numero_de_parcelar)/100.0)
|
104
|
+
valor_maior = Dinheiro.new((@quantia/numero_de_parcelar+1)/100.0)
|
105
|
+
[valor_menor] * (numero_de_parcelar - resto) + [valor_maior] * resto
|
106
|
+
end
|
107
|
+
|
108
|
+
# Escreve o valor por extenso.
|
109
|
+
#
|
110
|
+
# Exemplo:
|
111
|
+
# 1.real.to_extenso ==> 'um real'
|
112
|
+
# (100.58).to_extenso ==> 'cem reais e cinquenta e oito centavos'
|
113
|
+
def to_extenso
|
114
|
+
(@quantia/100.0).por_extenso_em_reais
|
115
|
+
end
|
116
|
+
|
117
|
+
# Alias para o metodo to_extenso.
|
118
|
+
alias_method :por_extenso, :to_extenso
|
119
|
+
|
120
|
+
# Alias para o metodo to_extenso.
|
121
|
+
alias_method :por_extenso_em_reais, :to_extenso
|
122
|
+
|
123
|
+
# Verifica se o valor é zero.
|
124
|
+
def zero?
|
125
|
+
to_f.zero?
|
126
|
+
end
|
127
|
+
|
128
|
+
# Retorna um Float.
|
129
|
+
def to_f
|
130
|
+
to_s.gsub('.', '').gsub(',', '.').to_f
|
131
|
+
end
|
132
|
+
|
133
|
+
def coerce(outro)#:nodoc:
|
134
|
+
[ Dinheiro.new(outro), self ]
|
135
|
+
end
|
136
|
+
|
137
|
+
# Retorna a própria instância/
|
138
|
+
def real
|
139
|
+
self
|
140
|
+
end
|
141
|
+
|
142
|
+
# Alias para real.
|
143
|
+
alias_method :reais, :real
|
144
|
+
|
145
|
+
# Retorna uma string formatada com sigla em valor monetário.
|
146
|
+
# Exemplo:
|
147
|
+
# Dinheiro.new(1).real_formatado ==> 'R$ 1,00'
|
148
|
+
# Dinheiro.new(-1).real_formatado ==> 'R$ -1,00'
|
149
|
+
def real_formatado
|
150
|
+
"R$ #{to_s}"
|
151
|
+
end
|
152
|
+
|
153
|
+
# Alias para real_formatado.
|
154
|
+
alias_method :reais_formatado, :real_formatado
|
155
|
+
|
156
|
+
# Retorna uma string formatada com sigla em valor contábil.
|
157
|
+
#
|
158
|
+
# Exemplo:
|
159
|
+
# Dinheiro.new(1).real_contabil ==> 'R$ 1,00'
|
160
|
+
# Dinheiro.new(-1).real_contabil ==> 'R$ (1,00)'
|
161
|
+
def real_contabil
|
162
|
+
"R$ " + contabil
|
163
|
+
end
|
164
|
+
|
165
|
+
# Alias para real_contabil.
|
166
|
+
alias_method :reais_contabeis, :real_contabil
|
167
|
+
|
168
|
+
# Retorna uma string formatada sem sigla.
|
169
|
+
#
|
170
|
+
# Exemplo:
|
171
|
+
# Dinheiro.new(1).contabil ==> '1,00'
|
172
|
+
# Dinheiro.new(-1).contabil ==> '(1,00)'
|
173
|
+
def contabil
|
174
|
+
if @quantia >= 0
|
175
|
+
to_s
|
176
|
+
else
|
177
|
+
"(" + to_s[1..-1] + ")"
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
# Method missing para retorna um BigDecinal quando chamada .
|
182
|
+
def method_missing(symbol, *args) #:nodoc:
|
183
|
+
#Ex: Chama ao método valor_decimal()
|
184
|
+
if (symbol.to_s =~ /^(.*)_decimal$/) && args.size == 0
|
185
|
+
BigDecimal.new quantia_sem_separacao_milhares.gsub(',','.')
|
186
|
+
else
|
187
|
+
super.method_missing(symbol, *args)
|
188
|
+
end
|
189
|
+
end
|
190
|
+
|
191
|
+
private
|
192
|
+
def quantia_de(outro)
|
193
|
+
outro = outro.to_f if outro.kind_of?(BigDecimal)
|
194
|
+
return outro.quantia if outro.kind_of?(Dinheiro)
|
195
|
+
(outro * 100).round
|
196
|
+
end
|
197
|
+
|
198
|
+
def transforma_em_string_que_represente_a_quantia(quantia)
|
199
|
+
if /^([+-]?)(\d)$/ =~ quantia.to_s
|
200
|
+
return "#{$1}0.0#{$2}"
|
201
|
+
end
|
202
|
+
/^([+-]?)(\d*)(\d\d)$/ =~ quantia.to_s
|
203
|
+
"#{$1}#{$2.to_i}.#{$3}"
|
204
|
+
end
|
205
|
+
|
206
|
+
def quantia=(quantia)
|
207
|
+
raise DinheiroInvalidoError unless quantia_valida?(quantia)
|
208
|
+
quantia = quantia.to_f if quantia.kind_of?(BigDecimal)
|
209
|
+
@quantia = (quantia * 100).round if quantia.kind_of?(Numeric)
|
210
|
+
@quantia = extrai_quantia_como_inteiro(quantia) if quantia.kind_of?(String)
|
211
|
+
end
|
212
|
+
|
213
|
+
def parte_inteira
|
214
|
+
quantia_sem_separacao_milhares[0,quantia_sem_separacao_milhares.length-QUANTIDADE_DIGITOS]
|
215
|
+
end
|
216
|
+
|
217
|
+
def parte_decimal
|
218
|
+
quantia_sem_separacao_milhares[-QUANTIDADE_DIGITOS, QUANTIDADE_DIGITOS]
|
219
|
+
end
|
220
|
+
|
221
|
+
def inteiro_com_milhar(inteiro)
|
222
|
+
return inteiro if quantidade_de_passos(inteiro) == 0
|
223
|
+
resultado = ""
|
224
|
+
quantidade_de_passos(inteiro).times do |passo|
|
225
|
+
resultado = "." + inteiro[-QUANTIDADE_DIGITOS + passo * -QUANTIDADE_DIGITOS, QUANTIDADE_DIGITOS] + resultado
|
226
|
+
end
|
227
|
+
resultado = inteiro[0, digitos_que_sobraram(inteiro)] + resultado
|
228
|
+
resultado.gsub(/^(-?)\./, '\1')
|
229
|
+
end
|
230
|
+
|
231
|
+
def quantia_sem_separacao_milhares
|
232
|
+
sprintf("%.2f", (@quantia.to_f / PRECISAO_DECIMAL)).gsub(SEPARADOR_MILHAR, SEPARADOR_FRACIONARIO)
|
233
|
+
end
|
234
|
+
|
235
|
+
def quantidade_de_passos(inteiro)
|
236
|
+
resultado = inteiro.length / QUANTIDADE_DIGITOS
|
237
|
+
resultado = (resultado - 1) if inteiro.length % QUANTIDADE_DIGITOS == 0
|
238
|
+
resultado
|
239
|
+
end
|
240
|
+
|
241
|
+
def digitos_que_sobraram(inteiro)
|
242
|
+
inteiro.length - (quantidade_de_passos(inteiro) * QUANTIDADE_DIGITOS)
|
243
|
+
end
|
244
|
+
|
245
|
+
def quantia_valida?(quantia)
|
246
|
+
return false if quantia.kind_of?(String) && !quantia_respeita_formato?(quantia)
|
247
|
+
quantia.kind_of?(String) || quantia.kind_of?(Numeric)
|
248
|
+
end
|
249
|
+
|
250
|
+
def extrai_quantia_como_inteiro(quantia)
|
251
|
+
if FORMATO_VALIDO_BR =~ quantia
|
252
|
+
return sem_milhar($2, $5, '.')
|
253
|
+
end
|
254
|
+
if FORMATO_VALIDO_EUA =~ quantia
|
255
|
+
return sem_milhar($2, $5, ',')
|
256
|
+
end
|
257
|
+
end
|
258
|
+
|
259
|
+
def sem_milhar(parte_inteira, parte_decimal, delimitador_de_milhar)
|
260
|
+
(inteiro(parte_inteira, delimitador_de_milhar) + decimal(parte_decimal)).to_i
|
261
|
+
end
|
262
|
+
|
263
|
+
def inteiro(inteiro_com_separador_milhar, separador)
|
264
|
+
return inteiro_com_separador_milhar.gsub(separador, '') unless inteiro_com_separador_milhar.blank?
|
265
|
+
""
|
266
|
+
end
|
267
|
+
|
268
|
+
def decimal(parte_fracionaria)
|
269
|
+
unless parte_fracionaria.blank?
|
270
|
+
return sem_delimitador_decimal(parte_fracionaria) if parte_fracionaria.length == 3
|
271
|
+
return sem_delimitador_decimal(parte_fracionaria) + "0" if parte_fracionaria.length == 2
|
272
|
+
end
|
273
|
+
"00"
|
274
|
+
end
|
275
|
+
|
276
|
+
def sem_delimitador_decimal(parte_fracionaria)
|
277
|
+
"#{parte_fracionaria}".gsub(/[.|,]/, '')
|
278
|
+
end
|
279
|
+
|
280
|
+
|
281
|
+
def quantia_respeita_formato?(quantia)
|
282
|
+
return true if FORMATO_VALIDO_BR.match(quantia) || FORMATO_VALIDO_EUA.match(quantia)
|
283
|
+
false
|
284
|
+
end
|
285
|
+
|
286
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module DinheiroUtil
|
2
|
+
|
3
|
+
# Ao incluir o modulo, cria aliases para_dinheiro
|
4
|
+
def self.included(base)
|
5
|
+
base.class_eval do
|
6
|
+
# Alias para para_dinheiro
|
7
|
+
alias_method :real, :para_dinheiro
|
8
|
+
|
9
|
+
# Alias para para_dinheiro
|
10
|
+
alias_method :reais, :para_dinheiro
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
# Transforma numero em dinheiro
|
15
|
+
#
|
16
|
+
# Exemplo:
|
17
|
+
# 1.para_dinheiro.class ==> Dinheiro
|
18
|
+
def para_dinheiro
|
19
|
+
Dinheiro.new(self)
|
20
|
+
end
|
21
|
+
|
22
|
+
# Retorna string formatada com simbolo monetario
|
23
|
+
#
|
24
|
+
# Exemplo:
|
25
|
+
# 1.real_contabil ==> 'R$ 1,00'
|
26
|
+
# -1.real_contabil ==> 'R$ (1,00)'
|
27
|
+
def real_contabil
|
28
|
+
Dinheiro.new(self).real_contabil
|
29
|
+
end
|
30
|
+
|
31
|
+
# Retorna string formatada com simbolo monetario
|
32
|
+
#
|
33
|
+
# Exemplo:
|
34
|
+
# 2.reais_contabeis ==> 'R$ 2,00'
|
35
|
+
# -2.reais_contabeis ==> 'R$ 2,00'
|
36
|
+
def reais_contabeis
|
37
|
+
Dinheiro.new(self).reais_contabeis
|
38
|
+
end
|
39
|
+
|
40
|
+
# Retorna string formatada com simbolo monetario
|
41
|
+
#
|
42
|
+
# Exemplo:
|
43
|
+
# 1.contabil ==> '1,00'
|
44
|
+
# -1.contabil ==> '(1,00)'
|
45
|
+
def contabil
|
46
|
+
Dinheiro.new(self).contabil
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
Numeric.send(:include, DinheiroUtil)
|
51
|
+
String.send(:include, DinheiroUtil)
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
class DinheiroInvalidoError < ArgumentError
|
4
|
+
def initialize
|
5
|
+
super('O valor deve estar preenchido e no formato correto. Ex.: 100.00 .')
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
class DivisaPorNaoEscalarError < ArgumentError
|
10
|
+
def initialize
|
11
|
+
super('Só é possível dividir dinheiro por numeros.')
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,101 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
module Extenso
|
3
|
+
@@unidade = {
|
4
|
+
0 => "zero",
|
5
|
+
1 => "um",
|
6
|
+
2 => "dois",
|
7
|
+
3 => "três",
|
8
|
+
4 => "quatro",
|
9
|
+
5 => "cinco",
|
10
|
+
6 => "seis",
|
11
|
+
7 => "sete",
|
12
|
+
8 => "oito",
|
13
|
+
9 => "nove"
|
14
|
+
}
|
15
|
+
@@dezena = {
|
16
|
+
10 => "dez",
|
17
|
+
11 => "onze",
|
18
|
+
12 => "doze",
|
19
|
+
13 => "treze",
|
20
|
+
14 => "quatorze",
|
21
|
+
15 => "quinze",
|
22
|
+
16 => "dezesseis",
|
23
|
+
17 => "dezessete",
|
24
|
+
18 => "dezoito",
|
25
|
+
19 => "dezenove",
|
26
|
+
20 => "vinte",
|
27
|
+
30 => "trinta",
|
28
|
+
40 => "quarenta",
|
29
|
+
50 => "cinquenta",
|
30
|
+
60 => "sessenta",
|
31
|
+
70 => "setenta",
|
32
|
+
80 => "oitenta",
|
33
|
+
90 => "noventa" }
|
34
|
+
@@centena = {100 => "cento",
|
35
|
+
200 => "duzentos",
|
36
|
+
300 => "trezentos",
|
37
|
+
400 => "quatrocentos",
|
38
|
+
500 => "quinhentos",
|
39
|
+
600 => "seiscentos",
|
40
|
+
700 => "setecentos",
|
41
|
+
800 => "oitocentos",
|
42
|
+
900 => "novecentos" }
|
43
|
+
|
44
|
+
# Escreve o numero por extenso.
|
45
|
+
#
|
46
|
+
# Exemplo:
|
47
|
+
# 1.por_extenso ==> 'um'
|
48
|
+
# 100.por_extenso ==> 'cem'
|
49
|
+
# 158.por_extenso ==> 'cento e cinquenta e oito'
|
50
|
+
def por_extenso
|
51
|
+
Extenso.por_extenso(self)
|
52
|
+
end
|
53
|
+
|
54
|
+
# Alias para o metodo por_extenso
|
55
|
+
alias_method :to_extenso, :por_extenso
|
56
|
+
|
57
|
+
# Escreve o numero por extenso.
|
58
|
+
#
|
59
|
+
# Exemplo:
|
60
|
+
# Extenso.por_extenso(1) ==> "um"
|
61
|
+
# Extenso.por_extenso(100) ==> "cem"
|
62
|
+
# Extenso.por_extenso(158) ==> "cento e cinquenta e oito"
|
63
|
+
def Extenso.por_extenso(numero)
|
64
|
+
negativo=(numero<0)? "menos " : ""
|
65
|
+
n=numero.to_i.abs
|
66
|
+
return case n
|
67
|
+
when 0..9 then negativo + @@unidade[n].to_s
|
68
|
+
when 10..19 then negativo + @@dezena[n].to_s
|
69
|
+
when 20..99
|
70
|
+
v=n % 10
|
71
|
+
if v== 0
|
72
|
+
negativo + @@dezena[n].to_s
|
73
|
+
else
|
74
|
+
"#{negativo}#{@@dezena[n-v]} e #{por_extenso(v)}"
|
75
|
+
end
|
76
|
+
when 100
|
77
|
+
negativo+"cem"
|
78
|
+
when 101..999
|
79
|
+
v=n % 100
|
80
|
+
if v== 0
|
81
|
+
negativo + @@centena[n].to_s
|
82
|
+
else
|
83
|
+
"#{negativo}#{@@centena[n-v]} e #{por_extenso(v)}"
|
84
|
+
end
|
85
|
+
when 1000..999999
|
86
|
+
m,c=n/1000,n%1000
|
87
|
+
%(#{negativo}#{por_extenso(m)} mil#{c > 0 ? " e #{por_extenso(c)}":''})
|
88
|
+
when 1_000_000..999_999_999
|
89
|
+
mi,m=n/1_000_000,n%1_000_000
|
90
|
+
%(#{negativo}#{por_extenso(mi)} milh#{mi > 1 ? 'ões':'ão'}#{m > 0 ? " e #{por_extenso(m)}" : ''})
|
91
|
+
when 1_000_000_000..999_999_999_999
|
92
|
+
bi,mi=n/1_000_000_000,n%1_000_000_000
|
93
|
+
%(#{negativo}#{por_extenso(bi)} bilh#{bi > 1 ? 'ões':'ão'}#{mi > 0 ? " e #{por_extenso(mi)}" : ''})
|
94
|
+
when 1_000_000_000_000..999_999_999_999_999
|
95
|
+
tri,bi=n/1_000_000_000_000,n%1_000_000_000_000
|
96
|
+
%(#{negativo}#{por_extenso(tri)} trilh#{tri > 1 ? 'ões':'ão'}#{bi > 0 ? " e #{por_extenso(bi)}" : ''})
|
97
|
+
else
|
98
|
+
raise "Valor excede o permitido: #{n}"
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
module ExtensoReal
|
2
|
+
include Extenso
|
3
|
+
|
4
|
+
# Escreve por extenso em reais.
|
5
|
+
#
|
6
|
+
# Exemplo:
|
7
|
+
# 1.por_extenso_em_reais ==> 'um real'
|
8
|
+
# (100.58).por_extenso_em_reais ==> 'cem reais e cinquenta e oito centavos'
|
9
|
+
def por_extenso_em_reais
|
10
|
+
ExtensoReal.por_extenso_em_reais(self)
|
11
|
+
end
|
12
|
+
|
13
|
+
# Alias para por_extenso_em_reais
|
14
|
+
alias_method :to_extenso_real, :por_extenso_em_reais
|
15
|
+
|
16
|
+
# Escreve o numero por extenso em reais.
|
17
|
+
#
|
18
|
+
# Exemplo:
|
19
|
+
# Extenso.por_extenso_em_reais(1) ==> "um real"
|
20
|
+
# Extenso.por_extenso_em_reais(100) ==> "cem reais"
|
21
|
+
# Extenso.por_extenso_em_reais(100.58) ==> "cem reais e cinquenta e oito centavos"
|
22
|
+
def ExtensoReal.por_extenso_em_reais(valor)
|
23
|
+
negativo=(valor<0)? " negativo" : ""
|
24
|
+
negativos=(valor<0)? " negativos" : ""
|
25
|
+
valor = valor.abs
|
26
|
+
return 'grátis' if valor == 0
|
27
|
+
case valor
|
28
|
+
when Integer
|
29
|
+
extenso = Extenso.por_extenso(valor)
|
30
|
+
if extenso =~ /^(.*)(ão$|ões$)/
|
31
|
+
complemento = 'de '
|
32
|
+
else
|
33
|
+
complemento = ''
|
34
|
+
end
|
35
|
+
%(#{extenso} #{valor <= 1 ? "real#{negativo}": "#{complemento}reais#{negativos}"})
|
36
|
+
when Float
|
37
|
+
real,cents=("%.2f" % valor).split(/\./).map{ |m| m.to_i}
|
38
|
+
valor_cents=Extenso.por_extenso(cents%100)
|
39
|
+
valor_cents+= case cents.to_i%100
|
40
|
+
when 0 then ""
|
41
|
+
when 1 then " centavo"
|
42
|
+
when 2..99 then " centavos"
|
43
|
+
end
|
44
|
+
|
45
|
+
if real.to_i > 0
|
46
|
+
"#{ExtensoReal.por_extenso_em_reais(real.to_i)}#{cents > 0 ? ' e ' + valor_cents + negativos : real.to_i > 1 ? negativos : negativo }"
|
47
|
+
else
|
48
|
+
if (cents.to_i%100)==1
|
49
|
+
"#{valor_cents}#{negativo}"
|
50
|
+
else
|
51
|
+
"#{valor_cents}#{negativos}"
|
52
|
+
end
|
53
|
+
end
|
54
|
+
else
|
55
|
+
ExtensoReal.por_extenso_em_reais(valor.to_s.strip.gsub(/[^\d]/,'.').to_f)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
Numeric.send(:include, ExtensoReal)
|
@@ -0,0 +1,19 @@
|
|
1
|
+
$:.unshift(File.dirname(__FILE__)) unless
|
2
|
+
$:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
|
3
|
+
|
4
|
+
%w(dinheiro
|
5
|
+
dinheiro_util
|
6
|
+
excecoes
|
7
|
+
nil_class
|
8
|
+
extenso
|
9
|
+
extenso_real).each {|req| require File.dirname(__FILE__) + "/brdinheiro_lite/#{req}"}
|
10
|
+
|
11
|
+
require 'bigdecimal'
|
12
|
+
|
13
|
+
String.send(:include, DinheiroUtil)
|
14
|
+
|
15
|
+
class Object
|
16
|
+
def blank?
|
17
|
+
respond_to?(:empty?) ? empty? : !self
|
18
|
+
end
|
19
|
+
end
|