lib/extenso_pt.rb in extenso_pt-0.5.0 vs lib/extenso_pt.rb in extenso_pt-0.5.1
- old
+ new
@@ -3,65 +3,70 @@
# @author Hernâni Rodrigues Vaz
module ExtensoPt
class Error < StandardError; end
- LC=[:pt,:br]
+ LC =[:pt,:br]
A0020={pt: ["","UM","DOIS","TRÊS","QUATRO","CINCO","SEIS","SETE","OITO","NOVE","DEZ","ONZE","DOZE","TREZE","CATORZE","QUINZE","DEZASSEIS","DEZASSETE","DEZOITO","DEZANOVE"],
br: ["","UM","DOIS","TRES","QUATRO","CINCO","SEIS","SETE","OITO","NOVE","DEZ","ONZE","DOZE","TREZE","QUATORZE","QUINZE","DEZESSEIS","DEZESSETE","DEZOITO","DEZENOVE"]}
A0100={pt: ["","","VINTE","TRINTA","QUARENTA","CINQUENTA","SESSENTA","SETENTA","OITENTA","NOVENTA"],
br: ["","","VINTE","TRINTA","QUARENTA","CINQUENTA","SESSENTA","SETENTA","OITENTA","NOVENTA"]}
A1000={pt: ["","CEM","CENTO","DUZENTOS","TREZENTOS","QUATROCENTOS","QUINHENTOS","SEISCENTOS","SETECENTOS","OITOCENTOS","NOVECENTOS"],
br: ["","CEM","CENTO","DUZENTOS","TREZENTOS","QUATROCENTOS","QUINHENTOS","SEISCENTOS","SETECENTOS","OITOCENTOS","NOVECENTOS"]}
A1e24={pt: ["","MIL"," MILHÃO"," MIL MILHÃO"," BILIÃO"," MIL BILIÃO"," TRILIÃO"," MIL TRILIÃO",""," MIL"," MILHÕES"," MIL MILHÕES"," BILIÕES"," MIL BILIÕES"," TRILIÕES"," MIL TRILIÕES"],
br: ["","MIL"," MILHÃO"," BILHÃO"," TRILHÃO"," QUADRILHÃO"," QUINTILHÃO"," SEXTILHÃO",""," MIL"," MILHÕES"," BILHÕES"," TRILHÕES"," QUADRILHÕES"," QUINTILHÕES"," SEXTILHÕES"]}
- # Produz o extenso dum grupo de 3 digitos em portugûes de portugal ou brasil.
+ # Produz o extenso dum grupo 3 digitos em portugûes de portugal ou brasil.
#
- # @param [Integer] mil o valor dum grupo de 3 digitos a converter
- # @param [Integer] pos posição deste grupo de 3 digitos no valor monetário em tratamento
- # @return [String] o extenso dum grupo de 3 digitos
+ # @param [Integer] mil o valor dum grupo 3 digitos a converter
+ # @param [Integer] pos posição deste grupo 3 digitos no valor monetário em tratamento
+ # @return [String] o extenso dum grupo 3 digitos
def self.e999(mil,pos=0)
cem=mil%100
A1000[@@lc][(mil>100?1:0)+mil/100]+(mil>100&&cem>0?" E ":"")+ # extenso das centenas
A0100[@@lc][cem/10]+(mil>20&&mil%10>0?" E ":"")+ # extenso dos dezenas
A0020[@@lc][pos==1&&mil==1?0:cem<20?cem:cem%10] # extenso das unidades mais 10-19
end
# Produz o extenso dum valor monetário em portugûes de portugal ou brasil.
#
- # @param [Integer] pos posição actual nos grupos de 3 digitos do valor monetário
+ # @param [Integer] pos posição actual nos grupos 3 digitos do valor monetário
# @param [String] ext extenso actual em construção
# @return [String] o extenso dum valor monetário
def self.enumerico(pos=0,ext="")
# testa fim do valor monetário
if (pos>=@@ai.count)
- # soma os grupos de 3 digitos para controle de singular/plural
- so1=@@ai[0].to_i+@@ai[1].to_i*2 # primeiros dois grupos
- so2=@@ai[2..-1].to_a.inject(:+).to_i*2 # restantes grupos
+ # soma grupos 3 digitos para controle de singular/plural
+ s06=@@ai[0].to_i+@@ai[1].to_i*2 # grupos 1,2 (primeiros 6 digitos)
+ sm6=@@ai[2..-1].to_a.inject(:+).to_i*2 # grupos 3.. (digitos acima de 6)
- if (so1+so2+@@nf==0)
- "ZERO "+@@mp # caso especial de zero
+ if (s06+sm6+@@nf==0)
+ "ZERO "+@@mp # caso especial de zero
else
- ext+=" DE" if (so2>0&&so1==0) # proposição DE para valores >1e6 mas 0 nos primeiros 6 digitos
- ext+=" "+@@ms if (so1+so2==1) # singular da moeda
- ext+=" "+@@mp if (so1+so2>1) # plural da moeda
- ext+=" E " if (so1+so2>0&&@@nf>0) # proposição E entre parte inteira e parte fracionária
- ext+=e999(@@nf) # extenso da parte fracionária
- ext+=" "+@@cs if (@@nf==1) # singular da parte fracionária
- ext+=" "+@@cp if (@@nf>1) # plural da parte fracionária
+ ext+=" DE" if (sm6>0&&s06==0) # proposição DE para >1e6 e zero nos primeiros 6 digitos
+ ext+=" "+@@ms if (s06+sm6==1) # singular da moeda
+ ext+=" "+@@mp if (s06+sm6>1) # plural da moeda
+ ext+=" E " if (s06+sm6>0&&@@nf>0) # proposição E entre parte inteira e parte fracionária
+ ext+=e999(@@nf) # extenso da parte fracionária
+ ext+=" "+@@cs if (@@nf==1) # singular da parte fracionária
+ ext+=" "+@@cp if (@@nf>1) # plural da parte fracionária
ext
end
else
- # extenso do grupo actual de 3 digitos
- dg3 =e999(@@ai[pos],pos)
- dg3+=A1e24[@@lc][@@ai[pos]>0?@@ai[pos]>1?8+pos:pos:0] # qualificador do grupo actual
- dg3+=pos>0?@@ai[pos-1]>100?" ":@@ai[pos-1]>0?" E ":"":"" # separação entre grupo actual e anterior
+ # tratamento do grupo actual 3 digitos
+ dg3 =e999(@@ai[pos],pos) # extenso
+ dg3+=A1e24[@@lc][@@ai[pos]>0?@@ai[pos]>1?8+pos:pos:0] # qualificador
- # proximo grupo de 3 digitos
+ # convenção de separação com grupo anterior 3 digitos
+ if (pos>0)
+ dg3+=" E " if (@@ai[pos-1]<101&&@@ai[pos-1]>0) # grupo < 101 => proposição E
+ dg3+=" " if (@@ai[pos-1]>100) # grupo > 100 => espaço
+ end
+
+ # tratamento do proximo grupo 3 digitos
enumerico(pos+1,dg3+ext)
end
end
# Converte um objeto criando extenso(s) em portugûes de portugal ou brasil.
@@ -75,26 +80,29 @@
obj.map{|k,v|[k,eobjeto(v)]}.to_h
elsif (obj.respond_to?:to_a)
# converte o objecto num Array e converte os valores do Array nos seus extensos - devolve um Array
obj.to_a.map{|a|eobjeto(a)}
else
- # converte objeto numa string de digitos usando bigdecimal/util para evitar bugs com valores superiores a 1e12
+ # converte objeto numa string de digitos
+ # usa bigdecimal/util para evitar aritmética binária (tem problemas com valores >1e12)
# qualquer valor não convertivel (ex: texto) resulta em "0.0"
svalor=obj.to_d.to_s('F')
- # array da parte inteira do valor monetário dividido em grupos de 3 digitos ex: 123022.12 => [22, 123]
+ # array da parte inteira do valor monetário dividido em grupos 3 digitos ex: 123022.12 => [22, 123]
+ # esta variavel é usada no processo de conversão
@@ai=svalor[/^\d+/].to_s.reverse.scan(/\d{1,3}/).map{|i|i.reverse.to_i}
# parte fracionária do valor monetário ex: 123022.12 => 12
# arredondada a 2 casas decimais (cêntimos/centavos)
+ # esta variavel é usada no processo de conversão
@@nf=(svalor[/\.\d*/].to_f*100).round
- # valores superiores a 1e24 não são tratados
+ # valores >1e24 não são tratados
if (@@ai.count>8)
""
else
- # extenso num numerico
+ # extenso dum numerico
enumerico
end
end
end
@@ -108,22 +116,22 @@
# @option moeda [String] :fplural fração no plural - pode ser inferido do singular mais "S"
# @return [String, Array<String>, Hash<String>] extenso se o objecto for (String, Float, Integer), Array dos extensos se o objecto for (Array, Range) ou Hash dos extensos se o objecto for (Hash)
def extenso(moeda={lc:(:pt),msingular:"EURO",fsingular:"CÊNTIMO"})
# parametrização por defeito para locale => :br
- if (moeda[:lc]==:br&&!moeda[:mplural]&&!moeda[:fplural])
- moeda={lc:(:br),msingular:"REAL",mplural:"REAIS",fsingular:"CENTAVO"}
- end
+ moeda={lc:(:br),msingular:"REAL",mplural:"REAIS",fsingular:"CENTAVO"} if (moeda[:lc]==:br&&!moeda[:mplural]&&!moeda[:fplural])
# se locale nao for [:pt,:br] entao :pt
+ # esta variavel é usada no processo de conversão
if (LC.include?moeda[:lc])
@@lc=moeda[:lc]
else
@@lc=:pt
end
# inferir singular da moeda a partir do plural
+ # estas variaveis são usadas no processo de conversão
if (moeda[:msingular])
@@ms=moeda[:msingular]
elsif (moeda[:mplural].to_s[-1]=="S")
@@ms=moeda[:mplural][0..-2]
else
@@ -137,9 +145,10 @@
else
@@cs="CÊNTIMO"
end
# inferir plural da moeda a partir do singular
+ # estas variaveis são usadas no processo de conversão
if (moeda[:mplural])
@@mp=moeda[:mplural]
else
@@mp=@@ms+"S"
end