extenso_pt 0.5.7 → 0.5.8
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +2 -2
- data/README.md +4 -2
- data/extenso_pt.gemspec +10 -9
- data/lib/extenso_pt/constantes.rb +56 -0
- data/lib/extenso_pt/module.rb +219 -0
- data/lib/extenso_pt/version.rb +1 -1
- data/lib/extenso_pt.rb +63 -244
- metadata +24 -21
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 957540b2bccdc61b30b6c221465b11573c9570720729dafd3df982ab73216da1
|
4
|
+
data.tar.gz: 4f2159763f75b938535d61c293834f0f039395d577521d7d8d56cbe19592fe42
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ec98f28a4969f2ed153086b55b781b89c617276d4d16bbb3de600dfa765b083a7ee6abd832a0f7d44eb13f7801deb189e1f7dc2890210934dbf5b27f09a79175
|
7
|
+
data.tar.gz: af1f863cad4cbce9c8aeaceb0353ccc2518ca7155428fa5fb4554fc095eecacae9222e1337cb7261462900b0f383dfd2cc1fa9c4ea913daf9bc9ad77a85022ed
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,8 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
extenso_pt (0.5.
|
4
|
+
extenso_pt (0.5.8)
|
5
|
+
bigdecimal (~> 1.4.4)
|
5
6
|
|
6
7
|
GEM
|
7
8
|
remote: https://rubygems.org/
|
@@ -14,7 +15,6 @@ PLATFORMS
|
|
14
15
|
ruby
|
15
16
|
|
16
17
|
DEPENDENCIES
|
17
|
-
bigdecimal (~> 1.4.4)
|
18
18
|
bundler (~> 1.17)
|
19
19
|
extenso_pt!
|
20
20
|
minitest (~> 5.0)
|
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# ExtensoPt [![Build Status](https://travis-ci.org/hernanilr/extenso_pt.svg?branch=master)](https://travis-ci.org/hernanilr/extenso_pt)
|
2
2
|
|
3
|
-
|
3
|
+
Converte valores monetários em extenso de portugês de portugal, brasil ou numeracao romana. Os valores podem ser um numerico, uma string de digitos ou um conjunto destes (array, range, hash). O extenso pode ser produzido na escala longa (utilizada em todos os países lusófonos) ou na escala curta (utilizada no Brasil) [wiki](https://pt.wikipedia.org/wiki/Escalas_curta_e_longa). Pode ainda converter os valores em numeracao romana e vice versa.
|
4
4
|
|
5
5
|
## Installation
|
6
6
|
|
@@ -21,7 +21,9 @@ Or install it yourself as:
|
|
21
21
|
## Usage
|
22
22
|
|
23
23
|
```ruby
|
24
|
-
|
24
|
+
1234.extenso => "MIL DUZENTOS E TRINTA E QUATRO EUROS"
|
25
|
+
1234.romana => "MCCXXXIV"
|
26
|
+
"MCCXXXIV".romana => 1234
|
25
27
|
12000000.12.extenso => "DOZE MILHÕES DE EUROS E DOZE CÊNTIMOS"
|
26
28
|
1.01.extenso(msingular:"DÓLAR") => "UM DÓLAR E UM CÊNTIMO"
|
27
29
|
10.1.extenso(mplural:"DÓLARES") => "DEZ DÓLARES E DEZ CÊNTIMOS" # plural inferido <silgular> mais "S"
|
data/extenso_pt.gemspec
CHANGED
@@ -12,14 +12,14 @@ Gem::Specification.new do |spec|
|
|
12
12
|
spec.homepage = 'https://github.com/hernanilr/extenso_pt'
|
13
13
|
spec.license = 'MIT'
|
14
14
|
|
15
|
-
spec.summary = '
|
16
|
-
|
17
|
-
|
18
|
-
spec.description
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
15
|
+
spec.summary = 'Converte valores monetários em extenso de portugês de ' \
|
16
|
+
'portugal, brasil ou numeracao romana.'
|
17
|
+
spec.description = spec.summary
|
18
|
+
spec.description += ' Os valores podem ser um numerico, uma string ' \
|
19
|
+
'de digitos ou um conjunto destes (array, range, hash). O extenso ' \
|
20
|
+
'pode ser produzido na escala longa (utilizada em todos os países ' \
|
21
|
+
'lusófonos) ou na escala curta (utilizada no Brasil). Pode ainda ' \
|
22
|
+
'converter os valores em numeracao romana e vice versa.'
|
23
23
|
|
24
24
|
spec.metadata['yard.run'] = 'yard' # use "yard" to build full HTML docs.
|
25
25
|
spec.metadata['homepage_uri'] = spec.homepage
|
@@ -34,8 +34,9 @@ Gem::Specification.new do |spec|
|
|
34
34
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
35
35
|
spec.require_paths = ['lib']
|
36
36
|
|
37
|
-
spec.add_development_dependency 'bigdecimal', '~> 1.4.4'
|
38
37
|
spec.add_development_dependency 'bundler', '~> 1.17'
|
39
38
|
spec.add_development_dependency 'minitest', '~> 5.0'
|
40
39
|
spec.add_development_dependency 'rake', '~> 10.0'
|
40
|
+
|
41
|
+
spec.add_dependency 'bigdecimal', '~> 1.4.4'
|
41
42
|
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# @author Hernani Rodrigues Vaz
|
4
|
+
module ExtensoPt
|
5
|
+
# constantes para producao de extenso em portugues de portugal ou brasil
|
6
|
+
EXTLC = %i[pt br].freeze
|
7
|
+
A0020 = {
|
8
|
+
pt: ['', 'UM', 'DOIS', 'TRÊS', 'QUATRO', 'CINCO', 'SEIS', 'SETE',
|
9
|
+
'OITO', 'NOVE', 'DEZ', 'ONZE', 'DOZE', 'TREZE', 'CATORZE',
|
10
|
+
'QUINZE', 'DEZASSEIS', 'DEZASSETE', 'DEZOITO', 'DEZANOVE'],
|
11
|
+
br: ['', 'UM', 'DOIS', 'TRES', 'QUATRO', 'CINCO', 'SEIS', 'SETE',
|
12
|
+
'OITO', 'NOVE', 'DEZ', 'ONZE', 'DOZE', 'TREZE', 'QUATORZE',
|
13
|
+
'QUINZE', 'DEZESSEIS', 'DEZESSETE', 'DEZOITO', 'DEZENOVE']
|
14
|
+
}.freeze
|
15
|
+
A0100 = {
|
16
|
+
pt: ['', '', 'VINTE', 'TRINTA', 'QUARENTA', 'CINQUENTA', 'SESSENTA',
|
17
|
+
'SETENTA', 'OITENTA', 'NOVENTA'],
|
18
|
+
br: ['', '', 'VINTE', 'TRINTA', 'QUARENTA', 'CINQUENTA', 'SESSENTA',
|
19
|
+
'SETENTA', 'OITENTA', 'NOVENTA']
|
20
|
+
}.freeze
|
21
|
+
A1000 = {
|
22
|
+
pt: ['', 'CEM', 'CENTO', 'DUZENTOS', 'TREZENTOS', 'QUATROCENTOS',
|
23
|
+
'QUINHENTOS', 'SEISCENTOS', 'SETECENTOS', 'OITOCENTOS', 'NOVECENTOS'],
|
24
|
+
br: ['', 'CEM', 'CENTO', 'DUZENTOS', 'TREZENTOS', 'QUATROCENTOS',
|
25
|
+
'QUINHENTOS', 'SEISCENTOS', 'SETECENTOS', 'OITOCENTOS', 'NOVECENTOS']
|
26
|
+
}.freeze
|
27
|
+
|
28
|
+
# escala longa portugal segundo convencao entre varios paises,
|
29
|
+
# na 9a Conferencia Geral de Pesos e Medidas (12-21 de Outubro de 1948),
|
30
|
+
# organizada pelo Bureau International des Poids et Mesures
|
31
|
+
# 1 000 000 = milhao
|
32
|
+
# 1 000 000 000 000 = biliao
|
33
|
+
# 1 000 000 000 000 000 000 = triliao
|
34
|
+
# 1 000 000 000 000 000 000 000 000 = quadriliao
|
35
|
+
# 1 000 000 000 000 000 000 000 000 000 000 = quintiliao
|
36
|
+
# 1 000 000 000 000 000 000 000 000 000 000 000 000 = sextiliao
|
37
|
+
S1E24 = { pt: ['', 'MIL', ' MILHÃO', ' MIL MILHÃO', ' BILIÃO',
|
38
|
+
' MIL BILIÃO', ' TRILIÃO', ' MIL TRILIÃO'],
|
39
|
+
br: ['', 'MIL', ' MILHÃO', ' BILHÃO', ' TRILHÃO',
|
40
|
+
' QUADRILHÃO', ' QUINTILHÃO', ' SEXTILHÃO'] }.freeze
|
41
|
+
P1E24 = { pt: ['', ' MIL', ' MILHÕES', ' MIL MILHÕES', ' BILIÕES',
|
42
|
+
' MIL BILIÕES', ' TRILIÕES', ' MIL TRILIÕES'],
|
43
|
+
br: ['', ' MIL', ' MILHÕES', ' BILHÕES', ' TRILHÕES',
|
44
|
+
' QUADRILHÕES', ' QUINTILHÕES', ' SEXTILHÕES'] }.freeze
|
45
|
+
|
46
|
+
# contantes para numeracao romana
|
47
|
+
ROMAN = { M: 1000, CM: 900,
|
48
|
+
D: 500, CD: 400,
|
49
|
+
C: 100, XC: 90,
|
50
|
+
L: 50, XL: 40,
|
51
|
+
X: 10, IX: 9,
|
52
|
+
V: 5, IV: 4,
|
53
|
+
I: 1 }.freeze
|
54
|
+
# numeral romano
|
55
|
+
RO_RE = /^M*(D?C{0,3}|C[DM])(L?X{0,3}|X[LC])(V?I{0,3}|I[VX])$/i.freeze
|
56
|
+
end
|
@@ -0,0 +1,219 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# @author Hernani Rodrigues Vaz
|
4
|
+
module ExtensoPt
|
5
|
+
# Produz o extenso das centenas em portugues de portugal ou brasil
|
6
|
+
#
|
7
|
+
# @param [Integer] mil o valor dum grupo 3 digitos a converter
|
8
|
+
# @return [String] o extenso das centenas
|
9
|
+
def self.e900(mil)
|
10
|
+
A1000[@lc][(mil > 100 ? 1 : 0) + mil / 100] +
|
11
|
+
(mil > 100 && (mil % 100).positive? ? ' E ' : '') # proposicao
|
12
|
+
end
|
13
|
+
|
14
|
+
# Produz o extenso das dezenas em portugues de portugal ou brasil
|
15
|
+
#
|
16
|
+
# @param [Integer] cem o valor dum grupo 3 digitos a converter
|
17
|
+
# @return [String] o extenso das dezenas
|
18
|
+
def self.e90(cem)
|
19
|
+
A0100[@lc][cem / 10] +
|
20
|
+
(cem > 20 && (cem % 10).positive? ? ' E ' : '') # proposicao
|
21
|
+
end
|
22
|
+
|
23
|
+
# Produz o extenso das unidades em portugues de portugal ou brasil
|
24
|
+
#
|
25
|
+
# @param [Integer] cem o valor dum grupo 3 digitos a converter
|
26
|
+
# @return [String] o extenso das unidades
|
27
|
+
def self.e9(cem)
|
28
|
+
A0020[@lc][cem < 20 ? cem : cem % 10]
|
29
|
+
end
|
30
|
+
|
31
|
+
# Produz extenso parte fracionaria em portugues de portugal ou brasil
|
32
|
+
#
|
33
|
+
# @return [String] o extenso da parte fracionaria dum valor monetario
|
34
|
+
def self.ef99
|
35
|
+
# parametrizacao por defeito
|
36
|
+
@cs ||= 'CÊNTIMO'
|
37
|
+
@cp ||= @ms + 'S'
|
38
|
+
|
39
|
+
if @nf.positive?
|
40
|
+
e90(@nf) + e9(@nf) + (@nf > 1 ? ' ' + @cp : ' ' + @cs)
|
41
|
+
else
|
42
|
+
''
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
# Produz final da moeda em portugues de portugal ou brasil
|
47
|
+
#
|
48
|
+
# @return [String] o final da moeda
|
49
|
+
def self.efim
|
50
|
+
# parametrizacao por defeito
|
51
|
+
@ms ||= 'EURO'
|
52
|
+
@mp ||= @ms + 'S'
|
53
|
+
|
54
|
+
# proposicao DE entre parte inteira e moeda
|
55
|
+
emo = @de ? ' DE' : ''
|
56
|
+
# moeda singular/plural
|
57
|
+
emo += @tt > 1 ? ' ' + @mp : ' ' + @ms if @tt.positive?
|
58
|
+
# proposicao E entre moeda e parte fracionaria
|
59
|
+
# extenso da parte fracionaria
|
60
|
+
emo + (@tt.positive? && @nf.positive? ? ' E ' : '') + ef99
|
61
|
+
end
|
62
|
+
|
63
|
+
# Produz separador entre grupos 3 digitos
|
64
|
+
#
|
65
|
+
# @param [Integer] pos posicao actual nos grupos 3 digitos do valor monetario
|
66
|
+
# @return [String] separador entre grupos 3 digitos
|
67
|
+
def self.esep(pos)
|
68
|
+
if pos.positive? && @ai[pos - 1].positive?
|
69
|
+
@ai[pos - 1] > 100 ? ' ' : ' E '
|
70
|
+
else
|
71
|
+
''
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
# Produz qualificador grupo de 3 digitos em portugues de portugal ou brasil
|
76
|
+
#
|
77
|
+
# @param [Integer] pos posicao actual nos grupos 3 digitos do valor monetario
|
78
|
+
# @return [String] qualificador grupo de 3 digitos
|
79
|
+
def self.e1e24(pos)
|
80
|
+
if @ai[pos].positive?
|
81
|
+
@ai[pos] > 1 ? P1E24[@lc][pos] : S1E24[@lc][pos]
|
82
|
+
else
|
83
|
+
''
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
# Produz extenso grupo 3 digitos em portugues de portugal ou brasil
|
88
|
+
#
|
89
|
+
# @param [Integer] pos posicao actual nos grupos 3 digitos do valor monetario
|
90
|
+
# @return [String] extenso grupo 3 digitos
|
91
|
+
def self.edg3(pos)
|
92
|
+
# parametrizacao por defeito
|
93
|
+
# the first mention of an @<variable> creates the
|
94
|
+
# instance variable in the current object ie: self = ExtensoPt
|
95
|
+
@lc ||= :pt
|
96
|
+
|
97
|
+
dg3 = if pos == 1 && @ai[pos] == 1
|
98
|
+
# caso especial MIL EUROS
|
99
|
+
''
|
100
|
+
else
|
101
|
+
e900(@ai[pos]) + e90(@ai[pos] % 100) + e9(@ai[pos] % 100)
|
102
|
+
end
|
103
|
+
# qualificador grupo de 3 digitos
|
104
|
+
dg3 + e1e24(pos)
|
105
|
+
end
|
106
|
+
|
107
|
+
# Parametrizar controle singular/plural & proposicoes
|
108
|
+
#
|
109
|
+
# @return [void]
|
110
|
+
def self.pcontrolo
|
111
|
+
# soma grupos 1,2 (primeiros 6 digitos)
|
112
|
+
@s6 = @ai[0].to_i + @ai[1].to_i * 2
|
113
|
+
# soma grupos 3.. (digitos acima de 6)
|
114
|
+
@m6 = @ai[2..-1].to_a.inject(:+).to_i * 2
|
115
|
+
@tt = @s6 + @m6 # proposicao E & singular/plural
|
116
|
+
@de = @s6.zero? && @m6.positive? # proposicao DE
|
117
|
+
end
|
118
|
+
|
119
|
+
# Produz o extenso dum valor monetario em portugues de portugal ou brasil
|
120
|
+
#
|
121
|
+
# @param [Integer] pos posicao actual nos grupos 3 digitos do valor monetario
|
122
|
+
# @param [String] ext extenso em construcao
|
123
|
+
# @return [String] o extenso dum valor monetario
|
124
|
+
def self.emonetario(pos, ext)
|
125
|
+
# testa fim do valor monetario
|
126
|
+
if pos >= @ai.count
|
127
|
+
# parametrizar controle singular/plural & proposicoes
|
128
|
+
pcontrolo
|
129
|
+
|
130
|
+
# caso especial zero
|
131
|
+
(@tt + @nf).zero? ? 'ZERO ' + @mp : ext + efim
|
132
|
+
else
|
133
|
+
# tratamento do proximo grupo 3 digitos
|
134
|
+
emonetario(pos + 1, edg3(pos) + esep(pos) + ext)
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
# Parametrizar parte inteira/fracionaria do valor monetario
|
139
|
+
#
|
140
|
+
# @param [String] digitos do valor monetario
|
141
|
+
# @return [void]
|
142
|
+
def self.pintfra(dig)
|
143
|
+
# parte inteira do valor monetario => array grupos 3 digitos
|
144
|
+
# ex: 123022.12 => [22, 123]
|
145
|
+
@ai = dig[/^\d+/].to_s.reverse.scan(/\d{1,3}/).map { |i| i.reverse.to_i }
|
146
|
+
|
147
|
+
# parte fracionaria do valor monetario
|
148
|
+
# ex: 123022.12 => 12
|
149
|
+
# arredondada a 2 casas decimais (centimos/centavos)
|
150
|
+
@nf = (dig[/\.\d*/].to_f * 100).round
|
151
|
+
end
|
152
|
+
|
153
|
+
# Converte objeto criando extenso(s) em portugues de portugal ou brasil
|
154
|
+
#
|
155
|
+
# @param [Object] obj objeto a converter
|
156
|
+
# (String, Float, Integer, Array, Range, Hash)
|
157
|
+
# @return [String, Array, Hash] string extenso
|
158
|
+
# se objecto for (String, Float, Integer),
|
159
|
+
# array<extensos> se objecto for (Array, Range),
|
160
|
+
# hash<extensos> se objecto for (Hash)
|
161
|
+
def self.o2e(obj)
|
162
|
+
if obj.is_a?(Hash)
|
163
|
+
# converte os valores do Hash nos seus extensos - devolve um Hash
|
164
|
+
obj.map { |k, v| [k, o2e(v)] }.to_h
|
165
|
+
elsif obj.respond_to?(:to_a)
|
166
|
+
# converte o objecto num Array com os extensos dos valores
|
167
|
+
obj.to_a.map { |a| o2e(a) }
|
168
|
+
else
|
169
|
+
# converte objeto em string digitos utilizando bigdecimal para
|
170
|
+
# evitar problemas com aritmetica virgula flutuante em valores >1e12
|
171
|
+
digitos = obj.to_d.to_s('F')
|
172
|
+
|
173
|
+
# parametrizar parte inteira/fracionaria (@ai, @nf) do valor monetario
|
174
|
+
pintfra(digitos)
|
175
|
+
|
176
|
+
# processar extenso - valores superiores a 1e24 nao sao tratados
|
177
|
+
digitos[/^\d+/].length <= 24 ? emonetario(0, '') : ''
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
# Parametrizar moeda inferindo singular a partir do plural
|
182
|
+
#
|
183
|
+
# @param [Hash] moeda as opcoes para parametrizar a moeda/fracao
|
184
|
+
# @option moeda [Symbol] :lc locale do extenso -
|
185
|
+
# portugues de portugal (:pt) ou brasil (:br)
|
186
|
+
# @option moeda [String] :msingular moeda no singular -
|
187
|
+
# inferido do plural menos"S"
|
188
|
+
# @option moeda [String] :fsingular fracao no singular -
|
189
|
+
# inferido do plural menos "S"
|
190
|
+
# @option moeda [String] :mplural moeda no plural
|
191
|
+
# @option moeda [String] :fplural fracao no plural
|
192
|
+
# @return [void]
|
193
|
+
def self.psingular(moeda)
|
194
|
+
@ms = moeda[:msingular] ||
|
195
|
+
(moeda[:mplural].to_s[-1] == 'S' ? moeda[:mplural][0..-2] : 'EURO')
|
196
|
+
@cs = moeda[:fsingular] ||
|
197
|
+
(moeda[:fplural].to_s[-1] == 'S' ? moeda[:fplural][0..-2] : 'CÊNTIMO')
|
198
|
+
end
|
199
|
+
|
200
|
+
# Parametrizar moeda inferindo plural a partir do singular
|
201
|
+
#
|
202
|
+
# @param [Hash] moeda as opcoes para parametrizar a moeda/fracao
|
203
|
+
# @option moeda [Symbol] :lc locale do extenso -
|
204
|
+
# portugues de portugal (:pt) ou brasil (:br)
|
205
|
+
# @option moeda [String] :msingular moeda no singular
|
206
|
+
# @option moeda [String] :fsingular fracao no singular
|
207
|
+
# @option moeda [String] :mplural moeda no plural -
|
208
|
+
# inferido do singular mais "S"
|
209
|
+
# @option moeda [String] :fplural fracao no plural -
|
210
|
+
# inferido do singular mais "S"
|
211
|
+
# @return [void]
|
212
|
+
def self.pplural(moeda)
|
213
|
+
# somente [:pt, :br]
|
214
|
+
@lc = EXTLC.include?(moeda[:lc]) ? moeda[:lc] : :pt
|
215
|
+
|
216
|
+
@mp = moeda[:mplural] || @ms + 'S'
|
217
|
+
@cp = moeda[:fplural] || @cs + 'S'
|
218
|
+
end
|
219
|
+
end
|
data/lib/extenso_pt/version.rb
CHANGED
data/lib/extenso_pt.rb
CHANGED
@@ -1,247 +1,15 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require 'extenso_pt/version'
|
4
3
|
require 'bigdecimal/util'
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
pt: ['', 'UM', 'DOIS', 'TRÊS', 'QUATRO', 'CINCO', 'SEIS', 'SETE',
|
9
|
-
'OITO', 'NOVE', 'DEZ', 'ONZE', 'DOZE', 'TREZE', 'CATORZE',
|
10
|
-
'QUINZE', 'DEZASSEIS', 'DEZASSETE', 'DEZOITO', 'DEZANOVE'],
|
11
|
-
br: ['', 'UM', 'DOIS', 'TRES', 'QUATRO', 'CINCO', 'SEIS', 'SETE',
|
12
|
-
'OITO', 'NOVE', 'DEZ', 'ONZE', 'DOZE', 'TREZE', 'QUATORZE',
|
13
|
-
'QUINZE', 'DEZESSEIS', 'DEZESSETE', 'DEZOITO', 'DEZENOVE']
|
14
|
-
}.freeze
|
15
|
-
A0100 = {
|
16
|
-
pt: ['', '', 'VINTE', 'TRINTA', 'QUARENTA', 'CINQUENTA', 'SESSENTA',
|
17
|
-
'SETENTA', 'OITENTA', 'NOVENTA'],
|
18
|
-
br: ['', '', 'VINTE', 'TRINTA', 'QUARENTA', 'CINQUENTA', 'SESSENTA',
|
19
|
-
'SETENTA', 'OITENTA', 'NOVENTA']
|
20
|
-
}.freeze
|
21
|
-
A1000 = {
|
22
|
-
pt: ['', 'CEM', 'CENTO', 'DUZENTOS', 'TREZENTOS', 'QUATROCENTOS',
|
23
|
-
'QUINHENTOS', 'SEISCENTOS', 'SETECENTOS', 'OITOCENTOS', 'NOVECENTOS'],
|
24
|
-
br: ['', 'CEM', 'CENTO', 'DUZENTOS', 'TREZENTOS', 'QUATROCENTOS',
|
25
|
-
'QUINHENTOS', 'SEISCENTOS', 'SETECENTOS', 'OITOCENTOS', 'NOVECENTOS']
|
26
|
-
}.freeze
|
27
|
-
S1E24 = { pt: ['', 'MIL', ' MILHÃO', ' MIL MILHÃO', ' BILIÃO',
|
28
|
-
' MIL BILIÃO', ' TRILIÃO', ' MIL TRILIÃO'],
|
29
|
-
br: ['', 'MIL', ' MILHÃO', ' BILHÃO', ' TRILHÃO',
|
30
|
-
' QUADRILHÃO', ' QUINTILHÃO', ' SEXTILHÃO'] }.freeze
|
31
|
-
P1E24 = { pt: ['', ' MIL', ' MILHÕES', ' MIL MILHÕES', ' BILIÕES',
|
32
|
-
' MIL BILIÕES', ' TRILIÕES', ' MIL TRILIÕES'],
|
33
|
-
br: ['', ' MIL', ' MILHÕES', ' BILHÕES', ' TRILHÕES',
|
34
|
-
' QUADRILHÕES', ' QUINTILHÕES', ' SEXTILHÕES'] }.freeze
|
4
|
+
require 'extenso_pt/version'
|
5
|
+
require 'extenso_pt/constantes'
|
6
|
+
require 'extenso_pt/module'
|
35
7
|
|
36
8
|
# @author Hernani Rodrigues Vaz
|
37
9
|
module ExtensoPt
|
38
10
|
class Error < StandardError; end
|
39
11
|
|
40
|
-
# Produz
|
41
|
-
#
|
42
|
-
# @param [Integer] mil o valor dum grupo 3 digitos a converter
|
43
|
-
# @return [String] o extenso das centenas
|
44
|
-
def self.e900(mil)
|
45
|
-
A1000[@lc][(mil > 100 ? 1 : 0) + mil / 100] +
|
46
|
-
(mil > 100 && (mil % 100).positive? ? ' E ' : '') # proposicao
|
47
|
-
end
|
48
|
-
|
49
|
-
# Produz o extenso das dezenas em portugues de portugal ou brasil.
|
50
|
-
#
|
51
|
-
# @param [Integer] mil o valor dum grupo 3 digitos a converter
|
52
|
-
# @return [String] o extenso das dezenas
|
53
|
-
def self.e90(mil)
|
54
|
-
A0100[@lc][mil % 100 / 10] +
|
55
|
-
(mil > 20 && (mil % 10).positive? ? ' E ' : '') # proposicao
|
56
|
-
end
|
57
|
-
|
58
|
-
# Produz o extenso das unidades em portugues de portugal ou brasil.
|
59
|
-
#
|
60
|
-
# @param [Integer] cem o valor dum grupo 3 digitos a converter
|
61
|
-
# @return [String] o extenso das unidades
|
62
|
-
def self.e9(cem)
|
63
|
-
A0020[@lc][(cem < 20 ? cem : cem % 10)]
|
64
|
-
end
|
65
|
-
|
66
|
-
# Produz extenso parte fracionaria em portugues de portugal ou brasil.
|
67
|
-
#
|
68
|
-
# @return [String] o extenso da parte fracionaria dum valor monetario
|
69
|
-
def self.ef99
|
70
|
-
if @nf.positive?
|
71
|
-
e90(@nf) + e9(@nf) + (@nf > 1 ? ' ' + @cp : ' ' + @cs)
|
72
|
-
else
|
73
|
-
''
|
74
|
-
end
|
75
|
-
end
|
76
|
-
|
77
|
-
# Produz final da moeda em portugues de portugal ou brasil.
|
78
|
-
#
|
79
|
-
# @return [String] o final da moeda
|
80
|
-
def self.efim
|
81
|
-
# proposicao DE entre parte inteira e moeda
|
82
|
-
emo = @de ? ' DE' : ''
|
83
|
-
# moeda singular/plural
|
84
|
-
emo += @tt > 1 ? ' ' + @mp : ' ' + @ms if @tt.positive?
|
85
|
-
# proposicao E entre moeda e parte fracionaria
|
86
|
-
# extenso da parte fracionaria
|
87
|
-
emo + (@tt.positive? && @nf.positive? ? ' E ' : '') + ef99
|
88
|
-
end
|
89
|
-
|
90
|
-
# Produz separador entre grupos 3 digitos
|
91
|
-
#
|
92
|
-
# @param [Integer] pos posicao actual nos grupos 3 digitos do valor monetario
|
93
|
-
# @return [String] separador entre grupos 3 digitos
|
94
|
-
def self.esep(pos)
|
95
|
-
if pos.positive? && @ai[pos - 1].positive?
|
96
|
-
@ai[pos - 1] > 100 ? ' ' : ' E '
|
97
|
-
else
|
98
|
-
''
|
99
|
-
end
|
100
|
-
end
|
101
|
-
|
102
|
-
# Produz qualificador grupo de 3 digitos em portugues de portugal ou brasil.
|
103
|
-
#
|
104
|
-
# @param [Integer] pos posicao actual nos grupos 3 digitos do valor monetario
|
105
|
-
# @return [String] qualificador grupo de 3 digitos
|
106
|
-
def self.e1e24(pos)
|
107
|
-
if @ai[pos].positive?
|
108
|
-
@ai[pos] > 1 ? P1E24[@lc][pos] : S1E24[@lc][pos]
|
109
|
-
else
|
110
|
-
''
|
111
|
-
end
|
112
|
-
end
|
113
|
-
|
114
|
-
# Produz extenso grupo 3 digitos em portugues de portugal ou brasil.
|
115
|
-
#
|
116
|
-
# @param [Integer] pos posicao actual nos grupos 3 digitos do valor monetario
|
117
|
-
# @return [String] extenso grupo 3 digitos
|
118
|
-
def self.edg3(pos)
|
119
|
-
dg3 = if pos == 1 && @ai[pos] == 1
|
120
|
-
# caso especial MIL EUROS
|
121
|
-
''
|
122
|
-
else
|
123
|
-
e900(@ai[pos]) + e90(@ai[pos]) + e9(@ai[pos] % 100)
|
124
|
-
end
|
125
|
-
# qualificador grupo de 3 digitos
|
126
|
-
dg3 + e1e24(pos)
|
127
|
-
end
|
128
|
-
|
129
|
-
# Parametrizar controle singular/plural & proposicoes
|
130
|
-
#
|
131
|
-
# @return [void]
|
132
|
-
def self.pcontrolo
|
133
|
-
# soma grupos 1,2 (primeiros 6 digitos)
|
134
|
-
@s6 = @ai[0].to_i + @ai[1].to_i * 2
|
135
|
-
# soma grupos 3.. (digitos acima de 6)
|
136
|
-
@m6 = @ai[2..-1].to_a.inject(:+).to_i * 2
|
137
|
-
@tt = @s6 + @m6 # proposicao E & singular/plural
|
138
|
-
@de = @s6.zero? && @m6.positive? # proposicao DE
|
139
|
-
end
|
140
|
-
|
141
|
-
# Produz o extenso dum valor monetario em portugues de portugal ou brasil.
|
142
|
-
#
|
143
|
-
# @param [Integer] pos posicao actual nos grupos 3 digitos do valor monetario
|
144
|
-
# @param [String] ext extenso em construcao
|
145
|
-
# @return [String] o extenso dum valor monetario
|
146
|
-
def self.enumerico(pos = 0, ext = '')
|
147
|
-
# testa fim do valor monetario
|
148
|
-
if pos >= @ai.count
|
149
|
-
# parametrizar controle singular/plural & proposicoes
|
150
|
-
pcontrolo
|
151
|
-
|
152
|
-
# caso especial zero
|
153
|
-
(@tt + @nf).zero? ? 'ZERO ' + @mp : ext + efim
|
154
|
-
else
|
155
|
-
# tratamento do proximo grupo 3 digitos
|
156
|
-
enumerico(pos + 1, edg3(pos) + esep(pos) + ext)
|
157
|
-
end
|
158
|
-
end
|
159
|
-
|
160
|
-
# Parametrizar parte inteira/fracionaria do valor monetario
|
161
|
-
#
|
162
|
-
# @param [String] dig string de digitos rdo valor monetario
|
163
|
-
# @return [void]
|
164
|
-
def self.pintfra(dig)
|
165
|
-
# parte inteira do valor monetario => array grupos 3 digitos
|
166
|
-
# ex: 123022.12 => [22, 123]
|
167
|
-
@ai = dig[/^\d+/].to_s.reverse.scan(/\d{1,3}/).map { |i| i.reverse.to_i }
|
168
|
-
|
169
|
-
# parte fracionaria do valor monetario
|
170
|
-
# ex: 123022.12 => 12
|
171
|
-
# arredondada a 2 casas decimais (centimos/centavos)
|
172
|
-
@nf = (dig[/\.\d*/].to_f * 100).round
|
173
|
-
end
|
174
|
-
|
175
|
-
# Converte um objeto criando extenso(s) em portugues de portugal ou brasil.
|
176
|
-
#
|
177
|
-
# @param [Object] objeto objeto a converter
|
178
|
-
# (String, Float, Integer, Array, Range, Hash)
|
179
|
-
# @return [String, Array<extensos>, Hash<extensos>] string extenso
|
180
|
-
# se objecto for (String, Float, Integer),
|
181
|
-
# array se objecto for (Array, Range),
|
182
|
-
# hash se objecto for (Hash)
|
183
|
-
def self.eobjeto(obj)
|
184
|
-
if obj.is_a?(Hash)
|
185
|
-
# converte os valores do Hash nos seus extensos - devolve um Hash
|
186
|
-
obj.map { |k, v| [k, eobjeto(v)] }.to_h
|
187
|
-
elsif obj.respond_to?(:to_a)
|
188
|
-
# converte o objecto num Array com os extensos dos valores
|
189
|
-
obj.to_a.map { |v| eobjeto(v) }
|
190
|
-
else
|
191
|
-
# converte objeto numa string de digitos
|
192
|
-
# usa bigdecimal/util para evitar aritmetica binaria
|
193
|
-
# (tem problemas com valores >1e12)
|
194
|
-
# qualquer valor nao convertivel (ex: texto) resulta em "0.0"
|
195
|
-
sdigitos = obj.to_d.to_s('F')
|
196
|
-
|
197
|
-
# parametrizar parte inteira/fracionaria (@ai, @nf) do valor monetario
|
198
|
-
pintfra(sdigitos)
|
199
|
-
|
200
|
-
# processar extenso - valores superiores a 1e24 nao sao tratados
|
201
|
-
sdigitos[/^\d+/].length <= 24 ? enumerico : ''
|
202
|
-
end
|
203
|
-
end
|
204
|
-
|
205
|
-
# Parametrizar moeda inferindo singular a partir do plural
|
206
|
-
#
|
207
|
-
# @param [Hash] moeda as opcoes para parametrizar a moeda/fracao
|
208
|
-
# @option moeda [Symbol] :lc locale do extenso -
|
209
|
-
# portugues de portugal (:pt) ou brasil (:br)
|
210
|
-
# @option moeda [String] :msingular moeda no singular -
|
211
|
-
# inferido do plural menos "S"
|
212
|
-
# @option moeda [String] :fsingular fracao no singular -
|
213
|
-
# inferido do plural menos "S"
|
214
|
-
# @option moeda [String] :mplural moeda no plural
|
215
|
-
# @option moeda [String] :fplural fracao no plural
|
216
|
-
# @return [void]
|
217
|
-
def self.psingular(moeda)
|
218
|
-
@ms = moeda[:msingular] ||
|
219
|
-
(moeda[:mplural].to_s[-1] == 'S' ? moeda[:mplural][0..-2] : 'EURO')
|
220
|
-
@cs = moeda[:fsingular] ||
|
221
|
-
(moeda[:fplural].to_s[-1] == 'S' ? moeda[:fplural][0..-2] : 'CÊNTIMO')
|
222
|
-
end
|
223
|
-
|
224
|
-
# Parametrizar moeda inferindo plural a partir do singular
|
225
|
-
#
|
226
|
-
# @param [Hash] moeda as opcoes para parametrizar a moeda/fracao
|
227
|
-
# @option moeda [Symbol] :lc locale do extenso -
|
228
|
-
# portugues de portugal (:pt) ou brasil (:br)
|
229
|
-
# @option moeda [String] :msingular moeda no singular
|
230
|
-
# @option moeda [String] :fsingular fracao no singular
|
231
|
-
# @option moeda [String] :mplural moeda no plural -
|
232
|
-
# inferido do singular mais "S"
|
233
|
-
# @option moeda [String] :fplural fracao no plural -
|
234
|
-
# inferido do singular mais "S"
|
235
|
-
# @return [void]
|
236
|
-
def self.pplural(moeda)
|
237
|
-
# somente [:pt, :br]
|
238
|
-
@lc = LC.include?(moeda[:lc]) ? moeda[:lc] : :pt
|
239
|
-
|
240
|
-
@mp = moeda[:mplural] || @ms + 'S'
|
241
|
-
@cp = moeda[:fplural] || @cs + 'S'
|
242
|
-
end
|
243
|
-
|
244
|
-
# Produz extenso(s) de objeto(s) em portugues de portugal ou brasil.
|
12
|
+
# Produz extenso(s)) em portugues de portugal ou brasil
|
245
13
|
#
|
246
14
|
# @param [Hash] moeda as opcoes para parametrizar a moeda/fracao
|
247
15
|
# @option moeda [Symbol] :lc locale do extenso -
|
@@ -250,10 +18,10 @@ module ExtensoPt
|
|
250
18
|
# @option moeda [String] :fsingular fracao no singular
|
251
19
|
# @option moeda [String] :mplural moeda no plural
|
252
20
|
# @option moeda [String] :fplural fracao no plural
|
253
|
-
# @return [String, Array
|
21
|
+
# @return [String, Array, Hash] string extenso
|
254
22
|
# se objecto for (String, Float, Integer),
|
255
|
-
# array se objecto for (Array, Range),
|
256
|
-
# hash se objecto for (Hash)
|
23
|
+
# array<extensos> se objecto for (Array, Range),
|
24
|
+
# hash<extensos> se objecto for (Hash)
|
257
25
|
def extenso(moeda = { lc: :pt, msingular: 'EURO', fsingular: 'CÊNTIMO' })
|
258
26
|
# parametrizacao por defeito para :br
|
259
27
|
if moeda[:lc] == :br && !moeda[:msingular] && !moeda[:mplural]
|
@@ -264,8 +32,8 @@ module ExtensoPt
|
|
264
32
|
ExtensoPt.psingular(moeda)
|
265
33
|
ExtensoPt.pplural(moeda)
|
266
34
|
|
267
|
-
# extenso
|
268
|
-
ExtensoPt.
|
35
|
+
# cria extenso(s) em portugues de portugal ou brasil
|
36
|
+
ExtensoPt.o2e(self)
|
269
37
|
end
|
270
38
|
end
|
271
39
|
|
@@ -284,17 +52,68 @@ class Range
|
|
284
52
|
include ExtensoPt
|
285
53
|
end
|
286
54
|
|
287
|
-
# permite obter o extenso
|
55
|
+
# permite obter o extenso de Float
|
288
56
|
class Float
|
289
57
|
include ExtensoPt
|
290
58
|
end
|
291
59
|
|
292
|
-
# permite obter o extenso
|
60
|
+
# permite obter o extenso ou numeral romano de Integer
|
293
61
|
class Integer
|
294
62
|
include ExtensoPt
|
63
|
+
|
64
|
+
# Produz numeracao romana a partir do inteiro
|
65
|
+
#
|
66
|
+
# @return [String] numeracao romana
|
67
|
+
def romana
|
68
|
+
return "-#{i2r(-self)}" if negative?
|
69
|
+
|
70
|
+
i2r(self)
|
71
|
+
end
|
72
|
+
|
73
|
+
# Recursivamente produz numeral romano
|
74
|
+
#
|
75
|
+
# @param [Integer] numero a converter em numeral romano
|
76
|
+
# @return [String] numeral romano
|
77
|
+
def i2r(numero)
|
78
|
+
return '' if numero.zero?
|
79
|
+
|
80
|
+
ROMAN.each { |r, v| return r.to_s + i2r(numero - v) if v <= numero }
|
81
|
+
end
|
295
82
|
end
|
296
83
|
|
297
|
-
# permite obter o extenso duma
|
84
|
+
# permite obter o extenso duma string de digitos ou
|
85
|
+
# inteiro duma string numeral romano
|
298
86
|
class String
|
299
87
|
include ExtensoPt
|
88
|
+
|
89
|
+
# Testa se string contem numeracao romana
|
90
|
+
#
|
91
|
+
# @return [true, false] sim ou nao numeracao romana
|
92
|
+
def romana?
|
93
|
+
RO_RE.match?(upcase)
|
94
|
+
end
|
95
|
+
|
96
|
+
# Produz inteiro a partir da numeracao romana
|
97
|
+
# ou numeracao romana a partir de string digitos
|
98
|
+
#
|
99
|
+
# @return [Integer, String] inteiro ou numeracao romana
|
100
|
+
def romana
|
101
|
+
return -self[/[^-]+/].romana if /-+/.match?(self)
|
102
|
+
return self[/^\d+/].to_i.romana if /^\d+/.match?(self)
|
103
|
+
return 0 unless romana?
|
104
|
+
|
105
|
+
r2i(upcase, 0)
|
106
|
+
end
|
107
|
+
|
108
|
+
# Recursivamente produz inteiro
|
109
|
+
#
|
110
|
+
# @param [String] numeral romano em convercao
|
111
|
+
# @param [Integer] ultimo numeral convertido
|
112
|
+
# @return [Integer] inteiro do numeral romano
|
113
|
+
def r2i(numeral, ultimo)
|
114
|
+
return 0 if numeral.empty?
|
115
|
+
|
116
|
+
v = ROMAN[numeral[-1].to_sym]
|
117
|
+
v < ultimo ? (r2i(numeral.chop, v) - v) : (r2i(numeral.chop, v) + v)
|
118
|
+
end
|
300
119
|
end
|
metadata
CHANGED
@@ -1,76 +1,76 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: extenso_pt
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.5.
|
4
|
+
version: 0.5.8
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Hernâni Rodrigues Vaz
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-
|
11
|
+
date: 2019-11-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
|
-
name:
|
14
|
+
name: bundler
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 1.
|
19
|
+
version: '1.17'
|
20
20
|
type: :development
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: 1.
|
26
|
+
version: '1.17'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
|
-
name:
|
28
|
+
name: minitest
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: '
|
33
|
+
version: '5.0'
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: '
|
40
|
+
version: '5.0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
|
-
name:
|
42
|
+
name: rake
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
45
|
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: '
|
47
|
+
version: '10.0'
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
52
|
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version: '
|
54
|
+
version: '10.0'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
|
-
name:
|
56
|
+
name: bigdecimal
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
59
|
- - "~>"
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version:
|
62
|
-
type: :
|
61
|
+
version: 1.4.4
|
62
|
+
type: :runtime
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
66
|
- - "~>"
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version:
|
69
|
-
description:
|
70
|
-
Os valores podem ser um numerico, uma string de digitos ou
|
71
|
-
range, hash). O extenso pode ser produzido na escala
|
72
|
-
países lusófonos) ou na escala curta (utilizada no
|
73
|
-
|
68
|
+
version: 1.4.4
|
69
|
+
description: Converte valores monetários em extenso de portugês de portugal, brasil
|
70
|
+
ou numeracao romana. Os valores podem ser um numerico, uma string de digitos ou
|
71
|
+
um conjunto destes (array, range, hash). O extenso pode ser produzido na escala
|
72
|
+
longa (utilizada em todos os países lusófonos) ou na escala curta (utilizada no
|
73
|
+
Brasil). Pode ainda converter os valores em numeracao romana e vice versa.
|
74
74
|
email:
|
75
75
|
- hernanirvaz@gmail.com
|
76
76
|
executables: []
|
@@ -89,6 +89,8 @@ files:
|
|
89
89
|
- bin/setup
|
90
90
|
- extenso_pt.gemspec
|
91
91
|
- lib/extenso_pt.rb
|
92
|
+
- lib/extenso_pt/constantes.rb
|
93
|
+
- lib/extenso_pt/module.rb
|
92
94
|
- lib/extenso_pt/version.rb
|
93
95
|
homepage: https://github.com/hernanilr/extenso_pt
|
94
96
|
licenses:
|
@@ -114,5 +116,6 @@ requirements: []
|
|
114
116
|
rubygems_version: 3.0.3
|
115
117
|
signing_key:
|
116
118
|
specification_version: 4
|
117
|
-
summary:
|
119
|
+
summary: Converte valores monetários em extenso de portugês de portugal, brasil ou
|
120
|
+
numeracao romana.
|
118
121
|
test_files: []
|