br_danfe 0.15.1 → 0.16.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.
Files changed (57) hide show
  1. checksums.yaml +4 -4
  2. data/.tool-versions +1 -0
  3. data/Gemfile.lock +35 -22
  4. data/Guardfile +2 -2
  5. data/README.md +23 -0
  6. data/br_danfe.gemspec +3 -2
  7. data/lib/br_danfe.rb +1 -1
  8. data/lib/br_danfe/danfe_lib/nfce.rb +1 -1
  9. data/lib/br_danfe/danfe_lib/nfe_lib/dest.rb +1 -1
  10. data/lib/br_danfe/danfe_lib/nfe_lib/emit_header.rb +1 -1
  11. data/lib/br_danfe/document_builder.rb +1 -1
  12. data/lib/br_danfe/helper.rb +7 -9
  13. data/lib/br_danfe/mdfe.rb +55 -0
  14. data/lib/br_danfe/mdfe_lib/authorization_protocol.rb +24 -0
  15. data/lib/br_danfe/mdfe_lib/document.rb +26 -0
  16. data/lib/br_danfe/mdfe_lib/drivers.rb +70 -0
  17. data/lib/br_danfe/mdfe_lib/fisco_control.rb +40 -0
  18. data/lib/br_danfe/mdfe_lib/header.rb +78 -0
  19. data/lib/br_danfe/mdfe_lib/mdfe_identification.rb +69 -0
  20. data/lib/br_danfe/mdfe_lib/notes.rb +94 -0
  21. data/lib/br_danfe/mdfe_lib/totalizer.rb +57 -0
  22. data/lib/br_danfe/mdfe_lib/vehicles.rb +80 -0
  23. data/lib/br_danfe/qr_code.rb +22 -0
  24. data/lib/br_danfe/version.rb +1 -1
  25. data/spec/br_danfe/danfe_lib/nfe_lib/infadic_spec.rb +3 -3
  26. data/spec/br_danfe/helper_spec.rb +12 -0
  27. data/spec/br_danfe/mdfe_lib/authorization_protocol_spec.rb +35 -0
  28. data/spec/br_danfe/mdfe_lib/document_spec.rb +20 -0
  29. data/spec/br_danfe/mdfe_lib/drivers_spec.rb +88 -0
  30. data/spec/br_danfe/mdfe_lib/fisco_control_spec.rb +55 -0
  31. data/spec/br_danfe/mdfe_lib/header_spec.rb +126 -0
  32. data/spec/br_danfe/mdfe_lib/mdfe_identification_spec.rb +104 -0
  33. data/spec/br_danfe/mdfe_lib/notes_spec.rb +97 -0
  34. data/spec/br_danfe/mdfe_lib/totalizer_spec.rb +63 -0
  35. data/spec/br_danfe/mdfe_lib/vehicles_spec.rb +66 -0
  36. data/spec/br_danfe/mdfe_spec.rb +46 -0
  37. data/spec/br_danfe/{danfe_lib/nfce_lib/qr_code_spec.rb → qr_code_spec.rb} +10 -5
  38. data/spec/fixtures/mdfe/lib/document#render.pdf +0 -0
  39. data/spec/fixtures/mdfe/lib/document#text.align.pdf +0 -0
  40. data/spec/fixtures/mdfe/lib/document#text.pad.pdf +0 -0
  41. data/spec/fixtures/mdfe/lib/document#text.simple.pdf +0 -0
  42. data/spec/fixtures/mdfe/lib/document#text.size.pdf +0 -0
  43. data/spec/fixtures/mdfe/lib/document#text.style.pdf +0 -0
  44. data/spec/fixtures/mdfe/lib/fisco_control#barcode.pdf +0 -0
  45. data/spec/fixtures/mdfe/lib/header#render-qr-code.pdf +0 -0
  46. data/spec/fixtures/mdfe/lib/header#render-with_logo.pdf +0 -0
  47. data/spec/fixtures/mdfe/lib/header#render-without_logo.pdf +0 -0
  48. data/spec/fixtures/mdfe/lib/mdfe-with-multiple-pages.pdf +1945 -0
  49. data/spec/fixtures/mdfe/lib/mdfe.fixture.pdf +1286 -0
  50. data/spec/fixtures/mdfe/lib/notes#render-big-aditional-information.pdf +1943 -0
  51. data/spec/fixtures/mdfe/lib/xml-mdfe-multiples-pages.xml +116 -0
  52. data/spec/fixtures/mdfe/lib/xml-mdfe.xml +250 -0
  53. data/spec/fixtures/qr_code/qr_code#render.pdf +0 -0
  54. metadata +83 -34
  55. data/lib/br_danfe/danfe_lib/nfce_lib/qr_code.rb +0 -25
  56. data/lib/br_danfe/danfe_lib/nfe_lib/cep.rb +0 -11
  57. data/spec/br_danfe/danfe_lib/nfe_lib/cep_spec.rb +0 -10
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 210c7c1c3a0ea98ed48753e1432c91ae8f4795400d5df40d7d9c2e0a91d4c502
4
- data.tar.gz: 611c666027eca9cac90640753446085f58b4b9deacc43c8d0df5f7150d623a1f
3
+ metadata.gz: 447b593d2df30cc919fbc59e6453d794c1a60319a256357f650023e51bc6f369
4
+ data.tar.gz: a1d696214eeb03ef958c001870427cada4d826fabeb09cb24b1174a3ff19107e
5
5
  SHA512:
6
- metadata.gz: 4c04ab16fdac8a9285024a018b2c23cdd5d65c6e2748b8cafa9e97ec67cf10f49cc0e0766a475e060f2c65793a6400795988e299d6931bd4cacb2ed01d18092f
7
- data.tar.gz: b894f40fba2376bd795beadfbf47dabe2db2c9d7a40e69c728d29550397c6df2baf14acb39ff73cface9df9ffd2de7832b2762647ccf2ab6715134fcfb740c82
6
+ metadata.gz: b7ca6b73178f85c69d8e40334cfdffe2a1840de6c4910c1a40d09f97df05624226a1c5e8e285b5774fcceac78646e32194ce372456a038a66f52f67cb6202f83
7
+ data.tar.gz: 480fbe9dedac710566471b56a87ec05598bde90232b49fce063462739f249be6084944f397b8424661a2201ce086c77b8ae76c0ceb3315c2b7bf12c0757dfd30
data/.tool-versions ADDED
@@ -0,0 +1 @@
1
+ ruby 2.7.4
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- br_danfe (0.15.1)
4
+ br_danfe (0.16.0)
5
5
  barby (= 0.6.8)
6
6
  br_documents (>= 0.1.3)
7
7
  i18n (>= 0.8.6)
@@ -13,15 +13,17 @@ PATH
13
13
  GEM
14
14
  remote: https://rubygems.org/
15
15
  specs:
16
- activemodel (6.1.3.2)
17
- activesupport (= 6.1.3.2)
18
- activesupport (6.1.3.2)
16
+ Ascii85 (1.1.0)
17
+ activemodel (6.1.4)
18
+ activesupport (= 6.1.4)
19
+ activesupport (6.1.4)
19
20
  concurrent-ruby (~> 1.0, >= 1.0.2)
20
21
  i18n (>= 1.6, < 2)
21
22
  minitest (>= 5.1)
22
23
  tzinfo (~> 2.0)
23
24
  zeitwerk (~> 2.3)
24
- ast (2.4.0)
25
+ afm (0.2.2)
26
+ ast (2.4.2)
25
27
  barby (0.6.8)
26
28
  br_documents (0.2.0)
27
29
  activemodel (>= 4.0.0)
@@ -31,9 +33,9 @@ GEM
31
33
  coderay (1.1.3)
32
34
  concurrent-ruby (1.1.9)
33
35
  diff-lcs (1.4.4)
34
- docile (1.3.2)
35
- ffi (1.13.1)
36
- formatador (0.2.5)
36
+ docile (1.4.0)
37
+ ffi (1.15.3)
38
+ formatador (0.3.0)
37
39
  guard (2.16.2)
38
40
  formatador (>= 0.2.4)
39
41
  listen (>= 2.7, < 4.0)
@@ -48,11 +50,12 @@ GEM
48
50
  guard (~> 2.1)
49
51
  guard-compat (~> 1.1)
50
52
  rspec (>= 2.99.0, < 4.0)
53
+ hashery (2.1.2)
51
54
  i18n (1.8.10)
52
55
  concurrent-ruby (~> 1.0)
53
56
  jaro_winkler (1.5.4)
54
- json (2.3.0)
55
- listen (3.2.1)
57
+ json (2.5.1)
58
+ listen (3.5.1)
56
59
  rb-fsevent (~> 0.10, >= 0.10.3)
57
60
  rb-inotify (~> 0.9, >= 0.9.10)
58
61
  lumberjack (1.2.8)
@@ -66,23 +69,31 @@ GEM
66
69
  notiffany (0.1.3)
67
70
  nenv (~> 0.1)
68
71
  shellany (~> 0.0)
69
- parallel (1.19.1)
70
- parser (2.7.0.4)
71
- ast (~> 2.4.0)
72
+ parallel (1.20.1)
73
+ parser (3.0.2.0)
74
+ ast (~> 2.4.1)
72
75
  pdf-core (0.9.0)
76
+ pdf-inspector (1.3.0)
77
+ pdf-reader (>= 1.0, < 3.0.a)
78
+ pdf-reader (2.5.0)
79
+ Ascii85 (~> 1.0)
80
+ afm (~> 0.2.1)
81
+ hashery (~> 2.0)
82
+ ruby-rc4
83
+ ttfunk
73
84
  prawn (2.4.0)
74
85
  pdf-core (~> 0.9.0)
75
86
  ttfunk (~> 1.7)
76
87
  prawn-table (0.2.2)
77
88
  prawn (>= 1.3.0, < 3.0.0)
78
- pry (0.13.1)
89
+ pry (0.14.1)
79
90
  coderay (~> 1.1)
80
91
  method_source (~> 1.0)
81
- psych (3.1.0)
92
+ psych (4.0.1)
82
93
  racc (1.5.2)
83
94
  rainbow (3.0.0)
84
95
  rake (13.0.1)
85
- rb-fsevent (0.10.4)
96
+ rb-fsevent (0.11.0)
86
97
  rb-inotify (0.10.1)
87
98
  ffi (~> 1.0)
88
99
  rqrcode (1.1.2)
@@ -93,15 +104,15 @@ GEM
93
104
  rspec-core (~> 3.10.0)
94
105
  rspec-expectations (~> 3.10.0)
95
106
  rspec-mocks (~> 3.10.0)
96
- rspec-core (3.10.0)
107
+ rspec-core (3.10.1)
97
108
  rspec-support (~> 3.10.0)
98
- rspec-expectations (3.10.0)
109
+ rspec-expectations (3.10.1)
99
110
  diff-lcs (>= 1.2.0, < 2.0)
100
111
  rspec-support (~> 3.10.0)
101
- rspec-mocks (3.10.0)
112
+ rspec-mocks (3.10.2)
102
113
  diff-lcs (>= 1.2.0, < 2.0)
103
114
  rspec-support (~> 3.10.0)
104
- rspec-support (3.10.0)
115
+ rspec-support (3.10.2)
105
116
  rubocop (0.67.0)
106
117
  jaro_winkler (~> 1.5.1)
107
118
  parallel (~> 1.10)
@@ -112,14 +123,15 @@ GEM
112
123
  unicode-display_width (>= 1.4.0, < 1.6)
113
124
  rubocop-performance (1.1.0)
114
125
  rubocop (>= 0.67.0)
115
- ruby-progressbar (1.10.1)
126
+ ruby-progressbar (1.11.0)
127
+ ruby-rc4 (0.1.5)
116
128
  shellany (0.0.1)
117
129
  simplecov (0.17.1)
118
130
  docile (~> 1.1)
119
131
  json (>= 1.8, < 3)
120
132
  simplecov-html (~> 0.10.0)
121
133
  simplecov-html (0.10.2)
122
- thor (1.0.1)
134
+ thor (1.1.0)
123
135
  ttfunk (1.7.0)
124
136
  tzinfo (2.0.4)
125
137
  concurrent-ruby (~> 1.0)
@@ -134,6 +146,7 @@ DEPENDENCIES
134
146
  byebug (= 11.1.3)
135
147
  guard (~> 2.16.2)
136
148
  guard-rspec
149
+ pdf-inspector (~> 1.3.0)
137
150
  rake (= 13.0.1)
138
151
  rspec (= 3.10.0)
139
152
  rubocop (= 0.67.0)
data/Guardfile CHANGED
@@ -1,5 +1,5 @@
1
- guard :rspec, cmd: "bundle exec rspec" do
2
- require "guard/rspec/dsl"
1
+ guard :rspec, cmd: 'bundle exec rspec' do
2
+ require 'guard/rspec/dsl'
3
3
  dsl = Guard::RSpec::Dsl.new(self)
4
4
 
5
5
  # RSpec files
data/README.md CHANGED
@@ -88,6 +88,29 @@ XML version | Supported?
88
88
  end
89
89
  end
90
90
 
91
+ ### DAMDFE - _Documento Auxiliar do Manifesto Eletrônico de Documentos Fiscais_
92
+
93
+ #### Usage in Ruby
94
+
95
+ xml = File.read("mdfe.xml")
96
+
97
+ mdfe = BrDanfe::Mdfe.new(xml)
98
+ mdfe.save_pdf("mdfe.pdf")
99
+
100
+ #### Usage in Rails Controller
101
+
102
+ class MdfeController < ApplicationController
103
+ def new
104
+ mdfe = Mdfe.find(params[:id])
105
+ xml_as_string = mdfe.generate_xml # your method that generates the MDF-e's xml
106
+
107
+ mdfe = BrDanfe::Mdfe.new(xml_as_string)
108
+
109
+ send_data mdfe.render_pdf, filename: "mdfe.pdf", type: "application/pdf"
110
+ end
111
+ end
112
+
113
+
91
114
  ## I18n
92
115
 
93
116
  By default, your rails application must be configured to `pt-Br`.
data/br_danfe.gemspec CHANGED
@@ -25,12 +25,13 @@ Gem::Specification.new do |spec|
25
25
  spec.add_dependency 'rqrcode', '~> 1.1.1'
26
26
 
27
27
  spec.add_development_dependency 'byebug', '11.1.3'
28
+ spec.add_development_dependency 'guard', '~> 2.16.2'
29
+ spec.add_development_dependency 'guard-rspec'
30
+ spec.add_development_dependency 'pdf-inspector', '~> 1.3.0'
28
31
  spec.add_development_dependency 'rake', '13.0.1'
29
32
  spec.add_development_dependency 'rspec', '3.10.0'
30
33
  spec.add_development_dependency 'rubocop', '0.67.0'
31
34
  spec.add_development_dependency 'rubocop-performance', '~> 1.1.0'
32
35
  spec.add_development_dependency 'simplecov', '0.17.1'
33
36
  spec.add_development_dependency 'simplecov-html', '0.10.2'
34
- spec.add_development_dependency 'guard', '~> 2.16.2'
35
- spec.add_development_dependency 'guard-rspec'
36
37
  end
data/lib/br_danfe.rb CHANGED
@@ -16,6 +16,6 @@ Prawn::Font::AFM.hide_m17n_warning = true
16
16
 
17
17
  module BrDanfe
18
18
  def self.root_path
19
- File.expand_path('../..',__FILE__)
19
+ File.expand_path('../..', __FILE__)
20
20
  end
21
21
  end
@@ -31,7 +31,7 @@ module BrDanfe
31
31
  NfceLib::Key.new(@document, xml).render
32
32
  NfceLib::Recipient.new(@document, xml).render
33
33
  NfceLib::NfceIdentification.new(@document, xml).render
34
- NfceLib::QrCode.new(@document, xml).render
34
+ BrDanfe::QrCode.new(pdf: @document, xml: xml, qr_code_tag: xml['qrCode'], box_size: 3.cm).render
35
35
  NfceLib::Footer.new(@document, xml).render(footer_info)
36
36
 
37
37
  render_no_fiscal_value(xml)
@@ -63,7 +63,7 @@ module BrDanfe
63
63
  end
64
64
 
65
65
  def cep
66
- Cep.format(@xml['enderDest/CEP'])
66
+ BrDanfe::Helper.format_cep(@xml['enderDest/CEP'])
67
67
  end
68
68
 
69
69
  def render_line3
@@ -50,7 +50,7 @@ module BrDanfe
50
50
  end
51
51
 
52
52
  def cep
53
- Cep.format(@xml['enderEmit/CEP'])
53
+ BrDanfe::Helper.format_cep(@xml['enderEmit/CEP'])
54
54
  end
55
55
 
56
56
  def logo
@@ -7,7 +7,7 @@ module BrDanfe
7
7
  bold: "#{BrDanfe.root_path}/fonts/tinos_bold.ttf",
8
8
  italic: "#{BrDanfe.root_path}/fonts/tinos_italic.ttf",
9
9
  bold_italic: "#{BrDanfe.root_path}/fonts/tinos_bold_italic.ttf",
10
- normal: "#{BrDanfe.root_path}/fonts/tinos.ttf",
10
+ normal: "#{BrDanfe.root_path}/fonts/tinos.ttf"
11
11
  }
12
12
 
13
13
  document
@@ -23,15 +23,9 @@ module BrDanfe
23
23
  integer_part + ',' + decimal_part
24
24
  end
25
25
 
26
- def self.format_datetime(xml_datetime)
27
- formated = ''
28
-
29
- unless xml_datetime.empty?
30
- date = DateTime.strptime(xml_datetime, '%Y-%m-%dT%H:%M:%S')
31
- formated = date.strftime('%d/%m/%Y %H:%M:%S')
32
- end
33
-
34
- formated
26
+ def self.format_datetime(xml_datetime, with_time_zone: false)
27
+ formated = with_time_zone ? '%d/%m/%Y %H:%M:%S%:z' : '%d/%m/%Y %H:%M:%S'
28
+ xml_datetime.present? ? Time.parse(xml_datetime).strftime(formated) : ''
35
29
  end
36
30
 
37
31
  def self.nfe?(xml)
@@ -39,5 +33,9 @@ module BrDanfe
39
33
 
40
34
  xml['ide > mod'] == nfe_code
41
35
  end
36
+
37
+ def self.format_cep(cep)
38
+ cep.sub(/(\d{2})(\d{3})(\d{3})/, '\\1.\\2-\\3')
39
+ end
42
40
  end
43
41
  end
@@ -0,0 +1,55 @@
1
+ module BrDanfe
2
+ BLACK_COLOR = '000000'.freeze
3
+ GRAY_COLOR = 'A0A0A0'.freeze
4
+ LIGHT_GRAY_COLOR = 'ECECEC'.freeze
5
+
6
+ class Mdfe
7
+ attr_reader :logo_options
8
+
9
+ def initialize(xml)
10
+ @xml = xml
11
+ @pdf = MdfeLib::Document.new
12
+ @logo_options = BrDanfe::Logo::Config.new
13
+ end
14
+
15
+ def save_pdf(filename)
16
+ generate
17
+ @pdf.render_file(filename)
18
+ end
19
+
20
+ def render_pdf
21
+ generate
22
+ @pdf.render
23
+ end
24
+
25
+ private
26
+
27
+ def generate
28
+ generate_on_first_page
29
+ generate_on_each_page
30
+ end
31
+
32
+ def generate_on_first_page
33
+ MdfeLib::Totalizer.new(@pdf, @xml).generate
34
+ MdfeLib::AuthorizationProtocol.new(@pdf, @xml).generate
35
+ MdfeLib::FiscoControl.new(@pdf, @xml).generate
36
+ MdfeLib::Vehicles.new(@pdf, @xml).generate
37
+ MdfeLib::Drivers.new(@pdf, @xml).generate
38
+ MdfeLib::Notes.new(@pdf, @xml).generate
39
+ end
40
+
41
+ def generate_on_each_page
42
+ header = MdfeLib::Header.new(@pdf, @xml, @logo_options.logo, @logo_options.logo_dimensions)
43
+ mdfe_identification = MdfeLib::MdfeIdentification.new(@pdf, @xml)
44
+
45
+ @pdf.page_count.times do |i|
46
+ page = i + 1
47
+
48
+ @pdf.go_to_page page
49
+
50
+ header.generate
51
+ mdfe_identification.generate(page)
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,24 @@
1
+ module BrDanfe
2
+ module MdfeLib
3
+ class AuthorizationProtocol
4
+ def initialize(pdf, xml)
5
+ @pdf = pdf
6
+ @xml = xml
7
+ end
8
+
9
+ def generate
10
+ authorization
11
+ end
12
+
13
+ private
14
+
15
+ def authorization
16
+ title = 'Protocolo de autorização'
17
+ protocol = @xml['infProt/nProt'] + ' - ' + Helper.format_datetime(@xml['infProt/dhRecbto'], with_time_zone: true)
18
+
19
+ @pdf.text_box(title, size: 9, align: :left, style: :bold, at: [0, 510])
20
+ @pdf.text_box(protocol, size: 11, align: :left, at: [0, 500])
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,26 @@
1
+ module BrDanfe
2
+ module MdfeLib
3
+ class Document
4
+ def initialize
5
+ @document = BrDanfe::DocumentBuilder.build(
6
+ page_size: 'A4',
7
+ page_layout: :portrait
8
+ )
9
+
10
+ @document.font 'tinos'
11
+ end
12
+
13
+ def method_missing(method_name, *args, &block)
14
+ if @document.respond_to? method_name
15
+ @document.send method_name, *args, &block
16
+ else
17
+ super
18
+ end
19
+ end
20
+
21
+ def respond_to_missing?(method_name, include_private = false)
22
+ @document.respond_to?(method_name, include_private) || super
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,70 @@
1
+ module BrDanfe
2
+ module MdfeLib
3
+ class Drivers
4
+ def initialize(pdf, xml)
5
+ @pdf = pdf
6
+ @xml = xml
7
+ end
8
+
9
+ def generate
10
+ @pdf.move_cursor_to 460
11
+ title
12
+ table_titles
13
+ generate_drivers
14
+ end
15
+
16
+ private
17
+
18
+ def title
19
+ title = 'Condutor'
20
+
21
+ @pdf.text_box(title, size: 12, align: :left, style: :bold, at: [250, @pdf.cursor])
22
+ end
23
+
24
+ def table_titles
25
+ cpf = 'CPF'
26
+ name = 'Nome'
27
+
28
+ @pdf.stroke_color GRAY_COLOR
29
+ @pdf.move_down 20
30
+ @pdf.text_box(cpf, size: 9, align: :left, at: [250, @pdf.cursor])
31
+ @pdf.text_box(name, size: 9, align: :left, at: [350, @pdf.cursor])
32
+ @pdf.move_down 10
33
+ @pdf.stroke_horizontal_line(250, 528, at: @pdf.cursor)
34
+ end
35
+
36
+ def generate_drivers
37
+ @pdf.move_cursor_to 425
38
+
39
+ drivers.each_with_index do |driver, index|
40
+ @pdf.bounding_box [250, @pdf.cursor], width: 278, height: 20 do
41
+ @pdf.stroke_color GRAY_COLOR
42
+ @pdf.dash([2], phase: 6)
43
+ @pdf.stroke_horizontal_line(0, 278, at: 26) unless index.zero?
44
+ @pdf.undash
45
+ @pdf.move_down 20
46
+
47
+ driver.each_with_index do |cell, index_driver|
48
+ @pdf.text_box(cell, at: [x_position(index_driver), 20], size: 12)
49
+ end
50
+ end
51
+ end
52
+ end
53
+
54
+ def drivers
55
+ @xml.collect('xmlns', 'condutor') { |rodo| driver(rodo) }
56
+ end
57
+
58
+ def driver(rodo)
59
+ [
60
+ rodo.css('CPF').text,
61
+ rodo.css('xNome').text
62
+ ]
63
+ end
64
+
65
+ def x_position(index)
66
+ index.even? ? 0 : 100
67
+ end
68
+ end
69
+ end
70
+ end