br_documents 1.0.1 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 37a56fa2cb38a6063a8c08b28726d881d7caee787207bf87fe9707ec811a1220
4
- data.tar.gz: dce5488d709fd8f6cb1b2c31a5fe7ddcec2cab8c52d19f7b7fe5bf0547390442
3
+ metadata.gz: dbede38202b97b16fe272f05e4d59604e624f327872bca314d034d740051f7a7
4
+ data.tar.gz: '09b3a133952daa79762a8cc41de9711a8225c119cff7d1ccbc14c9140fd82568'
5
5
  SHA512:
6
- metadata.gz: e0ebeeda069d76cb831a60b381c4d1232d7a85085a68b429925111f5af0d8d014704d2bb8a5b28e8903903d85bedcd497c1fded581f8d36724f9a4dbc09e78b2
7
- data.tar.gz: acde384b7f7fd58783d3d3990c5e58f0c1dc9db963f868262ee28c11a97433ada71b626cb9e9eb4cf690ca88c4ab929b1e50629ee198676309984ddd0c54268a
6
+ metadata.gz: 22c6aa91c7dec4d76bc49a94f7ca6fd87b97435dd8e01821901b8b6c229b5cbb29ca8d94f7ed95bd9ec6b0bef512a6c70399f83003cb2035b1a1c7f11fb722a1
7
+ data.tar.gz: cbe38b6fa404b38d1a822ff758ae33a735c50f60e0c0ad0e5c1e3975c6d90aadb2e883376bba661fa75a8b85012ef1da86a69ac1d6ca57aa9d824e48ddfe0a9c
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- br_documents (1.0.1)
4
+ br_documents (1.1.0)
5
5
  activemodel (>= 4.0.0)
6
6
  i18n (>= 0.6.5)
7
7
 
data/README.md CHANGED
@@ -200,6 +200,16 @@ RAILS_ENV | no | no | yes | no | test
200
200
  $ bundle exec rake release # Create tag vX.X.X, build and push br_documents-X.X.X.gem to Rubygems
201
201
  ```
202
202
 
203
+ 3. On Github generate `release` or `tag`
204
+
205
+ * Under your repository name, click [Releases](https://github.com/asseinfo/nf-e/releases);
206
+ * Click at `Draft a new release`;
207
+ * Type a version number for your release; example: v4.0.1
208
+ * Target `master`
209
+ * Type a title for your release; example: 4.0.1 (March 3, 2020)
210
+ * Click at `Generate release note` [optional]
211
+ * Click at `Publish release`
212
+
203
213
  You can build or install using one of the above tasks
204
214
 
205
215
  $ bundle exec rake build # Build br_documents-X.X.X.gem into the pkg directory
@@ -8,7 +8,7 @@ module BrDocuments
8
8
  private
9
9
 
10
10
  def format_regex
11
- /^(\d{2}\.\d{3}\.\d{3}\/\d{4}-\d{2})$|^(\d{14})$/
11
+ /^([A-Z0-9]{2}\.[A-Z0-9]{3}\.[A-Z0-9]{3}\/[A-Z0-9]{4}-\d{2})$|^([A-Z0-9]{12}\d{2})$/
12
12
  end
13
13
 
14
14
  def weights_for_digital_check
@@ -16,7 +16,8 @@ module BrDocuments
16
16
  end
17
17
 
18
18
  def format_number
19
- @number.sub(/(\d{2})(\d{3})(\d{3})(\d{4})(\d{2})/, '\\1.\\2.\\3/\\4-\\5')
19
+ mask = /\A([A-Z0-9]{2})([A-Z0-9]{3})([A-Z0-9]{3})([A-Z0-9]{4})(\d{2})\z/
20
+ remove_mask.sub(mask, '\\1.\\2.\\3/\\4-\\5')
20
21
  end
21
22
  end
22
23
  end
@@ -24,18 +24,18 @@ module BrDocuments
24
24
  end
25
25
 
26
26
  def sequence_of_equal_numbers?
27
- number_without_mask.chars.uniq.length == 1
27
+ remove_mask.chars.uniq.length == 1
28
28
  end
29
29
 
30
30
  def valid_check_digit?
31
31
  weight1, weight2 = weights_for_digital_check
32
32
 
33
- digital_check1 = generate_check_digit(number_without_mask, weight1)
34
- digital_check2 = generate_check_digit(number_without_mask, weight2)
33
+ digital_check1 = generate_check_digit(remove_mask, weight1)
34
+ digital_check2 = generate_check_digit(remove_mask, weight2)
35
35
  @number[-2, 2] == "#{digital_check1}#{digital_check2}"
36
36
  end
37
37
 
38
- def number_without_mask
38
+ def remove_mask
39
39
  @number.gsub(/[\.\/-]/, '')
40
40
  end
41
41
  end
@@ -7,10 +7,22 @@ module BrDocuments
7
7
  mod < 2 ? 0 : (11 - mod)
8
8
  end
9
9
 
10
+ # Converts each character to a numeric value for the modulo-11 calculation.
11
+ #
12
+ # The new CNPJ format (Receita Federal, effective July 2026) allows uppercase
13
+ # letters in the first 12 characters (root + filial). `char.to_i` can't handle
14
+ # this — it returns 0 for any non-digit.
15
+ #
16
+ # `char.ord - 48` works because 48 is the ASCII code of '0', giving us:
17
+ # '0'.ord - 48 # => 0 '9'.ord - 48 # => 9 (same as char.to_i)
18
+ # 'A'.ord - 48 # => 17 'B'.ord - 48 # => 18 'Z'.ord - 48 # => 42
19
+ #
20
+ # This is the character mapping defined by the Receita Federal specification
21
+ # and is backwards-compatible with CPF (digits only).
10
22
  def reduce_weights(values, weights)
11
23
  sum = 0
12
24
  weights.each_index do |i|
13
- sum += weights[i] * values[i].to_i
25
+ sum += weights[i] * (values[i].ord - 48)
14
26
  end
15
27
  sum
16
28
  end
@@ -25,18 +25,18 @@ module BrDocuments
25
25
  end
26
26
 
27
27
  def sequence_of_equal_numbers?
28
- number_without_mask.chars.uniq.length == 1
28
+ remove_mask.chars.uniq.length == 1
29
29
  end
30
30
 
31
- def number_without_mask
32
- @number_without_mask ||= @number.delete('.')
31
+ def remove_mask
32
+ @remove_mask ||= @number.delete('.')
33
33
  end
34
34
 
35
35
  def valid_check_digit?
36
36
  weights = [9, 8, 7, 6, 5, 4, 3, 2]
37
37
 
38
- check_digit = generate_check_digit(number_without_mask, weights)
39
- number_without_mask[8] == check_digit.to_s
38
+ check_digit = generate_check_digit(remove_mask, weights)
39
+ remove_mask[8] == check_digit.to_s
40
40
  end
41
41
 
42
42
  def format_number
@@ -1,3 +1,3 @@
1
1
  module BrDocuments
2
- VERSION = '1.0.1'.freeze
2
+ VERSION = '1.1.0'.freeze
3
3
  end
@@ -7,6 +7,11 @@ describe BrDocuments::CnpjCpf::Cnpj do
7
7
  expect(cnpj.formatted).to eq '04.001.155/0001-01'
8
8
  end
9
9
 
10
+ it 'returns a formatted alphanumeric number' do
11
+ cnpj = described_class.new('12ABC34501DE35')
12
+ expect(cnpj.formatted).to eq '12.ABC.345/01DE-35'
13
+ end
14
+
10
15
  context 'when is invalid' do
11
16
  it 'returns an empty string' do
12
17
  cnpj = described_class.new('123')
@@ -56,4 +61,44 @@ describe BrDocuments::CnpjCpf::Cnpj do
56
61
  expect(cnpj).to be_valid
57
62
  end
58
63
  end
64
+
65
+ context 'when is alphanumeric CNPJ' do
66
+ it 'is valid with correct alphanumeric number' do
67
+ ['12ABC34501DE35', '12.ABC.345/01DE-35'].each do |number|
68
+ cnpj = described_class.new(number)
69
+ expect(cnpj).to be_valid
70
+ end
71
+ end
72
+
73
+ it 'is valid when root is alphanumeric' do
74
+ ['ABCDEFGH000195', 'AB.CDE.FGH/0001-95'].each do |number|
75
+ cnpj = described_class.new(number)
76
+ expect(cnpj).to be_valid
77
+ end
78
+ end
79
+
80
+ it 'is valid when filial is alphanumeric' do
81
+ ['12345678ABCD06', '12.345.678/ABCD-06'].each do |number|
82
+ cnpj = described_class.new(number)
83
+ expect(cnpj).to be_valid
84
+ end
85
+ end
86
+
87
+ it 'is invalid with wrong check digit' do
88
+ cnpj = described_class.new('12ABC34501DE99')
89
+ expect(cnpj).not_to be_valid
90
+ end
91
+
92
+ it 'is invalid with lowercase input' do
93
+ cnpj = described_class.new('12abc34501de35')
94
+ expect(cnpj).not_to be_valid
95
+ end
96
+
97
+ it 'is invalid with special characters' do
98
+ ['12AB!34501DE35', '12ABC345@1DE35'].each do |number|
99
+ cnpj = described_class.new(number)
100
+ expect(cnpj).not_to be_valid
101
+ end
102
+ end
103
+ end
59
104
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: br_documents
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.1
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - ASSEINFO - Sistemas de Informação