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