lib/extenso_pt/extenso.rb in extenso_pt-0.7.2 vs lib/extenso_pt/extenso.rb in extenso_pt-0.7.3

- old
+ new

@@ -1,104 +1,171 @@ # frozen_string_literal: true # @author Hernani Rodrigues Vaz module ExtensoPt - # Produz extenso das centenas em portugues de portugal ou brasil + # extensos 1-19; 20-90; 100-900 + e013a = %w[UM DOIS TRÊS QUATRO CINCO SEIS SETE OITO NOVE DEZ ONZE DOZE TREZE].freeze + e019a = %w[QUINZE DEZASSEIS DEZASSETE DEZOITO DEZANOVE].freeze + e090a = %w[VINTE TRINTA QUARENTA CINQUENTA SESSENTA SETENTA OITENTA NOVENTA].freeze + e900a = %w[CEM CENTO DUZENTOS TREZENTOS QUATROCENTOS QUINHENTOS SEISCENTOS SETECENTOS OITOCENTOS NOVECENTOS].freeze + A0020 = { pt: [''] + e013a + ['CATORZE'] + e019a, br: [''] + e013a + ['QUATORZE'] + e019a }.freeze + A0100 = { pt: ['', ''] + e090a, br: ['', ''] + e090a }.freeze + A1000 = { pt: [''] + e900a, br: [''] + e900a }.freeze + + # singular extensos 1e3 ate 1e24 + # @note escala segundo convencao entre varios paises, + # na 9a Conferencia Geral de Pesos e Medidas (12-21 de Outubro de 1948), + # organizada pelo Bureau International des Poids et Mesures + # @example + # 1 000 000 = milhao + # 1 000 000 000 000 = biliao + # 1 000 000 000 000 000 000 = triliao + # 1 000 000 000 000 000 000 000 000 = quadriliao + # 1 000 000 000 000 000 000 000 000 000 000 = quintiliao + # 1 000 000 000 000 000 000 000 000 000 000 000 000 = sextiliao + S1E24 = { + pt: ['', 'MIL', ' MILHÃO', ' MIL MILHÃO', ' BILIÃO', ' MIL BILIÃO', ' TRILIÃO', ' MIL TRILIÃO'], + br: ['', 'MIL', ' MILHÃO', ' BILHÃO', ' TRILHÃO', ' QUADRILHÃO', ' QUINTILHÃO', ' SEXTILHÃO'] + }.freeze + + # plural extensos 1e3 ate 1e24 + # @note escala segundo convencao entre varios paises, + # na 9a Conferencia Geral de Pesos e Medidas (12-21 de Outubro de 1948), + # organizada pelo Bureau International des Poids et Mesures + P1E24 = { + pt: ['', ' MIL', ' MILHÕES', ' MIL MILHÕES', ' BILIÕES', ' MIL BILIÕES', ' TRILIÕES', ' MIL TRILIÕES'], + br: ['', ' MIL', ' MILHÕES', ' BILHÕES', ' TRILHÕES', ' QUADRILHÕES', ' QUINTILHÕES', ' SEXTILHÕES'] + }.freeze + + # Parametrizar variaveis da moeda # - # @param [Integer] mil o valor dum grupo 3 digitos a converter - # @return [String] extenso das centenas - def self.e900(mil) - A1000[@lc][(mil > 100 ? 1 : 0) + mil / 100] + (mil > 100 && (mil % 100).positive? ? ' E ' : '') + # @param [Hash<String, Symbol>] moeda opcoes parametrizar moeda/fracao + # @option moeda [Symbol] :lc locale do extenso - portugues de portugal (:pt) portugues do brasil (:br) + # @option moeda [String] :moeda_singular moeda no singular + # @option moeda [String] :fracao_singular fracao no singular + # @option moeda [String] :moeda_plural moeda no plural + # @option moeda [String] :fracao_plural fracao no plural + def self.parametrizar_moeda(moeda) + # parametrizacao por defeito + # the first mention of a @<variable> creates that instance variable in the current object ie: self = ExtensoPt + @lc = moeda[:lc] || :pt + @ms = moeda[:moeda_singular] || 'EURO' + @fs = moeda[:fracao_singular] || 'CÊNTIMO' + @mp = moeda[:moeda_plural] || "#{@ms}S" + @fp = moeda[:fracao_plural] || "#{@fs}S" end - # Produz extenso das dezenas em portugues de portugal ou brasil + # Parametrizar variaveis parte inteira e fracionaria # + # @param [String] digitos do valor monetario a converter + def self.parametrizar_grupos(digitos) + # cria array de grupos 3 digitos da parte inteira ex: 123022.12 => [22, 123] + @ai = digitos[/^\d+/].reverse.scan(/\d{1,3}/).map { |grp| Integer(grp.reverse) } + + # obtem parte fracionaria da string digitos arredondada a 2 casas decimais ex: 123022.124 => 12, 123022.125 => 13 + @nf = (Float(digitos[/\.\d*/]) * 100).round + end + + # @return [Array<Integer>] grupos 3 digitos da parte inteira + def self.grupos + @ai + end + + # @return [Integer] soma grupos 1-8 de digitos + def self.soma_grupos + Integer(@ai[0]) + Integer(@ai[1] || 0) * 2 + Integer(@ai[2..].to_a.inject(:+) || 0) * 2 + end + + # @return [true, false] sim ou nao proposicao DE + def self.testa_de? + Integer(@ai[0..1].inject(:+)).zero? && Integer(@ai[2..].to_a.inject(:+) || 0).positive? + end + + # @param [Integer] mil o valor dum grupo 3 digitos a converter + # @return [String] extenso das centenas em portugues de portugal ou brasil + def self.centenas(mil) + cem = mil > 100 + A1000[@lc][(cem ? 1 : 0) + mil / 100] + (cem && (mil % 100).positive? ? ' E ' : '') + end + # @param [Integer] cem a centena dum grupo 3 digitos a converter - # @return [String] extenso das dezenas - def self.e090(cem) + # @return [String] extenso das dezenas em portugues de portugal ou brasil + def self.dezenas(cem) A0100[@lc][cem / 10] + (cem > 20 && (cem % 10).positive? ? ' E ' : '') end - # Produz extenso das unidades em portugues de portugal ou brasil - # # @param [Integer] cem a centena dum grupo 3 digitos a converter - # @return [String] extenso das unidades - def self.e009(cem) + # @return [String] extenso das unidades em portugues de portugal ou brasil + def self.unidades(cem) A0020[@lc][cem < 20 ? cem : cem % 10] end - # @return [String] extenso da parte fracionaria em portugues de portugal ou brasil - def self.ef99 - if cnf? - e090(@nf) + e009(@nf) + ' ' + (@nf > 1 ? @fp : @fs) + # @return [String] proposicao E & extenso da parte fracionaria em portugues de portugal ou brasil + def self.fracionaria + if @nf.positive? + "#{soma_grupos.positive? ? ' E ' : ''}#{dezenas(@nf)}#{unidades(@nf)} #{@nf > 1 ? @fp : @fs}" else '' end end # @return [String] final da moeda em portugues de portugal ou brasil - def self.efim - t = c124 - if t.positive? - # proposicao DE entre parte inteira e moeda & moeda singular/plural & proposicao E entre moeda e parte fracionaria - (cde? ? ' DE ' : ' ') + (t > 1 ? @mp : @ms) + (cnf? ? ' E ' : '') + def self.final + som = soma_grupos + if som.positive? + # proposicao DE entre parte inteira e moeda & moeda singular/plural + "#{testa_de? ? ' DE ' : ' '}#{som > 1 ? @mp : @ms}" else '' - end + ef99 + end + fracionaria end - # Produz proposicao E entre grupos 3 digitos - # # @param [Integer] pos posicao actual nos grupos 3 digitos # @return [String] proposicao E entre grupos 3 digitos - def self.edgs(pos) - if pos.positive? && @ai[pos - 1].positive? - @ai[pos - 1] > 100 ? ' ' : ' E ' + def self.proposicao_grupo(pos) + grp = @ai[pos - 1] + if pos.positive? && grp.positive? + grp > 100 ? ' ' : ' E ' else '' end end - # Produz qualificador grupo de 3 digitos em portugues de portugal ou brasil - # # @param [Integer] pos posicao actual nos grupos 3 digitos - # @return [String] qualificador grupo de 3 digitos - def self.e124(pos) - if @ai[pos].positive? - @ai[pos] > 1 ? P1E24[@lc][pos] : S1E24[@lc][pos] + # @return [String] qualificador grupo de 3 digitos em portugues de portugal ou brasil + def self.qualificador_grupo(pos) + grp = @ai[pos] + if grp.positive? + grp > 1 ? P1E24[@lc][pos] : S1E24[@lc][pos] else '' - end + edgs(pos) + end + proposicao_grupo(pos) end - # Produz extenso de grupo 3 digitos em portugues de portugal ou brasil - # # @param [Integer] pos posicao actual nos grupos 3 digitos - # @return [String] extenso do grupo 3 digitos - def self.edg3(pos) + # @return [String] extenso do grupo 3 digitos em portugues de portugal ou brasil + def self.extenso_grupo(pos) + grp = @ai[pos] + dez = grp % 100 # caso especial MIL EUROS - if pos == 1 && @ai[pos] == 1 + if pos == 1 && grp == 1 '' else # extenso das centenas + extenso das dezenas + extenso das unidades - e900(@ai[pos]) + e090(@ai[pos] % 100) + e009(@ai[pos] % 100) - end + e124(pos) + "#{centenas(grp)}#{dezenas(dez)}#{unidades(dez)}" + end + qualificador_grupo(pos) end - # Produz extenso da parte inteira e fracionaria - # # @param [Integer] pos posicao no grupo 3 digitos # @param [String] ext extenso em construcao - # @return [String] extenso do valor monetario - def self.ejun(pos = 0, ext = '') + # @return [String] extenso do valor monetario completo + def self.extenso_completo(pos = 0, ext = '') # testa fim do valor monetario if pos >= @ai.count # caso especial de zero - (c124 + @nf).zero? ? 'ZERO ' + @mp : ext + efim + (soma_grupos + @nf).zero? ? "ZERO #{@mp}" : "#{ext}#{final}" else # converte grupo 3 digitos na posicao corrente & envoca proxima posicao - ejun(pos + 1, edg3(pos) + ext) + extenso_completo(pos + 1, extenso_grupo(pos) + ext) end end - # private_class_method :e900, :e090, :e009, :ef99, :efim, - # :edgs, :e124, :edg3 end