unpack brazilian-rails
This commit is contained in:
22
vendor/gems/brazilian-rails/brdinheiro/lib/brdinheiro.rb
vendored
Normal file
22
vendor/gems/brazilian-rails/brdinheiro/lib/brdinheiro.rb
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
$:.unshift(File.dirname(__FILE__)) unless
|
||||
$:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
|
||||
|
||||
%w(dinheiro
|
||||
dinheiro_util
|
||||
dinheiro_active_record
|
||||
excecoes
|
||||
nil_class).each {|req| require File.dirname(__FILE__) + "/brdinheiro/#{req}"}
|
||||
|
||||
%w(bigdecimal
|
||||
rubygems
|
||||
active_record
|
||||
active_support/all).each {|req| require req }
|
||||
|
||||
require 'brnumeros'
|
||||
|
||||
String.send(:include, DinheiroUtil)
|
||||
ActiveRecord::Base.send :include, DinheiroActiveRecord
|
||||
|
||||
module BrDinheiro
|
||||
end
|
||||
|
||||
296
vendor/gems/brazilian-rails/brdinheiro/lib/brdinheiro/dinheiro.rb
vendored
Normal file
296
vendor/gems/brazilian-rails/brdinheiro/lib/brdinheiro/dinheiro.rb
vendored
Normal file
@@ -0,0 +1,296 @@
|
||||
class Dinheiro
|
||||
include Comparable
|
||||
|
||||
attr_reader :quantia
|
||||
|
||||
FORMATO_VALIDO_BR = /^([R|r]\$\s*)?(([+-]?\d{1,3}(\.?\d{3})*))?(\,\d{0,2})?$/
|
||||
FORMATO_VALIDO_EUA = /^([R|r]\$\s*)?(([+-]?\d{1,3}(\,?\d{3})*))?(\.\d{0,2})?$/
|
||||
SEPARADOR_MILHAR = "."
|
||||
SEPARADOR_FRACIONARIO = ","
|
||||
QUANTIDADE_DIGITOS = 3
|
||||
PRECISAO_DECIMAL = 100
|
||||
|
||||
def initialize(quantia)
|
||||
self.quantia = quantia
|
||||
end
|
||||
|
||||
# Retorna o valor em Float quando uma coleção
|
||||
# ou objeto é convertido para JSON
|
||||
#
|
||||
# Exemplo:
|
||||
# produto = Produto.find 1
|
||||
# produto.to_json // {"nome": "MacBook", "valor": 3500.0}
|
||||
def as_json
|
||||
self.to_f
|
||||
end
|
||||
|
||||
# Retorna o valor armazenado em string.
|
||||
#
|
||||
# Exemplo:
|
||||
# 1000.to_s ==> '1.000,00'
|
||||
def to_s
|
||||
inteiro_com_milhar(parte_inteira) + parte_decimal
|
||||
end
|
||||
|
||||
# Compara com outro dinheiro se eh igual.
|
||||
#
|
||||
# Exemplo:
|
||||
# um_real = Dinheiro.new(1)
|
||||
# um_real == Dinheiro.new(1) ==> true
|
||||
# um_real == Dinheiro.new(2) ==> false
|
||||
def ==(outro_dinheiro)
|
||||
begin
|
||||
outro_dinheiro = Dinheiro.new(outro_dinheiro) unless outro_dinheiro.kind_of?(Dinheiro)
|
||||
rescue
|
||||
return false
|
||||
end
|
||||
@quantia == outro_dinheiro.quantia
|
||||
end
|
||||
|
||||
# Compara com outro dinheiro se eh maior ou menor.
|
||||
#
|
||||
# Exemplo:
|
||||
# 1.real < 2.reais ==> true
|
||||
# 1.real > 2.reais ==> false
|
||||
# 2.real < 1.reais ==> false
|
||||
# 2.real > 1.reais ==> true
|
||||
def <=>(outro_dinheiro)
|
||||
outro_dinheiro = Dinheiro.new(outro_dinheiro) unless outro_dinheiro.kind_of?(Dinheiro)
|
||||
@quantia <=> outro_dinheiro.quantia
|
||||
end
|
||||
|
||||
# Retorna a adicao entre dinheiros.
|
||||
#
|
||||
# Exemplo:
|
||||
# 1.real + 1.real == 2.reais
|
||||
# 1.real + 1 == 2.reais
|
||||
def +(outro)
|
||||
Dinheiro.new(transforma_em_string_que_represente_a_quantia(@quantia + quantia_de(outro)))
|
||||
end
|
||||
|
||||
# Retorna a subtracao entre dinheiros.
|
||||
#
|
||||
# Exemplo:
|
||||
# 10.reais - 2.reais == 8.reais
|
||||
# 10.reais - 2 == 8.reais
|
||||
def -(outro)
|
||||
Dinheiro.new(transforma_em_string_que_represente_a_quantia(@quantia - quantia_de(outro)))
|
||||
end
|
||||
|
||||
# Retorna a multiplicacao entre dinheiros.
|
||||
#
|
||||
# Exemplo:
|
||||
# 5.reais * 2 == 10.reais
|
||||
# 5.reais * 2.reais == 10.reais
|
||||
def *(outro)
|
||||
return Dinheiro.new(to_f * outro) unless outro.kind_of? Dinheiro
|
||||
outro * to_f
|
||||
end
|
||||
|
||||
# Retorna a divisao entre dinheiros.
|
||||
#
|
||||
# Exemplo:
|
||||
# 5.reais / 2 == (2.5).reais
|
||||
# 5.reais / 2.reais == DivisaPorNaoEscalarError
|
||||
# 5.reais / 0 == ZeroDivisionError
|
||||
#
|
||||
# Veja também o método parcelar
|
||||
def /(outro)
|
||||
raise DivisaPorNaoEscalarError unless outro.kind_of?(Numeric)
|
||||
return @quantia/outro if outro == 0
|
||||
Dinheiro.new(to_f / outro.to_f)
|
||||
end
|
||||
|
||||
# Retorna um array de dinheiro com as parcelas
|
||||
#
|
||||
# Exemplo:
|
||||
# 6.reais.parcelar(2) == [3.reais, 3.reais]
|
||||
# 6.reais.parcelar(2.reais) == DisivaPorNaoEscalarError
|
||||
# 6.reais.parcelar(0) == ZeroDivisionError
|
||||
def parcelar(numero_de_parcelar)
|
||||
raise DivisaPorNaoEscalarError unless numero_de_parcelar.kind_of?(Integer)
|
||||
resto = @quantia % numero_de_parcelar
|
||||
valor_menor = Dinheiro.new((@quantia/numero_de_parcelar)/100.0)
|
||||
valor_maior = Dinheiro.new((@quantia/numero_de_parcelar+1)/100.0)
|
||||
[valor_menor] * (numero_de_parcelar - resto) + [valor_maior] * resto
|
||||
end
|
||||
|
||||
# Escreve o valor por extenso.
|
||||
#
|
||||
# Exemplo:
|
||||
# 1.real.to_extenso ==> 'um real'
|
||||
# (100.58).to_extenso ==> 'cem reais e cinquenta e oito centavos'
|
||||
def to_extenso
|
||||
(@quantia/100.0).por_extenso_em_reais
|
||||
end
|
||||
|
||||
# Alias para o metodo to_extenso.
|
||||
alias_method :por_extenso, :to_extenso
|
||||
|
||||
# Alias para o metodo to_extenso.
|
||||
alias_method :por_extenso_em_reais, :to_extenso
|
||||
|
||||
# Verifica se o valor é zero.
|
||||
def zero?
|
||||
to_f.zero?
|
||||
end
|
||||
|
||||
# Retorna um Float.
|
||||
def to_f
|
||||
to_s.gsub('.', '').gsub(',', '.').to_f
|
||||
end
|
||||
|
||||
def coerce(outro)#:nodoc:
|
||||
[ Dinheiro.new(outro), self ]
|
||||
end
|
||||
|
||||
# Retorna a própria instância/
|
||||
def real
|
||||
self
|
||||
end
|
||||
|
||||
# Alias para real.
|
||||
alias_method :reais, :real
|
||||
|
||||
# Retorna uma string formatada com sigla em valor monetário.
|
||||
# Exemplo:
|
||||
# Dinheiro.new(1).real_formatado ==> 'R$ 1,00'
|
||||
# Dinheiro.new(-1).real_formatado ==> 'R$ -1,00'
|
||||
def real_formatado
|
||||
"R$ #{to_s}"
|
||||
end
|
||||
|
||||
# Alias para real_formatado.
|
||||
alias_method :reais_formatado, :real_formatado
|
||||
|
||||
# Retorna uma string formatada com sigla em valor contábil.
|
||||
#
|
||||
# Exemplo:
|
||||
# Dinheiro.new(1).real_contabil ==> 'R$ 1,00'
|
||||
# Dinheiro.new(-1).real_contabil ==> 'R$ (1,00)'
|
||||
def real_contabil
|
||||
"R$ " + contabil
|
||||
end
|
||||
|
||||
# Alias para real_contabil.
|
||||
alias_method :reais_contabeis, :real_contabil
|
||||
|
||||
# Retorna uma string formatada sem sigla.
|
||||
#
|
||||
# Exemplo:
|
||||
# Dinheiro.new(1).contabil ==> '1,00'
|
||||
# Dinheiro.new(-1).contabil ==> '(1,00)'
|
||||
def contabil
|
||||
if @quantia >= 0
|
||||
to_s
|
||||
else
|
||||
"(" + to_s[1..-1] + ")"
|
||||
end
|
||||
end
|
||||
|
||||
# Method missing para retorna um BigDecinal quando chamada .
|
||||
def method_missing(symbol, *args) #:nodoc:
|
||||
#Ex: Chama ao método valor_decimal()
|
||||
if (symbol.to_s =~ /^(.*)_decimal$/) && args.size == 0
|
||||
BigDecimal.new quantia_sem_separacao_milhares.gsub(',','.')
|
||||
else
|
||||
super.method_missing(symbol, *args)
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
def quantia_de(outro)
|
||||
outro = outro.to_f if outro.kind_of?(BigDecimal)
|
||||
return outro.quantia if outro.kind_of?(Dinheiro)
|
||||
(outro * 100).round
|
||||
end
|
||||
|
||||
def transforma_em_string_que_represente_a_quantia(quantia)
|
||||
if /^([+-]?)(\d)$/ =~ quantia.to_s
|
||||
return "#{$1}0.0#{$2}"
|
||||
end
|
||||
/^([+-]?)(\d*)(\d\d)$/ =~ quantia.to_s
|
||||
"#{$1}#{$2.to_i}.#{$3}"
|
||||
end
|
||||
|
||||
def quantia=(quantia)
|
||||
raise DinheiroInvalidoError unless quantia_valida?(quantia)
|
||||
quantia = quantia.to_f if quantia.kind_of?(BigDecimal)
|
||||
@quantia = (quantia * 100).round if quantia.kind_of?(Numeric)
|
||||
@quantia = extrai_quantia_como_inteiro(quantia) if quantia.kind_of?(String)
|
||||
end
|
||||
|
||||
def parte_inteira
|
||||
quantia_sem_separacao_milhares[0,quantia_sem_separacao_milhares.length-QUANTIDADE_DIGITOS]
|
||||
end
|
||||
|
||||
def parte_decimal
|
||||
quantia_sem_separacao_milhares[-QUANTIDADE_DIGITOS, QUANTIDADE_DIGITOS]
|
||||
end
|
||||
|
||||
def inteiro_com_milhar(inteiro)
|
||||
return inteiro if quantidade_de_passos(inteiro) == 0
|
||||
resultado = ""
|
||||
quantidade_de_passos(inteiro).times do |passo|
|
||||
resultado = "." + inteiro[-QUANTIDADE_DIGITOS + passo * -QUANTIDADE_DIGITOS, QUANTIDADE_DIGITOS] + resultado
|
||||
end
|
||||
resultado = inteiro[0, digitos_que_sobraram(inteiro)] + resultado
|
||||
resultado.gsub(/^(-?)\./, '\1')
|
||||
end
|
||||
|
||||
def quantia_sem_separacao_milhares
|
||||
sprintf("%.2f", (@quantia.to_f / PRECISAO_DECIMAL)).gsub(SEPARADOR_MILHAR, SEPARADOR_FRACIONARIO)
|
||||
end
|
||||
|
||||
def quantidade_de_passos(inteiro)
|
||||
resultado = inteiro.length / QUANTIDADE_DIGITOS
|
||||
resultado = (resultado - 1) if inteiro.length % QUANTIDADE_DIGITOS == 0
|
||||
resultado
|
||||
end
|
||||
|
||||
def digitos_que_sobraram(inteiro)
|
||||
inteiro.length - (quantidade_de_passos(inteiro) * QUANTIDADE_DIGITOS)
|
||||
end
|
||||
|
||||
def quantia_valida?(quantia)
|
||||
return false if quantia.kind_of?(String) && !quantia_respeita_formato?(quantia)
|
||||
quantia.kind_of?(String) || quantia.kind_of?(Numeric)
|
||||
end
|
||||
|
||||
def extrai_quantia_como_inteiro(quantia)
|
||||
if FORMATO_VALIDO_BR =~ quantia
|
||||
return sem_milhar($2, $5, '.')
|
||||
end
|
||||
if FORMATO_VALIDO_EUA =~ quantia
|
||||
return sem_milhar($2, $5, ',')
|
||||
end
|
||||
end
|
||||
|
||||
def sem_milhar(parte_inteira, parte_decimal, delimitador_de_milhar)
|
||||
(inteiro(parte_inteira, delimitador_de_milhar) + decimal(parte_decimal)).to_i
|
||||
end
|
||||
|
||||
def inteiro(inteiro_com_separador_milhar, separador)
|
||||
return inteiro_com_separador_milhar.gsub(separador, '') unless inteiro_com_separador_milhar.blank?
|
||||
""
|
||||
end
|
||||
|
||||
def decimal(parte_fracionaria)
|
||||
unless parte_fracionaria.blank?
|
||||
return sem_delimitador_decimal(parte_fracionaria) if parte_fracionaria.length == 3
|
||||
return sem_delimitador_decimal(parte_fracionaria) + "0" if parte_fracionaria.length == 2
|
||||
end
|
||||
"00"
|
||||
end
|
||||
|
||||
def sem_delimitador_decimal(parte_fracionaria)
|
||||
"#{parte_fracionaria}".gsub(/[.|,]/, '')
|
||||
end
|
||||
|
||||
|
||||
def quantia_respeita_formato?(quantia)
|
||||
return true if FORMATO_VALIDO_BR.match(quantia) || FORMATO_VALIDO_EUA.match(quantia)
|
||||
false
|
||||
end
|
||||
|
||||
end
|
||||
45
vendor/gems/brazilian-rails/brdinheiro/lib/brdinheiro/dinheiro_active_record.rb
vendored
Normal file
45
vendor/gems/brazilian-rails/brdinheiro/lib/brdinheiro/dinheiro_active_record.rb
vendored
Normal file
@@ -0,0 +1,45 @@
|
||||
module DinheiroActiveRecord#:nodoc:
|
||||
def self.included(base)#:nodoc:
|
||||
base.extend ClassMethods
|
||||
end
|
||||
module ClassMethods#:nodoc:
|
||||
def usar_como_dinheiro(*args)#:nodoc:
|
||||
unless args.size.zero?
|
||||
args.each do |name|
|
||||
composed_of name, :class_name => 'Dinheiro', :mapping => [name.to_s, "valor_decimal"], :allow_nil => true
|
||||
|
||||
name = name.to_s
|
||||
module_eval <<-ADICIONANDO_METODO
|
||||
validate :#{name}_valido?
|
||||
|
||||
def #{name}_valido?
|
||||
begin
|
||||
@#{name}.to_s.reais
|
||||
rescue Exception => e
|
||||
self.errors.add('#{name}', e.message)
|
||||
end
|
||||
end
|
||||
|
||||
def #{name}=(value)
|
||||
if value.nil?
|
||||
write_attribute('#{name}', nil)
|
||||
elsif value.kind_of?(Dinheiro)
|
||||
write_attribute('#{name}', value.valor_decimal)
|
||||
else
|
||||
begin
|
||||
write_attribute('#{name}', value.reais.valor_decimal)
|
||||
rescue
|
||||
@#{name} = value
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def #{name}
|
||||
read_attribute(:#{name}).reais if read_attribute(:#{name})
|
||||
end
|
||||
ADICIONANDO_METODO
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
51
vendor/gems/brazilian-rails/brdinheiro/lib/brdinheiro/dinheiro_util.rb
vendored
Normal file
51
vendor/gems/brazilian-rails/brdinheiro/lib/brdinheiro/dinheiro_util.rb
vendored
Normal file
@@ -0,0 +1,51 @@
|
||||
module DinheiroUtil
|
||||
|
||||
# Ao incluir o modulo, cria aliases para_dinheiro
|
||||
def self.included(base)
|
||||
base.class_eval do
|
||||
# Alias para para_dinheiro
|
||||
alias_method :real, :para_dinheiro
|
||||
|
||||
# Alias para para_dinheiro
|
||||
alias_method :reais, :para_dinheiro
|
||||
end
|
||||
end
|
||||
|
||||
# Transforma numero em dinheiro
|
||||
#
|
||||
# Exemplo:
|
||||
# 1.para_dinheiro.class ==> Dinheiro
|
||||
def para_dinheiro
|
||||
Dinheiro.new(self)
|
||||
end
|
||||
|
||||
# Retorna string formatada com simbolo monetario
|
||||
#
|
||||
# Exemplo:
|
||||
# 1.real_contabil ==> 'R$ 1,00'
|
||||
# -1.real_contabil ==> 'R$ (1,00)'
|
||||
def real_contabil
|
||||
Dinheiro.new(self).real_contabil
|
||||
end
|
||||
|
||||
# Retorna string formatada com simbolo monetario
|
||||
#
|
||||
# Exemplo:
|
||||
# 2.reais_contabeis ==> 'R$ 2,00'
|
||||
# -2.reais_contabeis ==> 'R$ 2,00'
|
||||
def reais_contabeis
|
||||
Dinheiro.new(self).reais_contabeis
|
||||
end
|
||||
|
||||
# Retorna string formatada com simbolo monetario
|
||||
#
|
||||
# Exemplo:
|
||||
# 1.contabil ==> '1,00'
|
||||
# -1.contabil ==> '(1,00)'
|
||||
def contabil
|
||||
Dinheiro.new(self).contabil
|
||||
end
|
||||
end
|
||||
|
||||
Numeric.send(:include, DinheiroUtil)
|
||||
String.send(:include, DinheiroUtil)
|
||||
6
vendor/gems/brazilian-rails/brdinheiro/lib/brdinheiro/excecoes.rb
vendored
Normal file
6
vendor/gems/brazilian-rails/brdinheiro/lib/brdinheiro/excecoes.rb
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
def cria_excecao(classe, mensagem)
|
||||
eval "class #{classe}; def initialize; super('#{mensagem}'); end; end"
|
||||
end
|
||||
|
||||
cria_excecao("DinheiroInvalidoError < ArgumentError", "O valor deve estar preenchido e no formato correto. Ex.: 100.00 .")
|
||||
cria_excecao("DivisaPorNaoEscalarError < ArgumentError", "So eh possivel dividir dinheiro por numeros.")
|
||||
24
vendor/gems/brazilian-rails/brdinheiro/lib/brdinheiro/nil_class.rb
vendored
Normal file
24
vendor/gems/brazilian-rails/brdinheiro/lib/brdinheiro/nil_class.rb
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
class NilClass
|
||||
|
||||
def valor
|
||||
0.real
|
||||
end
|
||||
|
||||
def contabil
|
||||
0.contabil
|
||||
end
|
||||
|
||||
def para_dinheiro
|
||||
0.real
|
||||
end
|
||||
|
||||
def reais
|
||||
0.real
|
||||
end
|
||||
|
||||
def real
|
||||
0.real
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
10
vendor/gems/brazilian-rails/brdinheiro/lib/brdinheiro/version.rb
vendored
Normal file
10
vendor/gems/brazilian-rails/brdinheiro/lib/brdinheiro/version.rb
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
module BrDinheiro
|
||||
module VERSION #:nodoc:
|
||||
MAJOR = 3
|
||||
MINOR = 3
|
||||
TINY = 0
|
||||
|
||||
STRING = "#{MAJOR}.#{MINOR}.#{TINY}"
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user