inss_calculator 0.3.2 → 0.4.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +2 -1
- data/Gemfile.lock +10 -9
- data/README.md +50 -1
- data/lib/dinheiro.rb +303 -0
- data/lib/inss_calculator/decorator/text.rb +39 -0
- data/lib/inss_calculator/discount_previdence_calculator.rb +1 -0
- data/lib/inss_calculator/eigth_discount_calculator.rb +35 -0
- data/lib/inss_calculator/fifth_discount_calculator.rb +35 -0
- data/lib/inss_calculator/public_inss_calculator.rb +24 -0
- data/lib/inss_calculator/seventh_discount_calculator.rb +35 -0
- data/lib/inss_calculator/sixth_discount_calculator.rb +35 -0
- data/lib/inss_calculator/version.rb +1 -1
- data/lib/inss_calculator.rb +19 -0
- metadata +10 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: dda408b24c4c0da00dbd74687fb89520ec440d089c169bb16bb9fef83163f287
|
4
|
+
data.tar.gz: d86a04f19fb5fb6b66115f60f0b4026cb4594b8771d50ad422c4f9f9f330adbb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 553359d8be075e3c58c83e9512f2f8d5a3247be37fa878bc13baa0c9d76ff6f6530d6ff772ca5925e5c9bce181ddc5212cc73dc5af77293cca500c8dc6dae6ef
|
7
|
+
data.tar.gz: 8b8f0a3a04ea4148c8608b2a76ed8335b8e7a0e6f86f96ac5c6a373c47ccd6fededb58398a1186963d01494ae11a886be90e6b016e9838dea7b3aa709ea8e423
|
data/.rubocop.yml
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
inss_calculator (0.
|
4
|
+
inss_calculator (0.4.1)
|
5
5
|
|
6
6
|
GEM
|
7
7
|
remote: https://rubygems.org/
|
@@ -10,15 +10,15 @@ GEM
|
|
10
10
|
diff-lcs (1.5.1)
|
11
11
|
json (2.7.2)
|
12
12
|
language_server-protocol (3.17.0.3)
|
13
|
-
parallel (1.
|
14
|
-
parser (3.3.
|
13
|
+
parallel (1.26.3)
|
14
|
+
parser (3.3.4.2)
|
15
15
|
ast (~> 2.4.1)
|
16
16
|
racc
|
17
|
-
racc (1.8.
|
17
|
+
racc (1.8.1)
|
18
18
|
rainbow (3.1.1)
|
19
19
|
rake (13.2.1)
|
20
20
|
regexp_parser (2.9.2)
|
21
|
-
rexml (3.3.
|
21
|
+
rexml (3.3.4)
|
22
22
|
strscan
|
23
23
|
rspec (3.13.0)
|
24
24
|
rspec-core (~> 3.13.0)
|
@@ -33,24 +33,25 @@ GEM
|
|
33
33
|
diff-lcs (>= 1.2.0, < 2.0)
|
34
34
|
rspec-support (~> 3.13.0)
|
35
35
|
rspec-support (3.13.1)
|
36
|
-
rubocop (1.
|
36
|
+
rubocop (1.65.1)
|
37
37
|
json (~> 2.3)
|
38
38
|
language_server-protocol (>= 3.17.0)
|
39
39
|
parallel (~> 1.10)
|
40
40
|
parser (>= 3.3.0.2)
|
41
41
|
rainbow (>= 2.2.2, < 4.0)
|
42
|
-
regexp_parser (>=
|
42
|
+
regexp_parser (>= 2.4, < 3.0)
|
43
43
|
rexml (>= 3.2.5, < 4.0)
|
44
44
|
rubocop-ast (>= 1.31.1, < 2.0)
|
45
45
|
ruby-progressbar (~> 1.7)
|
46
46
|
unicode-display_width (>= 2.4.0, < 3.0)
|
47
|
-
rubocop-ast (1.
|
47
|
+
rubocop-ast (1.32.0)
|
48
48
|
parser (>= 3.3.1.0)
|
49
49
|
ruby-progressbar (1.13.0)
|
50
50
|
strscan (3.1.0)
|
51
51
|
unicode-display_width (2.5.0)
|
52
52
|
|
53
53
|
PLATFORMS
|
54
|
+
ruby
|
54
55
|
x86_64-linux
|
55
56
|
|
56
57
|
DEPENDENCIES
|
@@ -60,4 +61,4 @@ DEPENDENCIES
|
|
60
61
|
rubocop (~> 1.21)
|
61
62
|
|
62
63
|
BUNDLED WITH
|
63
|
-
2.
|
64
|
+
2.5.17
|
data/README.md
CHANGED
@@ -1,6 +1,9 @@
|
|
1
1
|
# InssCalculator
|
2
2
|
|
3
|
-
Calculadora do desconto do INSS sobre o salário bruto 2024
|
3
|
+
Calculadora do desconto do INSS sobre o salário bruto 2024 de acordo com a [Portaria Inter Ministerial
|
4
|
+
número 2 de 11 de Janeiro de 2024](https://www.in.gov.br/en/web/dou/-/portaria-interministerial-mps/mf-n-2-de-11-de-janeiro-de-2024-537035232).
|
5
|
+
|
6
|
+
Esta mesma portaria discorre tanto sobre a contribuição do trabalhador do setor público quanto do setor privado.
|
4
7
|
|
5
8
|
## Instalation
|
6
9
|
|
@@ -12,12 +15,28 @@ Não conhecia [esse comando?](https://bundler.io/v2.5/man/bundle-add.1.html) Ele
|
|
12
15
|
|
13
16
|
## Usage
|
14
17
|
|
18
|
+
Para calcular a contribuição do trabalhador no setor privado:
|
19
|
+
|
15
20
|
```
|
16
21
|
gross_salary = 3000
|
17
22
|
calculator = InssCalculator::DiscountPrevidenceCalculator.new(gross_salary)
|
18
23
|
calculator.contribution => 258.81
|
19
24
|
calculator.salary => 3000.0
|
20
25
|
calculator.net_salary => 2741.19
|
26
|
+
|
27
|
+
```
|
28
|
+
Para calcular a contribuição do trabalhador no setor público:
|
29
|
+
|
30
|
+
```
|
31
|
+
|
32
|
+
gross_salary = 52000.54
|
33
|
+
calculator = InssCalculator::PublicInssCalculator.new(gross_salary)
|
34
|
+
calculator.contribution => 8726.63
|
35
|
+
calculator.salary => 52000.54
|
36
|
+
calculator.net_salary => 43273.91
|
37
|
+
|
38
|
+
```
|
39
|
+
```
|
21
40
|
```
|
22
41
|
### Precisas realizar uma query ao Banco de Dados por grupo de faixa salarial?
|
23
42
|
|
@@ -36,6 +55,21 @@ InssCalculator providencia as seguintes constantes:
|
|
36
55
|
InssCalculator::FOURTH_SALARY_BASE = 4000.04
|
37
56
|
InssCalculator::FOURTH_SALARY_LIMIT = 7786.02
|
38
57
|
|
58
|
+
# Abaixo as bases e os limites do setor público
|
59
|
+
|
60
|
+
InssCalculator::FIFTH_SALARY_BASE = 7786.03
|
61
|
+
InssCalculator::FIFTH_SALARY_LIMIT = 13_333.48
|
62
|
+
|
63
|
+
InssCalculator::SIXTH_SALARY_BASE = 13_333.49
|
64
|
+
InssCalculator::SIXTH_SALARY_LIMIT = 26_666.94
|
65
|
+
|
66
|
+
InssCalculator::SEVENTH_SALARY_BASE = 26_666.95
|
67
|
+
InssCalculator::SEVENTH_SALARY_LIMIT = 52_000.54
|
68
|
+
|
69
|
+
InssCalculator::EIGTH_SALARY_BASE = 52_000.55
|
70
|
+
InssCalculator::EIGTH_SALARY_LIMIT = Float::INFINITY
|
71
|
+
|
72
|
+
|
39
73
|
```
|
40
74
|
|
41
75
|
Desta forma, uma requisição que busca somente a primeira faixa salarial seria:
|
@@ -44,6 +78,21 @@ Desta forma, uma requisição que busca somente a primeira faixa salarial seria:
|
|
44
78
|
YourModel.where("salary <= ?", InssCalculator::FIRST_SALARY_LIMIT)
|
45
79
|
```
|
46
80
|
|
81
|
+
## Decorators
|
82
|
+
|
83
|
+
`InssCalculator::Decorator::Text` explica no formato de texto o que o trabalhador precisa saber.
|
84
|
+
Ideal para uso no parágrafo do HTML. Retire da view esta responsabildade e deixe com este decorator.
|
85
|
+
Você ainda tem acesso à classe original com `#calculator`.
|
86
|
+
|
87
|
+
```
|
88
|
+
calculator = InssCalculator::DiscountPrevidenceCalculator.new(3000)
|
89
|
+
text_decorator = InssCalculator::Decorator::Text.new(calculator)
|
90
|
+
text_decorator.present => "Com o salário de R$ 3.000,00, sua contribuição é de R$ 258,81. Seu salário líquido, portanto, é de R$ 2.741,19."
|
91
|
+
|
92
|
+
text_decorator.calculator => InssCalculator::DiscountPrevidenceCalculator.new(3000)
|
93
|
+
|
94
|
+
```
|
95
|
+
|
47
96
|
## Nota sobre trabalhar com números decimais em Ruby
|
48
97
|
|
49
98
|
Após investigar os resultados dos exemplos contábeis, concluiu-se que os números são truncados.
|
data/lib/dinheiro.rb
ADDED
@@ -0,0 +1,303 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Com base em https://github.com/tapajos/brazilian-rails/blob/master/brdinheiro/lib/brdinheiro/dinheiro.rb
|
4
|
+
class Dinheiro
|
5
|
+
include Comparable
|
6
|
+
|
7
|
+
attr_reader :quantia
|
8
|
+
|
9
|
+
FORMATO_VALIDO_BR = /^([R|r]\$\s*)?(([+-]?\d{1,3}(\.?\d{3})*))?(,\d{0,2})?$/
|
10
|
+
FORMATO_VALIDO_EUA = /^([R|r]\$\s*)?(([+-]?\d{1,3}(,?\d{3})*))?(\.\d{0,2})?$/
|
11
|
+
SEPARADOR_MILHAR = '.'
|
12
|
+
SEPARADOR_FRACIONARIO = ','
|
13
|
+
QUANTIDADE_DIGITOS = 3
|
14
|
+
PRECISAO_DECIMAL = 100
|
15
|
+
|
16
|
+
def initialize(quantia)
|
17
|
+
self.quantia = quantia
|
18
|
+
end
|
19
|
+
|
20
|
+
# Retorna o valor em Float quando uma coleção
|
21
|
+
# ou objeto é convertido para JSON
|
22
|
+
#
|
23
|
+
# Exemplo:
|
24
|
+
# produto = Produto.find 1
|
25
|
+
# produto.to_json // {"nome": "MacBook", "valor": 3500.0}
|
26
|
+
def as_json
|
27
|
+
to_f
|
28
|
+
end
|
29
|
+
|
30
|
+
# Retorna o valor armazenado em string.
|
31
|
+
#
|
32
|
+
# Exemplo:
|
33
|
+
# 1000.to_s ==> '1.000,00'
|
34
|
+
def to_s
|
35
|
+
inteiro_com_milhar(parte_inteira) + parte_decimal
|
36
|
+
end
|
37
|
+
|
38
|
+
# Compara com outro dinheiro se eh igual.
|
39
|
+
#
|
40
|
+
# Exemplo:
|
41
|
+
# um_real = Dinheiro.new(1)
|
42
|
+
# um_real == Dinheiro.new(1) ==> true
|
43
|
+
# um_real == Dinheiro.new(2) ==> false
|
44
|
+
def ==(other)
|
45
|
+
begin
|
46
|
+
other = Dinheiro.new(other) unless other.is_a?(Dinheiro)
|
47
|
+
rescue StandardError
|
48
|
+
return false
|
49
|
+
end
|
50
|
+
@quantia == other.quantia
|
51
|
+
end
|
52
|
+
|
53
|
+
# Compara com outro dinheiro se eh maior ou menor.
|
54
|
+
#
|
55
|
+
# Exemplo:
|
56
|
+
# 1.real < 2.reais ==> true
|
57
|
+
# 1.real > 2.reais ==> false
|
58
|
+
# 2.real < 1.reais ==> false
|
59
|
+
# 2.real > 1.reais ==> true
|
60
|
+
def <=>(other)
|
61
|
+
other = Dinheiro.new(other) unless other.is_a?(Dinheiro)
|
62
|
+
@quantia <=> other.quantia
|
63
|
+
end
|
64
|
+
|
65
|
+
# Retorna a adicao entre dinheiros.
|
66
|
+
#
|
67
|
+
# Exemplo:
|
68
|
+
# 1.real + 1.real == 2.reais
|
69
|
+
# 1.real + 1 == 2.reais
|
70
|
+
def +(other)
|
71
|
+
Dinheiro.new(transforma_em_string_que_represente_a_quantia(@quantia + quantia_de(other)))
|
72
|
+
end
|
73
|
+
|
74
|
+
# Retorna a subtracao entre dinheiros.
|
75
|
+
#
|
76
|
+
# Exemplo:
|
77
|
+
# 10.reais - 2.reais == 8.reais
|
78
|
+
# 10.reais - 2 == 8.reais
|
79
|
+
def -(other)
|
80
|
+
Dinheiro.new(transforma_em_string_que_represente_a_quantia(@quantia - quantia_de(other)))
|
81
|
+
end
|
82
|
+
|
83
|
+
# Retorna a multiplicacao entre dinheiros.
|
84
|
+
#
|
85
|
+
# Exemplo:
|
86
|
+
# 5.reais * 2 == 10.reais
|
87
|
+
# 5.reais * 2.reais == 10.reais
|
88
|
+
def *(other)
|
89
|
+
return Dinheiro.new(to_f * other) unless other.is_a? Dinheiro
|
90
|
+
|
91
|
+
other * to_f
|
92
|
+
end
|
93
|
+
|
94
|
+
# Retorna a divisao entre dinheiros.
|
95
|
+
#
|
96
|
+
# Exemplo:
|
97
|
+
# 5.reais / 2 == (2.5).reais
|
98
|
+
# 5.reais / 2.reais == DivisaPorNaoEscalarError
|
99
|
+
# 5.reais / 0 == ZeroDivisionError
|
100
|
+
#
|
101
|
+
# Veja também o método parcelar
|
102
|
+
def /(other)
|
103
|
+
raise DivisaPorNaoEscalarError unless other.is_a?(Numeric)
|
104
|
+
return @quantia / other if other.zero?
|
105
|
+
|
106
|
+
Dinheiro.new(to_f / other)
|
107
|
+
end
|
108
|
+
|
109
|
+
# Retorna um array de dinheiro com as parcelas
|
110
|
+
#
|
111
|
+
# Exemplo:
|
112
|
+
# 6.reais.parcelar(2) == [3.reais, 3.reais]
|
113
|
+
# 6.reais.parcelar(2.reais) == DisivaPorNaoEscalarError
|
114
|
+
# 6.reais.parcelar(0) == ZeroDivisionError
|
115
|
+
def parcelar(numero_de_parcelar)
|
116
|
+
raise DivisaPorNaoEscalarError unless numero_de_parcelar.is_a?(Integer)
|
117
|
+
|
118
|
+
resto = @quantia % numero_de_parcelar
|
119
|
+
valor_menor = Dinheiro.new((@quantia / numero_de_parcelar) / 100.0)
|
120
|
+
valor_maior = Dinheiro.new((@quantia / numero_de_parcelar + 1) / 100.0)
|
121
|
+
[valor_menor] * (numero_de_parcelar - resto) + [valor_maior] * resto
|
122
|
+
end
|
123
|
+
|
124
|
+
# Escreve o valor por extenso.
|
125
|
+
#
|
126
|
+
# Exemplo:
|
127
|
+
# 1.real.to_extenso ==> 'um real'
|
128
|
+
# (100.58).to_extenso ==> 'cem reais e cinquenta e oito centavos'
|
129
|
+
def to_extenso
|
130
|
+
(@quantia / 100.0).por_extenso_em_reais
|
131
|
+
end
|
132
|
+
|
133
|
+
# Alias para o metodo to_extenso.
|
134
|
+
alias por_extenso to_extenso
|
135
|
+
|
136
|
+
# Alias para o metodo to_extenso.
|
137
|
+
alias por_extenso_em_reais to_extenso
|
138
|
+
|
139
|
+
# Verifica se o valor é zero.
|
140
|
+
def zero?
|
141
|
+
to_f.zero?
|
142
|
+
end
|
143
|
+
|
144
|
+
# Retorna um Float.
|
145
|
+
def to_f
|
146
|
+
to_s.gsub('.', '').gsub(',', '.').to_f
|
147
|
+
end
|
148
|
+
|
149
|
+
def coerce(outro) # :nodoc:
|
150
|
+
[Dinheiro.new(outro), self]
|
151
|
+
end
|
152
|
+
|
153
|
+
# Retorna a própria instância/
|
154
|
+
def real
|
155
|
+
self
|
156
|
+
end
|
157
|
+
|
158
|
+
# Alias para real.
|
159
|
+
alias reais real
|
160
|
+
|
161
|
+
# Retorna uma string formatada com sigla em valor monetário.
|
162
|
+
# Exemplo:
|
163
|
+
# Dinheiro.new(1).real_formatado ==> 'R$ 1,00'
|
164
|
+
# Dinheiro.new(-1).real_formatado ==> 'R$ -1,00'
|
165
|
+
def real_formatado
|
166
|
+
"R$ #{self}"
|
167
|
+
end
|
168
|
+
|
169
|
+
# Alias para real_formatado.
|
170
|
+
alias reais_formatado real_formatado
|
171
|
+
|
172
|
+
# Retorna uma string formatada com sigla em valor contábil.
|
173
|
+
#
|
174
|
+
# Exemplo:
|
175
|
+
# Dinheiro.new(1).real_contabil ==> 'R$ 1,00'
|
176
|
+
# Dinheiro.new(-1).real_contabil ==> 'R$ (1,00)'
|
177
|
+
def real_contabil
|
178
|
+
"R$ #{contabil}"
|
179
|
+
end
|
180
|
+
|
181
|
+
# Alias para real_contabil.
|
182
|
+
alias reais_contabeis real_contabil
|
183
|
+
|
184
|
+
# Retorna uma string formatada sem sigla.
|
185
|
+
#
|
186
|
+
# Exemplo:
|
187
|
+
# Dinheiro.new(1).contabil ==> '1,00'
|
188
|
+
# Dinheiro.new(-1).contabil ==> '(1,00)'
|
189
|
+
def contabil
|
190
|
+
if @quantia >= 0
|
191
|
+
to_s
|
192
|
+
else
|
193
|
+
"(#{to_s[1..]})"
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
197
|
+
# Method missing para retorna um BigDecinal quando chamada .
|
198
|
+
def method_missing(symbol, *args) # :nodoc:
|
199
|
+
# Ex: Chama ao método valor_decimal()
|
200
|
+
if (symbol.to_s =~ /^(.*)_decimal$/) && args.empty?
|
201
|
+
BigDecimal quantia_sem_separacao_milhares.gsub(',', '.')
|
202
|
+
else
|
203
|
+
super.method_missing(symbol, *args)
|
204
|
+
end
|
205
|
+
end
|
206
|
+
|
207
|
+
private
|
208
|
+
|
209
|
+
def quantia_de(outro)
|
210
|
+
outro = outro.to_f if outro.is_a?(BigDecimal)
|
211
|
+
return outro.quantia if outro.is_a?(Dinheiro)
|
212
|
+
|
213
|
+
(outro * 100).round
|
214
|
+
end
|
215
|
+
|
216
|
+
def transforma_em_string_que_represente_a_quantia(quantia)
|
217
|
+
if /^([+-]?)(\d)$/ =~ quantia.to_s
|
218
|
+
return "#{::Regexp.last_match(1)}0.0#{::Regexp.last_match(2)}"
|
219
|
+
end
|
220
|
+
|
221
|
+
/^([+-]?)(\d*)(\d\d)$/ =~ quantia.to_s
|
222
|
+
"#{::Regexp.last_match(1)}#{::Regexp.last_match(2).to_i}.#{::Regexp.last_match(3)}"
|
223
|
+
end
|
224
|
+
|
225
|
+
def quantia=(quantia)
|
226
|
+
@quantia = (quantia * 100).round if quantia.is_a?(Numeric)
|
227
|
+
@quantia = extrai_quantia_como_inteiro(quantia) if quantia.is_a?(String)
|
228
|
+
end
|
229
|
+
|
230
|
+
def parte_inteira
|
231
|
+
quantia_sem_separacao_milhares[0, quantia_sem_separacao_milhares.length - QUANTIDADE_DIGITOS]
|
232
|
+
end
|
233
|
+
|
234
|
+
def parte_decimal
|
235
|
+
quantia_sem_separacao_milhares[-QUANTIDADE_DIGITOS, QUANTIDADE_DIGITOS]
|
236
|
+
end
|
237
|
+
|
238
|
+
def inteiro_com_milhar(inteiro)
|
239
|
+
return inteiro if quantidade_de_passos(inteiro).zero?
|
240
|
+
|
241
|
+
resultado = ''
|
242
|
+
quantidade_de_passos(inteiro).times do |passo|
|
243
|
+
resultado = ".#{inteiro[-QUANTIDADE_DIGITOS + passo * -QUANTIDADE_DIGITOS, QUANTIDADE_DIGITOS]}#{resultado}"
|
244
|
+
end
|
245
|
+
resultado = inteiro[0, digitos_que_sobraram(inteiro)] + resultado
|
246
|
+
resultado.gsub(/^(-?)\./, '\1')
|
247
|
+
end
|
248
|
+
|
249
|
+
def quantia_sem_separacao_milhares
|
250
|
+
format('%.2f', (@quantia.to_f / PRECISAO_DECIMAL)).gsub(SEPARADOR_MILHAR, SEPARADOR_FRACIONARIO)
|
251
|
+
end
|
252
|
+
|
253
|
+
def quantidade_de_passos(inteiro)
|
254
|
+
resultado = inteiro.length / QUANTIDADE_DIGITOS
|
255
|
+
resultado = (resultado - 1) if (inteiro.length % QUANTIDADE_DIGITOS).zero?
|
256
|
+
resultado
|
257
|
+
end
|
258
|
+
|
259
|
+
def digitos_que_sobraram(inteiro)
|
260
|
+
inteiro.length - (quantidade_de_passos(inteiro) * QUANTIDADE_DIGITOS)
|
261
|
+
end
|
262
|
+
|
263
|
+
def quantia_valida?(quantia)
|
264
|
+
return false if quantia.is_a?(String) && !quantia_respeita_formato?(quantia)
|
265
|
+
|
266
|
+
quantia.is_a?(String) || quantia.is_a?(Numeric)
|
267
|
+
end
|
268
|
+
|
269
|
+
def extrai_quantia_como_inteiro(quantia)
|
270
|
+
return sem_milhar(::Regexp.last_match(2), ::Regexp.last_match(5), '.') if FORMATO_VALIDO_BR =~ quantia
|
271
|
+
return unless FORMATO_VALIDO_EUA =~ quantia
|
272
|
+
|
273
|
+
sem_milhar(::Regexp.last_match(2), ::Regexp.last_match(5), ',')
|
274
|
+
end
|
275
|
+
|
276
|
+
def sem_milhar(parte_inteira, parte_decimal, delimitador_de_milhar)
|
277
|
+
(inteiro(parte_inteira, delimitador_de_milhar) + decimal(parte_decimal)).to_i
|
278
|
+
end
|
279
|
+
|
280
|
+
def inteiro(inteiro_com_separador_milhar, separador)
|
281
|
+
return inteiro_com_separador_milhar.gsub(separador, '') unless inteiro_com_separador_milhar.blank?
|
282
|
+
|
283
|
+
''
|
284
|
+
end
|
285
|
+
|
286
|
+
def decimal(parte_fracionaria)
|
287
|
+
unless parte_fracionaria.blank?
|
288
|
+
return sem_delimitador_decimal(parte_fracionaria) if parte_fracionaria.length == 3
|
289
|
+
return "#{sem_delimitador_decimal(parte_fracionaria)}0" if parte_fracionaria.length == 2
|
290
|
+
end
|
291
|
+
'00'
|
292
|
+
end
|
293
|
+
|
294
|
+
def sem_delimitador_decimal(parte_fracionaria)
|
295
|
+
parte_fracionaria.to_s.gsub(/[.|,]/, '')
|
296
|
+
end
|
297
|
+
|
298
|
+
def quantia_respeita_formato?(quantia)
|
299
|
+
return true if FORMATO_VALIDO_BR.match(quantia) || FORMATO_VALIDO_EUA.match(quantia)
|
300
|
+
|
301
|
+
false
|
302
|
+
end
|
303
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module InssCalculator
|
4
|
+
# It extends Calculator contribution to a presentable format.
|
5
|
+
module Decorator
|
6
|
+
require 'forwardable'
|
7
|
+
# InssCalculator::Decorator::Text implements the same Calculator interface
|
8
|
+
# and its #present method presents the contribution result in a text format.
|
9
|
+
class Text
|
10
|
+
extend Forwardable
|
11
|
+
|
12
|
+
def_delegators :@calculator, :salary, :net_salary, :contribution
|
13
|
+
|
14
|
+
attr_reader :calculator
|
15
|
+
|
16
|
+
def initialize(inss_calculator)
|
17
|
+
@calculator = inss_calculator
|
18
|
+
end
|
19
|
+
|
20
|
+
def present
|
21
|
+
"#{salary_text} #{contribution_text} #{net_salary_text}"
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def salary_text
|
27
|
+
"Com o salário de #{Dinheiro.new(calculator.salary).real_formatado},"
|
28
|
+
end
|
29
|
+
|
30
|
+
def contribution_text
|
31
|
+
"sua contribuição é de #{Dinheiro.new(calculator.contribution).real_formatado}."
|
32
|
+
end
|
33
|
+
|
34
|
+
def net_salary_text
|
35
|
+
"Seu salário líquido, portanto, é de #{Dinheiro.new(calculator.net_salary).real_formatado}."
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
module InssCalculator
|
4
4
|
# Based on this insecure protocoll site https://www.coalize.com.br/calculadora-de-inss
|
5
|
+
# Check also the official law https://www.in.gov.br/en/web/dou/-/portaria-interministerial-mps/mf-n-2-de-11-de-janeiro-de-2024-537035232
|
5
6
|
class DiscountPrevidenceCalculator
|
6
7
|
attr_reader :salary
|
7
8
|
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module InssCalculator
|
4
|
+
# EigthDiscountCalculator calculates between its range limit
|
5
|
+
# As the limit is infinity, it always eacrease the contribution.
|
6
|
+
class EigthDiscountCalculator < DiscountCalculatorBase
|
7
|
+
QUOTATION = 0.22
|
8
|
+
|
9
|
+
def contribution
|
10
|
+
return NO_CONTRIBUTION if salary <= salary_base
|
11
|
+
|
12
|
+
return full_contribution if salary > salary_limit
|
13
|
+
|
14
|
+
calculate_contribution
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def calculate_contribution
|
20
|
+
((salary - salary_base) * QUOTATION).truncate(2)
|
21
|
+
end
|
22
|
+
|
23
|
+
def full_contribution
|
24
|
+
((salary_limit - salary_base) * QUOTATION).truncate(2)
|
25
|
+
end
|
26
|
+
|
27
|
+
def salary_limit
|
28
|
+
InssCalculator::EIGTH_SALARY_LIMIT
|
29
|
+
end
|
30
|
+
|
31
|
+
def salary_base
|
32
|
+
InssCalculator::SEVENTH_SALARY_LIMIT
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module InssCalculator
|
4
|
+
# FifthDiscountCalculator calculates between its range limit
|
5
|
+
# In case the salary is beyond this limit, it will use its quotation apply inside the range salary limit
|
6
|
+
class FifthDiscountCalculator < DiscountCalculatorBase
|
7
|
+
QUOTATION = 0.145
|
8
|
+
|
9
|
+
def contribution
|
10
|
+
return NO_CONTRIBUTION if salary <= salary_base
|
11
|
+
|
12
|
+
return full_contribution if salary > salary_limit
|
13
|
+
|
14
|
+
calculate_contribution
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def calculate_contribution
|
20
|
+
((salary - salary_base) * QUOTATION).truncate(2)
|
21
|
+
end
|
22
|
+
|
23
|
+
def full_contribution
|
24
|
+
((salary_limit - salary_base) * QUOTATION).truncate(2)
|
25
|
+
end
|
26
|
+
|
27
|
+
def salary_limit
|
28
|
+
InssCalculator::FIFTH_SALARY_LIMIT
|
29
|
+
end
|
30
|
+
|
31
|
+
def salary_base
|
32
|
+
InssCalculator::FOURTH_SALARY_LIMIT
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module InssCalculator
|
4
|
+
# Based on this insecure protocoll site https://www.coalize.com.br/calculadora-de-inss
|
5
|
+
# Check also the official law https://www.in.gov.br/en/web/dou/-/portaria-interministerial-mps/mf-n-2-de-11-de-janeiro-de-2024-537035232
|
6
|
+
# The public contribution is an extension of the private contribution.
|
7
|
+
# They have the same rules and quotes percentagen until the fourth salary level.
|
8
|
+
class PublicInssCalculator < InssCalculator::DiscountPrevidenceCalculator
|
9
|
+
def contribution
|
10
|
+
super + public_contribution
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def public_contribution
|
16
|
+
[
|
17
|
+
FifthDiscountCalculator.new(salary).contribution,
|
18
|
+
SixthDiscountCalculator.new(salary).contribution,
|
19
|
+
SeventhDiscountCalculator.new(salary).contribution,
|
20
|
+
EigthDiscountCalculator.new(salary).contribution
|
21
|
+
].reduce(:+).round(2)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module InssCalculator
|
4
|
+
# SeventhDiscountCalculator calculates between its range limit
|
5
|
+
# In case the salary is beyond this limit, it will use its quotation apply inside the range salary limit
|
6
|
+
class SeventhDiscountCalculator < DiscountCalculatorBase
|
7
|
+
QUOTATION = 0.19
|
8
|
+
|
9
|
+
def contribution
|
10
|
+
return NO_CONTRIBUTION if salary <= salary_base
|
11
|
+
|
12
|
+
return full_contribution if salary > salary_limit
|
13
|
+
|
14
|
+
calculate_contribution
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def calculate_contribution
|
20
|
+
((salary - salary_base) * QUOTATION).truncate(2)
|
21
|
+
end
|
22
|
+
|
23
|
+
def full_contribution
|
24
|
+
((salary_limit - salary_base) * QUOTATION).truncate(2)
|
25
|
+
end
|
26
|
+
|
27
|
+
def salary_limit
|
28
|
+
InssCalculator::SEVENTH_SALARY_LIMIT
|
29
|
+
end
|
30
|
+
|
31
|
+
def salary_base
|
32
|
+
InssCalculator::SIXTH_SALARY_LIMIT
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module InssCalculator
|
4
|
+
# SixthDiscountCalculator calculates between its range limit
|
5
|
+
# In case the salary is beyond this limit, it will use its quotation apply inside the range salary limit
|
6
|
+
class SixthDiscountCalculator < DiscountCalculatorBase
|
7
|
+
QUOTATION = 0.165
|
8
|
+
|
9
|
+
def contribution
|
10
|
+
return NO_CONTRIBUTION if salary <= salary_base
|
11
|
+
|
12
|
+
return full_contribution if salary > salary_limit
|
13
|
+
|
14
|
+
calculate_contribution
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def calculate_contribution
|
20
|
+
((salary - salary_base) * QUOTATION).truncate(2)
|
21
|
+
end
|
22
|
+
|
23
|
+
def full_contribution
|
24
|
+
((salary_limit - salary_base) * QUOTATION).truncate(2)
|
25
|
+
end
|
26
|
+
|
27
|
+
def salary_limit
|
28
|
+
InssCalculator::SIXTH_SALARY_LIMIT
|
29
|
+
end
|
30
|
+
|
31
|
+
def salary_base
|
32
|
+
InssCalculator::FIFTH_SALARY_LIMIT
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
data/lib/inss_calculator.rb
CHANGED
@@ -1,12 +1,19 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require_relative 'inss_calculator/version'
|
4
|
+
require_relative './dinheiro'
|
4
5
|
require_relative 'inss_calculator/discount_calculator_base'
|
5
6
|
require_relative 'inss_calculator/discount_previdence_calculator'
|
7
|
+
require_relative 'inss_calculator/public_inss_calculator'
|
6
8
|
require_relative 'inss_calculator/first_discount_calculator'
|
7
9
|
require_relative 'inss_calculator/second_discount_calculator'
|
8
10
|
require_relative 'inss_calculator/third_discount_calculator'
|
9
11
|
require_relative 'inss_calculator/fourth_discount_calculator'
|
12
|
+
require_relative 'inss_calculator/fifth_discount_calculator'
|
13
|
+
require_relative 'inss_calculator/sixth_discount_calculator'
|
14
|
+
require_relative 'inss_calculator/seventh_discount_calculator'
|
15
|
+
require_relative 'inss_calculator/eigth_discount_calculator'
|
16
|
+
require_relative 'inss_calculator/decorator/text'
|
10
17
|
|
11
18
|
module InssCalculator
|
12
19
|
class Error < StandardError; end
|
@@ -22,4 +29,16 @@ module InssCalculator
|
|
22
29
|
|
23
30
|
FOURTH_SALARY_BASE = 4000.04
|
24
31
|
FOURTH_SALARY_LIMIT = 7786.02
|
32
|
+
|
33
|
+
FIFTH_SALARY_BASE = 7786.03
|
34
|
+
FIFTH_SALARY_LIMIT = 13_333.48
|
35
|
+
|
36
|
+
SIXTH_SALARY_BASE = 13_333.49
|
37
|
+
SIXTH_SALARY_LIMIT = 26_666.94
|
38
|
+
|
39
|
+
SEVENTH_SALARY_BASE = 26_666.95
|
40
|
+
SEVENTH_SALARY_LIMIT = 52_000.54
|
41
|
+
|
42
|
+
EIGTH_SALARY_BASE = 52_000.55
|
43
|
+
EIGTH_SALARY_LIMIT = Float::INFINITY
|
25
44
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: inss_calculator
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Paulo Felipe Souza
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-12-23 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: Calcula o valor a descontar de acordo com a faixa salarial. Os novos
|
14
14
|
valores corrente em 2024.
|
@@ -29,12 +29,19 @@ files:
|
|
29
29
|
- README.md
|
30
30
|
- Rakefile
|
31
31
|
- inss_calculator.gemspec
|
32
|
+
- lib/dinheiro.rb
|
32
33
|
- lib/inss_calculator.rb
|
34
|
+
- lib/inss_calculator/decorator/text.rb
|
33
35
|
- lib/inss_calculator/discount_calculator_base.rb
|
34
36
|
- lib/inss_calculator/discount_previdence_calculator.rb
|
37
|
+
- lib/inss_calculator/eigth_discount_calculator.rb
|
38
|
+
- lib/inss_calculator/fifth_discount_calculator.rb
|
35
39
|
- lib/inss_calculator/first_discount_calculator.rb
|
36
40
|
- lib/inss_calculator/fourth_discount_calculator.rb
|
41
|
+
- lib/inss_calculator/public_inss_calculator.rb
|
37
42
|
- lib/inss_calculator/second_discount_calculator.rb
|
43
|
+
- lib/inss_calculator/seventh_discount_calculator.rb
|
44
|
+
- lib/inss_calculator/sixth_discount_calculator.rb
|
38
45
|
- lib/inss_calculator/third_discount_calculator.rb
|
39
46
|
- lib/inss_calculator/version.rb
|
40
47
|
- sig/inss_calculator.rbs
|
@@ -60,7 +67,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
60
67
|
- !ruby/object:Gem::Version
|
61
68
|
version: '0'
|
62
69
|
requirements: []
|
63
|
-
rubygems_version: 3.
|
70
|
+
rubygems_version: 3.5.17
|
64
71
|
signing_key:
|
65
72
|
specification_version: 4
|
66
73
|
summary: Calculadora de desconto do INSS
|