├── .gitignore
├── .rspec
├── .ruby-gemset
├── .ruby-version
├── Gemfile
├── README.md
├── Rakefile
├── lib
├── municipios.json
├── ruby_danfe.rb
└── ruby_danfe
│ ├── cst.rb
│ ├── dacte_generator.rb
│ ├── dacteos_generator.rb
│ ├── danfe_generator.rb
│ ├── danfe_nfce_generator.rb
│ ├── danfse_generator.rb
│ ├── descricao.rb
│ ├── document.rb
│ ├── helper.rb
│ ├── options.rb
│ ├── railtie.rb
│ ├── ruby_danfe.rb
│ ├── version.rb
│ └── xml.rb
├── ruby_danfe.gemspec
├── spec
├── features
│ └── ruby_danfe_spec.rb
├── fixtures
│ ├── 4_decimals_nfe_simples_nacional.xml
│ ├── cte.xml
│ ├── nfe_date_format_infoadprod_infoadfisco_issues.xml
│ ├── nfe_simples_nacional.xml
│ ├── nfe_with_fci.xml
│ ├── nfe_with_ns.xml
│ ├── nfe_without_ns.xml
│ └── nfse.xml
├── lib
│ ├── cst_spec.rb
│ ├── descricao_spec.rb
│ ├── helper_spec.rb
│ ├── options_spec.rb
│ └── ruby_danfe_spec.rb
├── spec_helper.rb
└── support
│ └── be_same_file_as.rb
└── test
├── cteos.xml
├── danfe.xml
├── generate.rb
├── generate_nfce.rb
├── nfce.xml
├── nfe_simples_nacional.xml
├── nfe_with_fci.xml
├── nfe_with_ns.xml
└── nfe_without_ns.xml
/.gitignore:
--------------------------------------------------------------------------------
1 | .idea
2 | .DS_store
3 | *sublime-*
4 | Gemfile.lock
5 | pkg
6 | *.pdf
7 | coverage
8 |
--------------------------------------------------------------------------------
/.rspec:
--------------------------------------------------------------------------------
1 | --color --format documentation --order rand
2 |
--------------------------------------------------------------------------------
/.ruby-gemset:
--------------------------------------------------------------------------------
1 | ruby-danfe
2 |
--------------------------------------------------------------------------------
/.ruby-version:
--------------------------------------------------------------------------------
1 | ruby-3.2.2
--------------------------------------------------------------------------------
/Gemfile:
--------------------------------------------------------------------------------
1 | source 'http://rubygems.org'
2 |
3 | # Specify your gem's dependencies in ruby_danfe.gemspec
4 | gemspec
5 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Ruby DANFE
2 |
3 | It generates PDF files for Brazilian DANFE (_Documento Auxiliar da Nota Fiscal Eletrônica_) from a valid NF-e XML.
4 |
5 | It also generates Brazilian DACTE (_Documento Auxiliar do Conhecimento de Transporte Eletrônico_).
6 |
7 | This project is inspired on [NFePHP class](http://www.assembla.com/wiki/show/nfephp/DanfeNFePHP).
8 |
9 | ## Installing
10 |
11 | gem install ruby_danfe
12 |
13 | ## Usage
14 |
15 | If you have the xml saved in a file:
16 |
17 | require "ruby_danfe"
18 | RubyDanfe.generate("sample.pdf", "sample.xml")
19 | RubyDanfe.generate("cte.pdf", "cte.xml", "dacte")
20 | RubyDanfe.generate("cteos.pdf", "cteos.xml", "dacteos")
21 |
22 | If you have the xml in a variable:
23 |
24 | xml = "string xml"
25 | pdf = RubyDanfe.generatePDF(xml)
26 | pdf.render_file "output.pdf"
27 |
28 | You can use some options too! In this example, the product's field quantity will be rendered with 4 decimals after comma:
29 |
30 | xml = "string xml"
31 | RubyDanfe.options = {"quantity_decimals" => 4}
32 | pdf = RubyDanfe.generatePDF(xml)
33 | pdf.render_file "output.pdf"
34 |
35 | If you have some especific option that is global for your project, you can create a file at config/ruby_danfe.yml, then the ruby_danfe always will load this options. Example:
36 |
37 | project_name/config/ruby_danfe.yml
38 |
39 | ruby_danfe:
40 | options:
41 | quantity_decimals: 3
42 | numerify_prod_qcom: false
43 |
44 |
45 | ## Development
46 |
47 | ### Installing dependencies
48 |
49 | You can install all necessaries dependencies using bunder like above:
50 |
51 | $ bundle install
52 |
53 | ### Tests
54 |
55 | #### Manual tests
56 |
57 | At `test` folder you will find the `generate.rb` file. It shows how to generate a pdf file from a valid xml.
58 |
59 | You can use it following the steps above:
60 |
61 | $ cd test
62 | $ ruby generate.rb nfe_with_ns.xml
63 | $ ruby generate.rb cte_with_ns.xml 'dacte'
64 | $ ruby generate.rb cteos_with_ns.xml 'dacteos'
65 |
66 | You can also use an special version of irb with all classes pre-loaded. Just use:
67 |
68 | $ rake console
69 | RubyDanfe.generate("output.pdf", "test/nfe_with_ns.xml")
70 | RubyDanfe.generate("output.pdf", "test/cte.xml", 'dacte')
71 | RubyDanfe.generate("output.pdf", "test/cteos.xml", 'dacteos')
72 |
73 | or
74 |
75 | $ rake console
76 | my_xml_string = ""
77 | file = File.new("test/nfe_with_ns.xml", "r")
78 | while (line = file.gets)
79 | my_xml_string = my_xml_string + line
80 | end
81 | file.close
82 |
83 | xml = RubyDanfe::XML.new(my_xml_string)
84 | pdf = RubyDanfe.generatePDF(xml)
85 |
86 | pdf.render_file "output.pdf"
87 |
88 | #### Automated tests with RSpec
89 |
90 | You can run all specs using:
91 |
92 | $ rspec
93 |
94 | In the `spec/fixtures` folder, you are going to find some xml files. Each one represent a different NF-e context.
95 |
96 | Each xml file must have its respective pdf file.
97 |
98 | If you did some change that caused general visual changes at output pdfs, so you have to rebuild all fixtures pdf files.
99 |
100 | You can do this automagically running the following taks:
101 |
102 | $ rake spec:fixtures:recreate_pdfs
103 |
104 | #### Code coverage
105 |
106 | Code coverage is available through of SimpleCov. Just run `rspec` and open the coverage report in your browser.
107 |
108 | ### Building and publishing
109 |
110 | You can build using one of the above tasks
111 |
112 | $ rake build # Build ruby_danfe-X.X.X.gem into the pkg directory
113 | $ rake install # Build and install ruby_danfe-X.X.X.gem into system gems
114 | $ rake release # Create tag vX.X.X and build and push ruby_danfe-X.X.X.gem to Rubygems
115 |
116 | ## Contributing
117 |
118 | We encourage you to contribute to Ruby DANFE!
119 |
120 | 1. Fork it
121 | 2. Create your feature branch (`git checkout -b my-new-feature`)
122 | 3. Commit your changes (`git commit -am 'Add some feature'`)
123 | 4. Push to the branch (`git push origin my-new-feature`)
124 | 5. Create new Pull Request
125 |
126 | ## License
127 |
128 | Ruby DANFE is released under the [MIT License](http://www.opensource.org/licenses/MIT).
129 |
--------------------------------------------------------------------------------
/Rakefile:
--------------------------------------------------------------------------------
1 | require "bundler/gem_tasks"
2 | require "ruby_danfe"
3 |
4 | desc "Open an irb session preloaded ruby_danfe classes"
5 | task :console do
6 | sh "irb -rubygems -I lib -r ruby_danfe.rb"
7 | end
8 |
9 | namespace :spec do
10 | namespace :fixtures do
11 | desc "Recreate all pdfs fixtures. Use this task always that output pdf format is changed."
12 | task :recreate_pdfs do
13 | Dir["spec/fixtures/nfe*.xml"].each do |f|
14 | puts "Recreating #{f}.fixture.pdf"
15 | RubyDanfe.generate("#{f}.fixture.pdf", "#{f}")
16 | end
17 |
18 | puts "Recreating spec/fixtures/4_decimals_nfe_simples_nacional.xml.fixture.pdf"
19 | RubyDanfe.options = {"quantity_decimals" => 4}
20 | RubyDanfe.generate("spec/fixtures/4_decimals_nfe_simples_nacional.xml.fixture.pdf", "spec/fixtures/4_decimals_nfe_simples_nacional.xml")
21 |
22 | Dir["spec/fixtures/cte*.xml"].each do |f|
23 | puts "Recreating #{f}.fixture.pdf"
24 | RubyDanfe.generate("#{f}.fixture.pdf", "#{f}", :dacte)
25 | end
26 |
27 | Dir["spec/fixtures/nfse*.xml"].each do |f|
28 | puts "Recreating #{f}.fixture.pdf"
29 | RubyDanfe.generate("#{f}.fixture.pdf", "#{f}", :danfse)
30 | end
31 | end
32 | end
33 | end
34 |
--------------------------------------------------------------------------------
/lib/ruby_danfe.rb:
--------------------------------------------------------------------------------
1 | require_relative 'ruby_danfe/railtie.rb'
2 |
--------------------------------------------------------------------------------
/lib/ruby_danfe/cst.rb:
--------------------------------------------------------------------------------
1 | module RubyDanfe
2 | class Cst
3 | def self.to_danfe(xml)
4 | value = origin(xml)
5 |
6 | if csosn?(xml)
7 | value += xml.css("ICMS/*/CSOSN").text
8 | elsif cst?(xml)
9 | value += xml.css("ICMS/*/CST").text
10 | end
11 |
12 | value
13 | end
14 |
15 | private
16 | def self.origin(xml)
17 | xml.css('ICMS/*/orig').text
18 | end
19 |
20 | def self.cst?(xml)
21 | xml.css("ICMS/*/CST").text != ""
22 | end
23 |
24 | def self.csosn?(xml)
25 | xml.css("ICMS/*/CSOSN").text != ""
26 | end
27 | end
28 | end
29 |
--------------------------------------------------------------------------------
/lib/ruby_danfe/dacte_generator.rb:
--------------------------------------------------------------------------------
1 | # coding: utf-8
2 | module RubyDanfe
3 | class DacteGenerator
4 | def initialize(xml)
5 | @xml = xml
6 | @pdf = Document.new
7 | end
8 |
9 | def generatePDF
10 | @pdf.repeat :all do
11 | render_emitente
12 | render_tipo_cte
13 | render_tipo_servico
14 | render_tomador
15 | render_forma_de_pagamento
16 | render_infobox
17 | render_remetente
18 | render_destinatario
19 | render_expedidor
20 | render_recebedor
21 | render_tomador_do_servico
22 | render_produto
23 | render_quantidade
24 | render_seguradora
25 | render_valor_da_prestacao
26 | render_impostos
27 | render_documentos_originarios
28 | render_observacoes
29 | render_modal
30 | end
31 |
32 | @pdf
33 | end
34 |
35 | private
36 | def render_emitente
37 | @pdf.ibox 2.27, 7.67, 0.25, 0.54
38 | @pdf.ibox 2.27, 7.67, 0.25, 0.74, '',
39 | @xml['emit/xNome'],
40 | { :align => :center, :size => 9, :border => 0, :style => :bold }
41 |
42 | fone = @xml['enderEmit/fone']
43 | unless fone.eql?('')
44 | if fone.size > 8
45 | fone = '(' + @xml['enderEmit/fone'][0,2] + ') ' + @xml['enderEmit/fone'][2,5] + '-' + @xml['enderEmit/fone'][6,4]
46 | else
47 | fone = @xml['enderEmit/fone'][0,4] + '-' + @xml['enderEmit/fone'][4,4]
48 | end
49 | end
50 | @pdf.ibox 2.27, 7.67, 0.25, 1.20, '',
51 | @xml['enderEmit/xLgr'] + ", " + @xml['enderEmit/nro'] + "\n" +
52 | @xml['enderEmit/xMun'] + " - " + @xml['enderEmit/UF'] + " " + @xml['enderEmit/xPais'] + "\n" +
53 | "Fone/Fax: " + fone,
54 | { :align => :center, :size => 8, :border => 0, :style => :bold }
55 |
56 | @pdf.ibox 2.27, 7.67, 0.25, 2.30, '',
57 | "CNPJ: " + Helper.format_cnpj(@xml['emit/CNPJ']) + " " + "IE: " + @xml['emit/IE'],
58 | { :align => :center, :size => 7, :border => 0, :style => :bold }
59 | end
60 |
61 | def render_tipo_cte
62 | # tipo ct-e
63 | tpCTe = case @xml['ide/tpCTe']
64 | when '0' then 'Normal'
65 | when '1' then 'Complemento de Valores'
66 | when '2' then 'Anulação de Valores'
67 | when '3' then 'Substituto'
68 | else ''
69 | end
70 | @pdf.ibox 0.90, 3.84, 0.25, 2.81, 'TIPO DE CT-E', tpCTe, { :align => :center, :size => 8, :style => :bold }
71 | end
72 |
73 | def render_tipo_servico
74 | # tipo servico
75 | tpServ = case @xml['ide/tpServ']
76 | when '0' then 'Normal'
77 | when '1' then 'Subcontratação'
78 | when '2' then 'Redespacho'
79 | when '3' then 'Redespacho Intermediário'
80 | else ''
81 | end
82 | @pdf.ibox 0.90, 3.83, 4.08, 2.81, 'TIPO DE SERVIÇO', tpServ, { :align => :center, :size => 8, :style => :bold }
83 | end
84 |
85 | def render_tomador
86 | # tomador
87 | if @xml['ide/toma3'] != '' || @xml['ide/toma03'] != '' then
88 | @xml['ide/toma3'] != '' ? tomador = 'toma3' : tomador = 'toma03'
89 | else if @xml['ide/toma4'] != '' || @xml['ide/toma04'] != '' then
90 | @xml['ide/toma4'] != '' ? tomador = 'toma4' : tomador = 'toma04'
91 | end
92 | end
93 | toma = case @xml[tomador + '/toma']
94 | when '0' then 'Remetente'
95 | when '1' then 'Expedidor'
96 | when '2' then 'Recebedor'
97 | when '3' then 'Destinatário'
98 | when '4' then 'Outros'
99 | else ''
100 | end
101 | @pdf.ibox 0.90, 3.83, 0.25, 3.71, 'TOMADOR DO SERVIÇO', toma, { :align => :center, :size => 8, :style => :bold }
102 | end
103 |
104 | def render_forma_de_pagamento
105 | # forma de pagamento
106 | forma = case @xml['ide/forPag']
107 | when '0' then 'Pago'
108 | when '1' then 'A pagar'
109 | when '2' then 'Outros'
110 | else ''
111 | end
112 | @pdf.ibox 0.90, 3.83, 4.08, 3.71, 'FORMA DE PAGAMENTO', forma, { :align => :center, :size => 8, :style => :bold }
113 | end
114 |
115 | def render_infobox
116 | # infobox
117 | @pdf.ibox 0.90, 9.39, 7.92, 0.54, '', 'DACTE', { :align => :center, :style => :bold, :size => 12}
118 | @pdf.ibox 0.90, 9.39, 7.92, 0.94, '', 'Documento auxiliar do Conhecimento de Transporte Eletrônico', { :align => :center, :border => 0, :size => 7 }
119 | #@pdf.ibox 0.90, 9.39, 7.92, 1.04, '', 'de Transporte Eletrônico', { :align => :center, :border => 0, :size => 6 }
120 |
121 | # tipo
122 | @pdf.ibox 0.90, 3.43, 17.31, 0.54, '', 'MODAL', { :align => :center, :size => 7 }
123 |
124 | # modal
125 | # modal = case @xml['ide/modal']
126 | # when '1' then 'Rodoviário'
127 | # when '2' then 'Aéreo'
128 | # when '3' then 'Aquaviário'
129 | # when '4' then 'Ferroviário'
130 | # when '5' then 'Dutoviário'
131 | # else ''
132 | # end
133 | @pdf.ibox 0.90, 3.43, 17.31, 0.84, '', 'RODOVIÁRIO', { :align => :center, :size => 8, :border => 0, :style => :bold }
134 | @pdf.ibox 0.91, 1.98, 7.92, 1.44, 'MODELO', @xml['ide/mod'], {:size => 8, :align => :center}
135 | @pdf.ibox 0.91, 0.75, 9.90, 1.44, 'SERIE', @xml['ide/serie'], {:size => 8, :align => :center}
136 | @pdf.ibox 0.91, 2.48, 10.65, 1.44, 'NÚMERO', @xml['ide/nCT'], {:size => 8, :align => :center}
137 | @pdf.ibox 0.91, 0.97, 13.13, 1.44, 'FL', '1/1', {:size => 8, :align => :center}
138 | emiss = @xml['ide/dhEmi'][8, 2] + '/' + @xml['ide/dhEmi'][5, 2] + '/' + @xml['ide/dhEmi'][0, 4] + " " +
139 | @xml['ide/dhEmi'][11, 8]
140 |
141 | @pdf.ibox 0.91, 3.21, 14.10, 1.44, 'DATA E HORA DE EMISSÃO', emiss, {:size => 8, :align => :center}
142 | @pdf.ibox 0.91, 3.43, 17.31, 1.44, 'INSC. SUFRAMA DESTINATÁRIO', @xml['dest/ISUF'], {:size => 8, :align => :center}
143 | @pdf.ibox 1.13, 12.82, 7.92, 2.35
144 | @pdf.ibarcode 0.85, 12.82, 9.25, 3.35, @xml.attrib('infCte', 'Id')[3..-1]
145 | @pdf.ibox 0.62, 12.82, 7.92, 3.48, 'Chave de acesso', ''
146 | @pdf.ibox 0.90, 12.82, 7.92, 3.62, '', @xml.attrib('infCte', 'Id')[3..-1].gsub(/(\d)(?=(\d\d\d\d)+(?!\d))/, "\\1 "), {:style => :bold, :align => :center, :size => 8, :border => 0}
147 | @pdf.ibox 1.13, 12.82, 7.92, 4.10, '', 'Consulta de autenticidade no portal do CT-e, no site da Sefaz Autorizadora, ou em http://www.cte.fazenda.gov.br/portal',
148 | { :align => :center, :valign => :center, :style => :bold, :size => 8 }
149 | @pdf.ibox 0.71, 12.82, 7.92, 5.23, 'Protocolo de Autorização de Uso'
150 | @pdf.ibox 0.90, 12.82, 7.92, 5.38, '', @xml['infProt/nProt'], { :style => :bold, :align => :left, :border => 0, :size => 8 }
151 | @pdf.ibox 1.33, 7.67, 0.25, 4.61, 'CFOP - NATUREZA DA PRESTAÇÃO', @xml['ide/CFOP'] + ' - ' + @xml['ide/natOp'], { :align => :left, :size => 7, :style => :bold }
152 | # UFIni -xMunIni
153 | @pdf.ibox 0.92, 10.25, 0.25, 5.94, 'INÍCIO DA PRESTAÇÃO', @xml['ide/UFIni'] + ' - ' + @xml['ide/xMunIni']
154 | # UFFim -cMunFim – xMunFim
155 | @pdf.ibox 0.92, 10.24, 10.50, 5.94, 'TÉRMINO DA PRESTAÇÃO', @xml['ide/UFFim'] + ' - ' + @xml['ide/cMunFim'] + ' - ' + @xml['ide/xMunFim']
156 | end
157 |
158 | def render_remetente
159 | # remetente
160 | @pdf.ibox 2.76, 10.25, 0.25, 6.86
161 | @pdf.ibox 0.90, 10.00, 0.28, 7.05, '', 'Remetente: ', { :size => 7, :border => 0, :style => :italic }
162 | @pdf.ibox 0.90, 10.00, 1.88, 7.05, '', @xml['rem/xNome'], { :size => 7, :border => 0, :style => :bold }
163 | @pdf.ibox 0.90, 10.00, 0.28, 7.41, '', 'Endereço: ', { :size => 7, :border => 0, :style => :italic }
164 | @pdf.ibox 0.90, 10.00, 1.88, 7.41, '', @xml['enderReme/xLgr'] + ', ' + @xml['enderReme/nro'] + (@xml['enderReme/xCpl'] != '' ? ' - ' + @xml['enderReme/xCpl'] : ''), { :size => 7, :border => 0, :style => :bold } if @xml['enderReme/xLgr'] != ''
165 | @pdf.ibox 0.90, 5.00, 1.88, 7.68, '', @xml['enderReme/xBairro'], { :size => 7, :border => 0, :style => :bold }
166 | @pdf.ibox 0.90, 10.00, 0.28, 8.02, '', 'Município: ', { :size => 7, :border => 0, :style => :italic }
167 | @pdf.ibox 0.90, 10.00, 1.88, 8.02, '', @xml['enderReme/xMun'], { :size => 7, :border => 0, :style => :bold }
168 | @pdf.ibox 0.90, 3.00, 6.50, 8.02, '', 'CEP: ', { :size => 7, :border => 0, :style => :italic }
169 | @pdf.ibox 0.90, 3.00, 7.20, 8.02, '', @xml['enderReme/CEP'][0,2] + '.' + @xml['enderReme/CEP'][3,3] + '-' + @xml['enderReme/CEP'][5,3], { :size => 7, :border => 0, :style => :bold } if @xml['enderReme/CEP'] != ''
170 | @pdf.ibox 0.90, 10.00, 0.28, 8.41, '', 'CNPJ/CPF: ', { :size => 7, :border => 0, :style => :italic }
171 | @pdf.ibox 0.90, 10.00, 1.88, 8.41, '', Helper.format_cnpj(@xml['rem/CNPJ']), { :size => 7, :border => 0, :style => :bold } if @xml['rem/CNPJ'] != ''
172 | @pdf.ibox 0.90, 10.00, 1.88, 8.41, '', @xml['rem/CPF'][0,3] + '.' + @xml['rem/CPF'][3,3] + '.' + @xml['rem/CPF'][6,3] + '-' + @xml['rem/CPF'][9,2], { :size => 7, :border => 0, :style => :bold } if @xml['rem/CPF'] != ''
173 | @pdf.ibox 0.90, 3.50, 6.50, 8.41, '', 'Inscr. Est.: ', { :size => 7, :border => 0, :style => :italic }
174 | @pdf.ibox 0.90, 3.50, 7.85, 8.41, '', @xml['rem/IE'], { :size => 7, :border => 0, :style => :bold }
175 | @pdf.ibox 0.90, 6.00, 0.28, 8.82, '', 'UF: ' + ' ' + 'País: ', { :size => 7, :border => 0, :style => :italic }
176 | @pdf.ibox 0.90, 6.00, 1.88, 8.82, '', @xml['enderReme/UF'] + ' ' + @xml['enderReme/xPais'], { :size => 7, :border => 0, :style => :bold }
177 | @pdf.ibox 0.90, 3.00, 6.50, 8.82, '', 'Fone: ', { :size => 7, :border => 0, :style => :italic }
178 | fone = @xml['rem/fone']
179 | unless fone.eql?('')
180 | if fone.size > 8
181 | @pdf.ibox 0.90, 3.00, 7.20, 8.82, '', '(' + @xml['rem/fone'][0,2] + ')' + @xml['rem/fone'][2,4] + '-' + @xml['rem/fone'][6,4], { :size => 7, :border => 0, :style => :bold }
182 | else
183 | @pdf.ibox 0.90, 3.00, 7.20, 8.82, '', @xml['rem/fone'][0,4] + '-' + @xml['rem/fone'][4,4], { :size => 7, :border => 0, :style => :bold }
184 | end
185 | end
186 | end
187 |
188 | def render_destinatario
189 | # destinatário
190 | @pdf.ibox 2.76, 10.24, 10.50, 6.86
191 | @pdf.ibox 0.90, 10.00, 10.53, 7.05, '', 'Destinatário: ', { :size => 7, :border => 0, :style => :italic }
192 | @pdf.ibox 0.90, 10.00, 12.10, 7.05, '', @xml['dest/xNome'], { :size => 7, :border => 0, :style => :bold }
193 | @pdf.ibox 0.90, 10.00, 10.53, 7.41, '', 'Endereço: ', { :size => 7, :border => 0, :style => :italic }
194 | @pdf.ibox 0.90, 10.00, 12.10, 7.41, '', @xml['enderDest/xLgr'] + ', ' + @xml['enderDest/nro'] + (@xml['enderDest/xCpl'] != '' ? ' - ' + @xml['enderDest/xCpl'] : ''), { :size => 7, :border => 0, :style => :bold } if @xml['enderDest/xLgr'] != ''
195 | @pdf.ibox 0.90, 5.00, 12.10, 7.68, '', @xml['enderDest/xBairro'], { :size => 7, :border => 0, :style => :bold }
196 | @pdf.ibox 0.90, 10.00, 10.53, 8.02, '', 'Município: ', { :size => 7, :border => 0, :style => :italic }
197 | @pdf.ibox 0.90, 10.00, 12.10, 8.02, '', @xml['enderDest/xMun'], { :size => 7, :border => 0, :style => :bold }
198 | @pdf.ibox 0.90, 3.00, 16.75, 8.02, '', 'CEP: ' , { :size => 7, :border => 0, :style => :italic }
199 | @pdf.ibox 0.90, 3.00, 17.40, 8.02, '', @xml['enderDest/CEP'][0,2] + '.' + @xml['enderDest/CEP'][3,3] + '-' + @xml['enderDest/CEP'][5,3], { :size => 7, :border => 0, :style => :bold } if @xml['enderDest/CEP'] != ''
200 | @pdf.ibox 0.90, 10.00, 10.53, 8.41, '', 'CNPJ/CPF: ', { :size => 7, :border => 0, :style => :italic }
201 | @pdf.ibox 0.90, 10.00, 12.10, 8.41, '', Helper.format_cnpj(@xml['dest/CNPJ']), { :size => 7, :border => 0, :style => :bold } if @xml['dest/CNPJ'] != ''
202 | @pdf.ibox 0.90, 10.00, 12.10, 8.41, '', @xml['dest/CPF'][0,3] + '.' + @xml['dest/CPF'][3,3] + '.' + @xml['dest/CPF'][6,3] + '-' + @xml['dest/CPF'][9,2], { :size => 7, :border => 0, :style => :bold } if @xml['dest/CPF'] != ''
203 | @pdf.ibox 0.90, 3.50, 16.75, 8.41, '', 'Inscr. Est.: ', { :size => 7, :border => 0, :style => :italic }
204 | @pdf.ibox 0.90, 3.50, 18.05, 8.41, '', @xml['dest/IE'], { :size => 7, :border => 0, :style => :bold }
205 | @pdf.ibox 0.90, 6.00, 10.53, 8.82, '', 'UF: ' + ' ' + 'País: ' , { :size => 7, :border => 0, :style => :italic }
206 | @pdf.ibox 0.90, 6.00, 12.10, 8.82, '', @xml['enderDest/UF'] + ' ' + @xml['enderDest/xPais'] , { :size => 7, :border => 0, :style => :bold }
207 | @pdf.ibox 0.90, 3.00, 16.75, 8.82, '', 'Fone: ', { :size => 7, :border => 0, :style => :italic }
208 | fone = @xml['dest/fone']
209 | unless fone.eql?('')
210 | if fone.size > 8
211 | @pdf.ibox 0.90, 3.00, 17.40, 8.82, '', '(' + @xml['dest/fone'][0,2] + ')' + @xml['dest/fone'][2,4] + '-' + @xml['dest/fone'][6,4], { :size => 7, :border => 0, :style => :bold }
212 | else
213 | @pdf.ibox 0.90, 3.00, 17.40, 8.82, '', @xml['dest/fone'][0,4] + '-' + @xml['dest/fone'][4,4], { :size => 7, :border => 0, :style => :bold }
214 | end
215 | end
216 | end
217 |
218 | def render_expedidor
219 | # expedidor
220 | @pdf.ibox 2.76, 10.25, 0.25, 9.62
221 | @pdf.ibox 0.90, 10.00, 0.28, 9.81, '', 'Expedidor: ', { :size => 7, :border => 0, :style => :italic }
222 | @pdf.ibox 0.90, 10.00, 1.88, 9.81, '', @xml['exped/xNome'], { :size => 7, :border => 0, :style => :bold }
223 | @pdf.ibox 0.90, 10.00, 0.28, 10.17, '', 'Endereço: ', { :size => 7, :border => 0, :style => :italic }
224 | @pdf.ibox 0.90, 10.00, 1.88, 10.17, '', @xml['enderExped/xLgr'] + ', ' + @xml['enderExped/nro'] + (@xml['enderExped/xCpl'] != '' ? ' - ' + @xml['enderExped/xCpl'] : ''), { :size => 7, :border => 0, :style => :bold } if @xml['enderExped/xLgr'] != ''
225 | @pdf.ibox 0.90, 5.00, 1.88, 10.44, '', @xml['enderExped/xBairro'], { :size => 7, :border => 0, :style => :bold }
226 | @pdf.ibox 0.90, 10.00, 0.28, 10.78, '', 'Município: ', { :size => 7, :border => 0, :style => :italic }
227 | @pdf.ibox 0.90, 10.00, 1.88, 10.78, '', @xml['enderExped/xMun'], { :size => 7, :border => 0, :style => :bold }
228 | @pdf.ibox 0.90, 3.00, 6.50, 10.78, '', 'CEP: ', { :size => 7, :border => 0, :style => :italic }
229 | @pdf.ibox 0.90, 3.00, 7.20, 10.78, '', @xml['enderExped/CEP'][0,2] + '.' + @xml['enderExped/CEP'][3,3] + '-' + @xml['enderExped/CEP'][5,3], { :size => 7, :border => 0, :style => :bold } if @xml['enderExped/CEP'] != ''
230 | @pdf.ibox 0.90, 10.00, 0.28, 11.17, '', 'CNPJ/CPF: ', { :size => 7, :border => 0, :style => :italic }
231 | @pdf.ibox 0.90, 10.00, 1.88, 11.17, '', Helper.format_cnpj(@xml['exped/CNPJ']), { :size => 7, :border => 0, :style => :bold } if @xml['exped/CNPJ'] != ''
232 | @pdf.ibox 0.90, 10.00, 1.88, 11.17, '', @xml['exped/CPF'][0,3] + '.' + @xml['exped/CPF'][3,3] + '.' + @xml['exped/CPF'][6,3] + '-' + @xml['exped/CPF'][9,2], { :size => 7, :border => 0, :style => :bold } if @xml['exped/CPF'] != ''
233 | @pdf.ibox 0.90, 3.50, 6.50, 11.17, '', 'Inscr. Est.:' , { :size => 7, :border => 0, :style => :italic }
234 | @pdf.ibox 0.90, 3.50, 7.85, 11.17, '', @xml['exped/IE'], { :size => 7, :border => 0, :style => :bold }
235 | @pdf.ibox 0.90, 6.00, 0.28, 11.58, '', 'UF: ' + ' ' + 'País: ', { :size => 7, :border => 0, :style => :italic }
236 | @pdf.ibox 0.90, 6.00, 1.88, 11.58, '', @xml['enderExped/UF'] + ' ' + @xml['enderExped/xPais'], { :size => 7, :border => 0, :style => :bold }
237 | @pdf.ibox 0.90, 3.00, 6.50, 11.58, '', 'Fone: ', { :size => 7, :border => 0, :style => :italic }
238 | fone = @xml['exped/fone']
239 | unless fone.eql?('')
240 | if @xml['exped/fone'] != '' and fone.size > 8
241 | @pdf.ibox 0.90, 3.00, 7.20, 11.58, '', '(' + @xml['exped/fone'][0,2] + ')' + @xml['exped/fone'][2,4] + '-' + @xml['exped/fone'][6,4], { :size => 7, :border => 0, :style => :bold }
242 | else
243 | @pdf.ibox 0.90, 3.00, 7.20, 11.58, '', @xml['exped/fone'][0,4] + '-' + @xml['exped/fone'][4,4], { :size => 7, :border => 0, :style => :bold }
244 | end
245 | end
246 | end
247 |
248 | def render_recebedor
249 | # recebedor
250 | @pdf.ibox 2.76, 10.24, 10.50, 9.62
251 | @pdf.ibox 0.90, 10.00, 10.53, 9.81, '', 'Recebedor: ', { :size => 7, :border => 0, :style => :italic }
252 | @pdf.ibox 0.90, 10.00, 12.10, 9.81, '', @xml['receb/xNome'], { :size => 7, :border => 0, :style => :bold }
253 | @pdf.ibox 0.90, 10.00, 10.53, 10.17, '', 'Endereço: ', { :size => 7, :border => 0, :style => :italic }
254 | @pdf.ibox 0.90, 10.00, 12.10, 10.17, '', @xml['enderReceb/xLgr'] + ', ' + @xml['enderReceb/nro'] + (@xml['enderReceb/xCpl'] != '' ? ' - ' + @xml['enderReceb/xCpl'] : ''), { :size => 7, :border => 0, :style => :bold } if @xml['enderReceb/xLgr'] != ''
255 | @pdf.ibox 0.90, 5.00, 12.10, 10.44, '', @xml['enderReceb/xBairro'], { :size => 7, :border => 0, :style => :bold }
256 | @pdf.ibox 0.90, 10.00, 10.53, 10.78, '', 'Município: ' , { :size => 7, :border => 0, :style => :italic }
257 | @pdf.ibox 0.90, 10.00, 12.10, 10.78, '', @xml['enderReceb/xMun'], { :size => 7, :border => 0, :style => :bold }
258 | @pdf.ibox 0.90, 3.00, 16.75, 10.78, '', 'CEP: ', { :size => 7, :border => 0, :style => :italic }
259 | @pdf.ibox 0.90, 3.00, 17.40, 10.78, '', @xml['enderReceb/CEP'][0,2] + '.' + @xml['enderReceb/CEP'][3,3] + '-' + @xml['enderReceb/CEP'][5,3], { :size => 7, :border => 0, :style => :bold } if @xml['enderReceb/CEP'] != ''
260 | @pdf.ibox 0.90, 10.00, 10.53, 11.17, '', 'CNPJ/CPF: ', { :size => 7, :border => 0, :style => :italic }
261 | @pdf.ibox 0.90, 10.00, 12.10, 11.17, '', Helper.format_cnpj(@xml['receb/CNPJ']), { :size => 7, :border => 0, :style => :bold } if @xml['receb/CNPJ'] != ''
262 | @pdf.ibox 0.90, 10.00, 12.10, 11.17, '', @xml['receb/CPF'][0,3] + '.' + @xml['receb/CPF'][3,3] + '.' + @xml['receb/CPF'][6,3] + '-' + @xml['receb/CPF'][9,2], { :size => 7, :border => 0, :style => :bold } if @xml['receb/CPF'] != ''
263 | @pdf.ibox 0.90, 3.50, 16.75, 11.17, '', 'Inscr. Est.: ', { :size => 7, :border => 0, :style => :italic }
264 | @pdf.ibox 0.90, 3.50, 18.05, 11.17, '', @xml['receb/IE'], { :size => 7, :border => 0, :style => :bold }
265 | @pdf.ibox 0.90, 6.00, 10.53, 11.58, '', 'UF: ' + ' ' + 'País: ', { :size => 7, :border => 0, :style => :italic }
266 | @pdf.ibox 0.90, 6.00, 12.10, 11.58, '', @xml['enderReceb/UF'] + ' ' + @xml['enderReceb/xPais'], { :size => 7, :border => 0, :style => :bold }
267 | @pdf.ibox 0.90, 3.00, 16.75, 11.58, '', 'Fone: ', { :size => 7, :border => 0, :style => :italic }
268 | fone = @xml['receb/fone']
269 | unless fone.eql?('')
270 | if @xml['receb/fone'] != '' and fone.size > 8
271 | @pdf.ibox 0.90, 3.00, 17.40, 11.58, '', '(' + @xml['receb/fone'][0,2] + ')' + @xml['receb/fone'][2,4] + '-' + @xml['receb/fone'][6,4], { :size => 7, :border => 0, :style => :bold }
272 | else
273 | @pdf.ibox 0.90, 3.00, 17.40, 11.58, '', @xml['receb/fone'][0,4] + '-' + @xml['receb/fone'][4,4], { :size => 7, :border => 0, :style => :bold }
274 | end
275 | end
276 | end
277 |
278 | def render_tomador_do_servico
279 | # tomador
280 | @pdf.ibox 1.45, 20.49, 0.25, 12.38
281 | if @xml['ide/toma3'] != '' || @xml['ide/toma03'] != '' then
282 | @xml['ide/toma3'] != '' ? tomador = 'toma3' : tomador = 'toma03'
283 | else if @xml['ide/toma4'] != '' || @xml['ide/toma04'] != '' then
284 | @xml['ide/toma4'] != '' ? tomador = 'toma4' : tomador = 'toma04'
285 | end
286 | end
287 | toma = case @xml[tomador + '/toma']
288 | when '0' then 'rem'
289 | when '1' then 'exped'
290 | when '2' then 'receb'
291 | when '3' then 'dest'
292 | when '4' then 'Outros'
293 | else ''
294 | end
295 | endereco = case @xml[tomador + '/toma']
296 | when '0' then 'enderReme'
297 | when '1' then 'enderExped'
298 | when '2' then 'enderReceb'
299 | when '3' then 'enderDest'
300 | when '4' then 'Outros'
301 | else ''
302 | end
303 | if toma == 'Outros'
304 | @pdf.ibox 0.90, 10.00, 0.28, 12.45, '', 'Tomador do Serviço: ', { :size => 7, :border => 0, :style => :italic }
305 | @pdf.ibox 0.90, 10.00, 2.58, 12.45, '', @xml['toma4/xNome'], { :size => 7, :border => 0, :style => :bold }
306 | @pdf.ibox 0.90, 10.00, 10.50, 12.45, '', 'Município: ', { :size => 7, :border => 0, :style => :italic }
307 | @pdf.ibox 0.90, 10.00, 11.80, 12.45, '', @xml['enderToma/xMun'], { :size => 7, :border => 0, :style => :bold }
308 | @pdf.ibox 0.90, 4.00, 18.00, 12.45, '', 'CEP: ', { :size => 7, :border => 0, :style => :italic }
309 | @pdf.ibox 0.90, 4.00, 18.70, 12.45, '', @xml['enderToma/CEP'][0,2] + '.' + @xml['enderToma/CEP'][3,3] + '-' + @xml['enderToma/CEP'][5,3], { :size => 7, :border => 0, :style => :bold } if @xml['enderToma/CEP'] != ''
310 | @pdf.ibox 0.90, 10.00, 0.28, 12.81, '', 'Endereço: ', { :size => 7, :border => 0, :style => :italic }
311 | @pdf.ibox 0.90, 10.00, 1.88, 12.81, '', @xml['enderToma/xLgr'] + ', ' + @xml['enderToma/nro'] + (@xml['enderToma/xCpl'] != '' ? ' - ' + @xml['enderToma/xCpl'] : '') + ' - ' + @xml['enderToma/xBairro'], { :size => 7, :border => 0, :style => :bold } if @xml['enderToma/xLgr'] != ''
312 | @pdf.ibox 0.90, 2.00, 13.50, 12.81, '', 'UF: ' , { :size => 7, :border => 0, :style => :italic }
313 | @pdf.ibox 0.90, 2.00, 14.50, 12.81, '', @xml['enderToma/UF'], { :size => 7, :border => 0, :style => :bold }
314 | @pdf.ibox 0.90, 5.00, 16.50, 12.81, '', 'País: ' , { :size => 7, :border => 0, :style => :italic }
315 | @pdf.ibox 0.90, 5.00, 17.50, 12.81, '', @xml['enderToma/xPais'], { :size => 7, :border => 0, :style => :bold }
316 | @pdf.ibox 0.90, 5.00, 0.28, 13.17, '', 'CNPJ/CPF: ' , { :size => 7, :border => 0, :style => :italic }
317 | @pdf.ibox 0.90, 5.00, 1.88, 13.17, '', Helper.format_cnpj(@xml['toma4/CNPJ']), { :size => 7, :border => 0, :style => :bold } if @xml['toma4/CNPJ'] != ''
318 | @pdf.ibox 0.90, 5.00, 1.88, 13.17, '', @xml['toma4/CPF'][0,3] + '.' + @xml['toma4/CPF'][3,3] + '.' + @xml['toma4/CPF'][6,3] + '-' + @xml['toma4/CPF'][9,2], { :size => 7, :border => 0, :style => :bold } if @xml['toma4/CPF'] != ''
319 | @pdf.ibox 0.90, 5.00, 5.60, 13.17, '', 'Inscr. Est.: ', { :size => 7, :border => 0, :style => :italic }
320 | @pdf.ibox 0.90, 5.00, 7.20, 13.17, '', @xml['toma4/IE'], { :size => 7, :border => 0, :style => :bold }
321 | @pdf.ibox 0.90, 5.00, 10.50, 13.17, '', 'Fone: ' , { :size => 7, :border => 0, :style => :italic }
322 | fone = @xml['toma4/fone']
323 | unless fone.eql?('')
324 | if fone.size > 8
325 | @pdf.ibox 0.90, 5.00, 11.80, 13.17, '', '(' + @xml['toma4/fone'][0,2] + ')' + @xml['toma4/fone'][2,4] + '-' + @xml['toma4/fone'][6,4], { :size => 7, :border => 0, :style => :bold }
326 | else
327 | @pdf.ibox 0.90, 5.00, 11.80, 13.17, '', @xml['toma4/fone'][0,4] + '-' + @xml['toma4/fone'][4,4], { :size => 7, :border => 0, :style => :bold }
328 | end
329 | end
330 | else
331 | @pdf.ibox 0.90, 10.00, 0.28, 12.45, '', 'Tomador do Serviço: ', { :size => 7, :border => 0, :style => :italic }
332 | @pdf.ibox 0.90, 10.00, 2.58, 12.45, '', @xml[toma + '/xNome'], { :size => 7, :border => 0, :style => :bold }
333 | @pdf.ibox 0.90, 10.00, 10.50, 12.45, '', 'Município: ', { :size => 7, :border => 0, :style => :italic }
334 | @pdf.ibox 0.90, 10.00, 11.80, 12.45, '', @xml[endereco + '/xMun'], { :size => 7, :border => 0, :style => :bold }
335 | @pdf.ibox 0.90, 4.00, 18.00, 12.45, '', 'CEP: ', { :size => 7, :border => 0, :style => :italic }
336 | @pdf.ibox 0.90, 4.00, 18.70, 12.45, '', @xml[endereco + '/CEP'][0,2] + '.' + @xml[endereco + '/CEP'][3,3] + '-' + @xml[endereco + '/CEP'][5,3], { :size => 7, :border => 0, :style => :bold } if @xml[endereco + '/CEP'] != ''
337 | @pdf.ibox 0.90, 10.00, 0.28, 12.81, '', 'Endereço: ', { :size => 7, :border => 0, :style => :italic }
338 | @pdf.ibox 0.90, 10.00, 1.88, 12.81, '', @xml[endereco + '/xLgr'] + ', ' + @xml[endereco + '/nro'] + (@xml[endereco + '/xCpl'] != '' ? ' - ' + @xml[endereco + '/xCpl'] : '') + ' - ' + @xml[endereco + '/xBairro'], { :size => 7, :border => 0, :style => :bold } if @xml[endereco + '/xLgr'] != ''
339 | @pdf.ibox 0.90, 2.00, 13.50, 12.81, '', 'UF: ' , { :size => 7, :border => 0, :style => :italic }
340 | @pdf.ibox 0.90, 2.00, 14.50, 12.81, '', @xml[endereco + '/UF'], { :size => 7, :border => 0, :style => :bold }
341 | @pdf.ibox 0.90, 5.00, 16.50, 12.81, '', 'País: ' , { :size => 7, :border => 0, :style => :italic }
342 | @pdf.ibox 0.90, 5.00, 17.50, 12.81, '', @xml[endereco + '/xPais'], { :size => 7, :border => 0, :style => :bold }
343 | @pdf.ibox 0.90, 5.00, 0.28, 13.17, '', 'CNPJ/CPF: ' , { :size => 7, :border => 0, :style => :italic }
344 | @pdf.ibox 0.90, 5.00, 1.88, 13.17, '', Helper.format_cnpj(@xml[toma + '/CNPJ']), { :size => 7, :border => 0, :style => :bold } if @xml[toma + '/CNPJ'] != ''
345 | @pdf.ibox 0.90, 5.00, 1.88, 13.17, '', @xml[toma + '/CPF'][0,3] + '.' + @xml[toma + '/CPF'][3,3] + '.' + @xml[toma + '/CPF'][6,3] + '-' + @xml[toma + '/CPF'][9,2], { :size => 7, :border => 0, :style => :bold } if @xml[toma + '/CPF'] != ''
346 | @pdf.ibox 0.90, 5.00, 5.60, 13.17, '', 'Inscr. Est.: ', { :size => 7, :border => 0, :style => :italic }
347 | @pdf.ibox 0.90, 5.00, 7.20, 13.17, '', @xml[toma + '/IE'], { :size => 7, :border => 0, :style => :bold }
348 | @pdf.ibox 0.90, 5.00, 10.50, 13.17, '', 'Fone: ' , { :size => 7, :border => 0, :style => :italic }
349 | fone = @xml[toma + '/fone']
350 | unless fone.eql?('')
351 | if fone.size > 8
352 | @pdf.ibox 0.90, 5.00, 11.80, 13.17, '', '(' + @xml[toma + '/fone'][0,2] + ')' + @xml[toma + '/fone'][2,4] + '-' + @xml[toma + '/fone'][6,4], { :size => 7, :border => 0, :style => :bold }
353 | else
354 | @pdf.ibox 0.90, 5.00, 11.80, 13.17, '', @xml[toma + '/fone'][0,4] + '-' + @xml[toma + '/fone'][4,4], { :size => 7, :border => 0, :style => :bold }
355 | end
356 | end
357 | end
358 | end
359 |
360 | def render_produto
361 | #produto predominante/outras caract, valor total
362 | #@pdf.ibox 0.92, 20.49, 0.25, 13.82
363 | @pdf.ibox 0.90, 6.83, 0.25, 13.82, 'PRODUTO PREDOMINANTE', @xml['infCarga/proPred'], {:size => 7, :style => :bold }
364 | @pdf.ibox 0.90, 6.83, 7.09, 13.82, 'OUTRAS CARACTERÍSTICAS DA CARGA', @xml['infCarga/xOutCat'], {:size => 7, :style => :bold }
365 | @pdf.ibox 0.90, 6.82, 13.92, 13.82, 'VALOR TOTAL DA MERCADORIA', @xml['infCarga/vCarga'].empty? ? '0,00' : @xml['infCarga/vCarga'], {:size => 7, :style => :bold }
366 | end
367 |
368 | def render_quantidade
369 | #quantidade carga
370 | @pdf.ibox 0.90, 1.07, 0.25, 14.72, '', 'QTD.', { :size => 7, :align => :center, :style => :italic}
371 | @pdf.ibox 0.90, 1.07, 0.25, 15.02, '', 'CARGA', { :size => 7, :align => :center, :style => :italic, :border => 0}
372 | @pdf.ibox 0.90, 3.50, 1.33, 14.72, 'QT./UN. MEDIDA', '', { :size => 7, :style => :italic }
373 | @pdf.ibox 0.90, 3.50, 4.83, 14.72, 'QT./UN. MEDIDA', '', { :size => 7, :style => :italic }
374 | @pdf.ibox 0.90, 3.50, 8.33, 14.72, 'QT./UN. MEDIDA', '', { :size => 7, :style => :italic }
375 | x = 1.33
376 | @xml.collect('xmlns', 'infQ') { |det|
377 | if !det.css('cUnid').text.eql?('00')
378 | desc = "#{det.css('qCarga').text} #{det.css('tpMed').text}"
379 | @pdf.ibox 0.90, 3.50, x, 15.02, '', desc, { :size => 7, :style => :bold, :border => 0 }
380 | x = x + 3.50
381 | end
382 | }
383 | end
384 |
385 | def render_seguradora
386 | #seguradora
387 | respons = case @xml['seg/respSeg']
388 | when '0' then 'Remetente'
389 | when '1' then 'Expedidor'
390 | when '2' then 'Recebedor'
391 | when '3' then 'Destinatário'
392 | when '4' then 'Emitente do CT-e'
393 | when '5' then 'Tomador de Serviço'
394 | else ''
395 | end
396 | @pdf.ibox 0.30, 8.91, 11.83, 14.72, 'Nome da Seguradora: ' + @xml['seg/xSeg'], '', {:size => 7}
397 | @pdf.ibox 0.60, 3.70, 11.83, 15.02, '', 'Responsável: ' + respons, {:size => 6}
398 | @pdf.ibox 0.60, 2.50, 15.52, 15.02, '', 'Nº Apólice: ' + @xml['seg/nApol'], { :size => 6}
399 | @pdf.ibox 0.60, 2.73, 18.01, 15.02, '', 'Nº Averbação: ' + @xml['seg/nAver'], { :size => 6}
400 | end
401 |
402 | def render_valor_da_prestacao
403 | #componentes do valor da prestação de serviço
404 | @pdf.ibox 0.40, 20.49, 0.25, 15.63, '', 'COMPONENTES DO VALOR DA PRESTAÇÃO DE SERVIÇO', { :align => :left, :size => 7, :style => :bold, :border => 0}
405 | @pdf.ibox 1.40, 4.00, 0.25, 16.03
406 | @pdf.ibox 1.40, 2.12, 0.25, 16.02, 'NOME', '', { :size => 7, :border => 0 }
407 | @pdf.ibox 1.40, 1.88, 3.05, 16.02, 'VALOR', '', { :size => 7, :border => 0 }
408 | @pdf.ibox 1.40, 4.00, 4.26, 16.03
409 | @pdf.ibox 1.40, 2.12, 4.26, 16.02, 'NOME', '', { :size => 7, :border => 0 }
410 | @pdf.ibox 1.40, 1.88, 7.14, 16.02, 'VALOR', '', { :size => 7, :border => 0 }
411 | @pdf.ibox 1.40, 4.00, 8.25, 16.03
412 | @pdf.ibox 1.40, 2.12, 8.25, 16.02, 'NOME', '', { :size => 7, :border => 0 }
413 | @pdf.ibox 1.40, 1.88, 11.05, 16.02, 'VALOR', '', { :size => 7, :border => 0 }
414 | @pdf.ibox 1.40, 4.00, 12.26, 16.03
415 | @pdf.ibox 1.40, 2.12, 12.26, 16.02, 'NOME', '', { :size => 7, :border => 0 }
416 | @pdf.ibox 1.40, 1.88, 15.05, 16.02, 'VALOR', '',{ :size => 7, :border => 0 }
417 | x = 0.25
418 | y = 16.40
419 | @xml.collect('xmlns', 'Comp') { |det|
420 | @pdf.ibox 1.40, 2.12, x, y, '', det.css('xNome').text, { :size => 6, :border => 0, :style => :bold }
421 | @pdf.inumeric 1.40, 1.88, x + 1.80, y, '', det.css('vComp').text, { :size => 7, :border => 0, :align => :right, :style => :bold }
422 | y = y + 0.40
423 | if y > 16.80
424 | x = x + 4.00
425 | y = 16.40
426 | end
427 | }
428 | @pdf.ibox 0.70, 4.48, 16.26, 16.03
429 | @pdf.inumeric 0.70, 4.48, 16.26, 16.03, 'VALOR TOTAL DO SERVIÇO', @xml['vPrest/vTPrest'], { :align => :center, :size => 6, :style => :bold}
430 | @pdf.inumeric 0.70, 4.48, 16.26, 16.73, 'VALOR A RECEBER', @xml['vPrest/vRec'],{ :align => :center, :size => 6, :style => :bold }
431 | end
432 |
433 | def render_impostos
434 | #informações relativas ao Imposto
435 | @pdf.ibox 0.40, 20.49, 0.25, 17.42, '', 'INFORMAÇÕES RELATIVAS AO IMPOSTO', { :align => :left, :size => 7, :border => 0, :style => :bold }
436 | complemento = ''
437 | if !@xml['imp/ICMS/ICMS00'].eql?("")
438 | cst = '00 - Tributação Normal ICMS'
439 | tipoIcms = 'ICMS00'
440 | elsif !@xml['imp/ICMS/ICMS20'].eql?("")
441 | cst = '20 - Tributação com BC reduzida do ICMS'
442 | tipoIcms = 'ICMS20'
443 | elsif !@xml['imp/ICMS/ICMS45'].eql?("")
444 | cst = '40 - ICMS Isenção; 41 - ICMS não tributada; 51 - ICMS diferido'
445 | tipoIcms = 'ICMS45'
446 | elsif !@xml['imp/ICMS/ICMS60'].eql?("")
447 | cst = '60 - ICMS cobrado anteriormente por Substituição Tributária'
448 | tipoIcms = 'ICMS60'
449 | complemento = 'STRet'
450 | elsif !@xml['imp/ICMS/ICMS90'].eql?("")
451 | cst = '90 - ICMS outros'
452 | tipoIcms = 'ICMS90'
453 | elsif !@xml['imp/ICMS/ICMSSN'].eql?("")
454 | cst = 'Simples Nacional'
455 | tipoIcms = 'ICMSSN'
456 | else
457 | cst = '90 - ICMS outros'
458 | tipoIcms = 'ICMSOutraUF'
459 | end
460 | @pdf.ibox 0.90, 10.00, 0.25, 17.83, 'SITUAÇÃO TRIBUTÁRIA', cst, { :size => 7, :style => :bold }
461 | @pdf.inumeric 0.90, 3.00, 10.25, 17.83, 'BASE DE CÁLCULO', @xml['imp/ICMS/'+ tipoIcms + '/vBC'+ complemento], { :size => 7, :style => :bold }
462 | @pdf.inumeric 0.90, 1.00, 13.25, 17.83, 'AL. ICMS', @xml['imp/ICMS/' + tipoIcms + '/pICMS'+ complemento], { :size => 7, :style => :bold }
463 | @pdf.inumeric 0.90, 3.00, 14.25, 17.83, 'VALOR ICMS', @xml['imp/ICMS/' + tipoIcms + '/vICMS'],{ :size => 7, :style => :bold }
464 | @pdf.inumeric 0.90, 2.00, 17.25, 17.83, '% RED.BC.CALC.', @xml['imp/ICMS/' + tipoIcms + '/pRedBC'], { :size => 7, :style => :bold }
465 | @pdf.inumeric 0.90, 1.49, 19.25, 17.83, 'ICMS ST.', @xml['imp/ICMS/' + tipoIcms + '/vICMS'+ complemento], { :size => 7, :style => :bold }
466 | end
467 |
468 | def render_documentos_originarios
469 | #documentos originários
470 | @pdf.ibox 0.40, 20.49, 0.25, 18.73, '', 'DOCUMENTOS ORIGINÁRIOS', { :align => :left, :size => 7, :style => :bold, :border => 0 }
471 | @pdf.ibox 5.52, 1.75, 0.25, 19.13, 'TP DOC.', '', { :size => 7}
472 | @pdf.ibox 5.52, 5.50, 2.00, 19.13, 'CNPJ/CPF EMITENTE/CHAVE', '', { :size => 7}
473 | @pdf.ibox 5.52, 1.00, 7.50, 19.13, 'SÉRIE', '', { :size => 7}
474 | @pdf.ibox 5.52, 2.00, 8.50, 19.13, 'Nº DOCUMENTO', '', { :size => 7}
475 | @pdf.ibox 5.52, 1.75, 10.50, 19.13, 'TP DOC.', '', { :size => 7}
476 | @pdf.ibox 5.52, 5.50, 12.25, 19.13, 'CNPJ/CPF EMITENTE/CHAVE', '', { :size => 7}
477 | @pdf.ibox 5.52, 1.00, 17.75, 19.13, 'SÉRIE', '', { :size => 7}
478 | @pdf.ibox 5.52, 2.00, 18.74, 19.13, 'Nº DOCUMENTO', '', { :size => 7}
479 | x = 0.25
480 | y = 19.43
481 | @xml.collect('xmlns', 'infNF') { |det|
482 | x, y = 0.25, y + 0.25 if x == 20.75
483 | @pdf.ibox 5.52, 1.50, x, y, '', det.css('mod').text, { :size => 7, :border => 0, :style => :bold }
484 | x = x + 1.75
485 | @pdf.ibox 5.52, 2.25, x, y, '', Helper.format_cnpj(@xml['rem/CNPJ']), { :size => 7, :border => 0, :style => :bold } if @xml['rem/CNPJ'] != ''
486 | @pdf.ibox 5.52, 5.25, x, y, '', @xml['rem/CPF'][0,3] + '.' + @xml['rem/CPF'][3,3] + '.' +@xml['rem/CPF'][6,3] + '-' + @xml['rem/CPF'][9,2], { :size => 7, :border => 0, :style => :bold } if @xml['rem/CPF'] != ''
487 | x = x + 5.50
488 | @pdf.ibox 5.52, 0.75, x, y, '', det.css('serie').text, { :size => 7, :border => 0, :style => :bold }
489 | x = x + 1.00
490 | @pdf.ibox 5.52, 1.75, x, y, '', det.css('nDoc').text, { :size => 7, :border => 0, :style => :bold }
491 | x = x + 2.00
492 | }
493 | # NFe
494 | @xml.collect('xmlns', 'infNFe') { |det|
495 | chave = det.css('chave').text
496 | unless chave.empty?
497 | x, y = 0.25, y + 0.25 if x == 20.75
498 | @pdf.ibox 5.52, 1.50, x, y, '', 'NFe', { :size => 7, :border => 0, :style => :bold }
499 | x = x + 1.75
500 | @pdf.ibox 5.52, 5.25, x, y, '', chave, { :size => 6, :border => 0, :style => :bold }
501 | x = x + 5.50
502 | @pdf.ibox 5.52, 0.75, x, y, '', chave[22, 3], { :size => 7, :border => 0, :style => :bold }
503 | x = x + 1.00
504 | @pdf.ibox 5.52, 1.75, x, y, '', chave[25, 9].gsub(/^[0]+/, ''), { :size => 7, :border => 0, :style => :bold }
505 | x = x + 2.00
506 | end
507 | }
508 | end
509 |
510 | def render_observacoes
511 | #OBSERVAÇÕES
512 | @pdf.ibox 0.40, 20.49, 0.25, 24.65, '', 'OBSERVAÇÕES', { :align => :left, :size => 7, :style => :bold, :border => 0 }
513 | @pdf.ibox 1.40, 20.49, 0.25, 25.05, '', (@xml['compl/xObs'] + "\n CTe COMPLEMENTADO " + "Chave: " + @xml['infCteComp/chave'] + " Valor de serviço: " +
514 | Helper.numerify(@xml['vPresComp/vTPrest']).to_s ), { :align => :left, :size => 7 }
515 | end
516 |
517 | def render_modal
518 | #informações do modal
519 | @pdf.ibox 0.40, 20.49, 0.25, 26.45, '', 'INFORMAÇÕES ESPECÍFICAS DO MODAL RODOVIÁRIO - CARGA FRACIONADA', { :align => :left, :size => 7, :style => :bold, :border => 0}
520 | @pdf.ibox 0.90, 3.00, 0.25, 26.85, 'RNTRC DA EMPRESA', @xml['rodo/RNTRC'], { :size => 7, :style => :bold }
521 | @pdf.ibox 0.90, 3.00, 3.25, 26.85, 'CIOT', @xml['rodo/CIOT'], { :size => 7, :style => :bold }
522 |
523 | dtentrega = @xml['rodo/dPrev'][8, 2].to_s + '/' + @xml['rodo/dPrev'][5, 2].to_s + '/' + @xml['rodo/dPrev'][0, 4].to_s
524 |
525 | @pdf.ibox 0.90, 4.00, 6.25, 26.85, 'DATA PREVISTA DE ENTREGA', dtentrega, { :size => 7, :style => :bold }
526 | @pdf.ibox 0.90, 10.49, 10.25, 26.85, '', 'ESTE CONHECIMENTO DE TRANSPORTE ATENDE A LEGISLAÇÃO DE TRANSPORTE RODOVIÁRIO EM VIGOR', { :size => 5, :align => :center }
527 |
528 | #informações do modal
529 | @pdf.ibox 0.40, 15.49, 0.25, 27.75, '', 'USO EXCLUSIVO DO EMISSOR DO CT-e', { :align => :center, :size => 7 }
530 | @pdf.ibox 1.20, 15.49, 0.25, 28.15, '', '', { :align => :center, :size => 6 }
531 | @pdf.ibox 0.40, 5.00, 15.74, 27.75, '', 'RESERVADO AO FISCO', { :align => :center, :size => 7 }
532 | @pdf.ibox 1.20, 5.00, 15.74, 28.15, '', '', { :align => :center, :size => 6 }
533 | end
534 | end
535 | end
536 |
--------------------------------------------------------------------------------
/lib/ruby_danfe/dacteos_generator.rb:
--------------------------------------------------------------------------------
1 | # coding: utf-8
2 | module RubyDanfe
3 | class DacteosGenerator < RubyDanfe::DacteGenerator
4 |
5 |
6 | def render_infobox
7 | # infobox
8 | @pdf.ibox 0.90, 9.39, 7.92, 0.54, '', 'DACTEOS', { :align => :center, :style => :bold, :size => 12}
9 | @pdf.ibox 0.90, 9.39, 7.92, 0.94, '', 'Documento auxiliar do Conhecimento de Transporte Eletrônico para Outros Serviços', { :align => :center, :border => 0, :size => 7 }
10 |
11 | @pdf.ibox 0.90, 3.43, 17.31, 0.54, '', 'MODAL', { :align => :center, :size => 7 }
12 | @pdf.ibox 0.90, 3.43, 17.31, 0.84, '', 'RODOVIÁRIO', { :align => :center, :size => 8, :border => 0, :style => :bold }
13 | @pdf.ibox 0.91, 1.98, 7.92, 1.44, 'MODELO', @xml['ide/mod'], {:size => 8, :align => :center}
14 | @pdf.ibox 0.91, 0.75, 9.90, 1.44, 'SERIE', @xml['ide/serie'], {:size => 8, :align => :center}
15 | @pdf.ibox 0.91, 2.48, 10.65, 1.44, 'NÚMERO', @xml['ide/nCT'], {:size => 8, :align => :center}
16 | @pdf.ibox 0.91, 0.97, 13.13, 1.44, 'FL', '1/1', {:size => 8, :align => :center}
17 | emiss = @xml['ide/dhEmi'][8, 2] + '/' + @xml['ide/dhEmi'][5, 2] + '/' + @xml['ide/dhEmi'][0, 4] + " " +
18 | @xml['ide/dhEmi'][11, 8]
19 |
20 | @pdf.ibox 0.91, 3.21, 14.10, 1.44, 'DATA E HORA DE EMISSÃO', emiss, {:size => 8, :align => :center}
21 | @pdf.ibox 0.91, 3.43, 17.31, 1.44, 'INSC. SUFRAMA DESTINATÁRIO', @xml['dest/ISUF'], {:size => 8, :align => :center}
22 | @pdf.ibox 1.13, 12.82, 7.92, 2.35
23 | @pdf.ibarcode 0.85, 12.82, 9.25, 3.35, @xml.attrib('infCte', 'Id')[3..-1]
24 | @pdf.ibox 0.62, 12.82, 7.92, 3.48, 'Chave de acesso', ''
25 | @pdf.ibox 0.90, 12.82, 7.92, 3.62, '', @xml.attrib('infCte', 'Id')[3..-1].gsub(/(\d)(?=(\d\d\d\d)+(?!\d))/, "\\1 "), {:style => :bold, :align => :center, :size => 8, :border => 0}
26 | @pdf.ibox 1.13, 12.82, 7.92, 4.10, '', 'Consulta de autenticidade no portal do CT-e, no site da Sefaz Autorizadora, ou em http://www.cte.fazenda.gov.br/portal',
27 | { :align => :center, :valign => :center, :style => :bold, :size => 8 }
28 | @pdf.ibox 0.71, 12.82, 7.92, 5.23, 'Protocolo de Autorização de Uso'
29 | @pdf.ibox 0.90, 12.82, 7.92, 5.38, '', @xml['infProt/nProt'], { :style => :bold, :align => :left, :border => 0, :size => 8 }
30 | @pdf.ibox 1.33, 7.67, 0.25, 4.61, 'CFOP - NATUREZA DA PRESTAÇÃO', @xml['ide/CFOP'] + ' - ' + @xml['ide/natOp'], { :align => :left, :size => 7, :style => :bold }
31 | # UFIni -xMunIni
32 | @pdf.ibox 0.92, 10.25, 0.25, 5.94, 'INÍCIO DA PRESTAÇÃO', @xml['ide/UFIni'] + ' - ' + @xml['ide/xMunIni']
33 | # UFFim -cMunFim – xMunFim
34 | @pdf.ibox 0.92, 10.24, 10.50, 5.94, 'TÉRMINO DA PRESTAÇÃO', @xml['ide/UFFim'] + ' - ' + @xml['ide/cMunFim'] + ' - ' + @xml['ide/xMunFim']
35 | end
36 |
37 | def render_tomador
38 | # tomador
39 | toma_cnpj = @xml['toma/CNPJ']
40 | @pdf.ibox 0.90, 3.83, 0.25, 3.71, 'TOMADOR DO SERVIÇO', Helper.format_cnpj(toma_cnpj), { :align => :center, :size => 8, :style => :bold }
41 | end
42 |
43 |
44 | def render_tomador_do_servico
45 | # tomador
46 | @pdf.ibox 1.45, 20.49, 0.25, 12.38
47 |
48 | endereco = 'enderToma'
49 | @pdf.ibox 0.90, 10.00, 0.28, 12.45, '', 'Tomador do Serviço: ', { :size => 7, :border => 0, :style => :italic }
50 | @pdf.ibox 0.90, 10.00, 2.58, 12.45, '', @xml['toma/xNome'], { :size => 7, :border => 0, :style => :bold }
51 | @pdf.ibox 0.90, 10.00, 10.50, 12.45, '', 'Município: ', { :size => 7, :border => 0, :style => :italic }
52 | @pdf.ibox 0.90, 10.00, 11.80, 12.45, '', @xml['enderToma/xMun'], { :size => 7, :border => 0, :style => :bold }
53 | @pdf.ibox 0.90, 4.00, 18.00, 12.45, '', 'CEP: ', { :size => 7, :border => 0, :style => :italic }
54 | @pdf.ibox 0.90, 4.00, 18.70, 12.45, '', @xml['enderToma/CEP'][0,2] + '.' + @xml['enderToma/CEP'][3,3] + '-' + @xml['enderToma/CEP'][5,3], { :size => 7, :border => 0, :style => :bold } if @xml['enderToma/CEP'] != ''
55 | @pdf.ibox 0.90, 10.00, 0.28, 12.81, '', 'Endereço: ', { :size => 7, :border => 0, :style => :italic }
56 | @pdf.ibox 0.90, 10.00, 1.88, 12.81, '', @xml['enderToma/xLgr'] + ', ' + @xml['enderToma/nro'] + (@xml['enderToma/xCpl'] != '' ? ' - ' + @xml['enderToma/xCpl'] : '') + ' - ' + @xml['enderToma/xBairro'], { :size => 7, :border => 0, :style => :bold } if @xml['enderToma/xLgr'] != ''
57 | @pdf.ibox 0.90, 2.00, 13.50, 12.81, '', 'UF: ' , { :size => 7, :border => 0, :style => :italic }
58 | @pdf.ibox 0.90, 2.00, 14.50, 12.81, '', @xml['enderToma/UF'], { :size => 7, :border => 0, :style => :bold }
59 | @pdf.ibox 0.90, 5.00, 16.50, 12.81, '', 'País: ' , { :size => 7, :border => 0, :style => :italic }
60 | @pdf.ibox 0.90, 5.00, 17.50, 12.81, '', @xml['enderToma/xPais'], { :size => 7, :border => 0, :style => :bold }
61 | @pdf.ibox 0.90, 5.00, 0.28, 13.17, '', 'CNPJ/CPF: ' , { :size => 7, :border => 0, :style => :italic }
62 | @pdf.ibox 0.90, 5.00, 1.88, 13.17, '', Helper.format_cnpj(@xml['toma/CNPJ']), { :size => 7, :border => 0, :style => :bold } if @xml['toma/CNPJ'] != ''
63 | @pdf.ibox 0.90, 5.00, 1.88, 13.17, '', @xml['toma/CPF'][0,3] + '.' + @xml['toma/CPF'][3,3] + '.' + @xml['toma/CPF'][6,3] + '-' + @xml['toma/CPF'][9,2], { :size => 7, :border => 0, :style => :bold } if @xml['toma/CPF'] != ''
64 | @pdf.ibox 0.90, 5.00, 5.60, 13.17, '', 'Inscr. Est.: ', { :size => 7, :border => 0, :style => :italic }
65 | @pdf.ibox 0.90, 5.00, 7.20, 13.17, '', @xml['toma/IE'], { :size => 7, :border => 0, :style => :bold }
66 | @pdf.ibox 0.90, 5.00, 10.50, 13.17, '', 'Fone: ' , { :size => 7, :border => 0, :style => :italic }
67 | fone = @xml['toma/fone']
68 | unless fone.eql?('')
69 | if fone.size > 8
70 | @pdf.ibox 0.90, 5.00, 11.80, 13.17, '', '(' + @xml['toma/fone'][0,2] + ')' + @xml['toma/fone'][2,4] + '-' + @xml['toma/fone'][6,4], { :size => 7, :border => 0, :style => :bold }
71 | else
72 | @pdf.ibox 0.90, 5.00, 11.80, 13.17, '', @xml['toma/fone'][0,4] + '-' + @xml['toma/fone'][4,4], { :size => 7, :border => 0, :style => :bold }
73 | end
74 | end
75 | end
76 |
77 | end
78 | end
79 |
--------------------------------------------------------------------------------
/lib/ruby_danfe/danfe_generator.rb:
--------------------------------------------------------------------------------
1 | # coding: utf-8
2 | module RubyDanfe
3 | class DanfeGenerator
4 | def initialize(xml)
5 | @xml = xml
6 | @pdf = Document.new
7 | @vol = 0
8 | end
9 |
10 | def generatePDF
11 | @pdf.repeat :all do
12 | render_canhoto
13 | render_emitente
14 | render_dados_adicionais_box
15 | end
16 |
17 | @pdf.repeat :all, dynamic: true do
18 | render_cabecalho_dos_produtos(@pdf.page_number)
19 | end
20 |
21 | render_titulo
22 | render_faturas
23 | render_calculo_do_imposto
24 | render_transportadora_e_volumes
25 | render_calculo_do_issqn
26 |
27 | render_dados_adicionais
28 |
29 | @pdf.go_to_page(1)
30 | render_produtos
31 |
32 | @pdf.page_count.times do |i|
33 | @pdf.go_to_page(i + 1)
34 | @pdf.ibox 1.00, 3.08, 6.71, 5.54, '',
35 | "FOLHA #{i + 1} de #{@pdf.page_count}", {:size => 8, :align => :center, :valign => :center, :border => 0, :style => :bold}
36 | end
37 |
38 | @pdf
39 | end
40 |
41 | private
42 | def render_canhoto
43 | @pdf.ibox 0.85, 16.10, 0.25, 0.42, "RECEBEMOS DE " + @xml['emit/xNome'] + " OS PRODUTOS CONSTANTES DA NOTA FISCAL INDICADA ABAIXO"
44 | @pdf.ibox 0.85, 4.10, 0.25, 1.27, "DATA DE RECEBIMENTO"
45 | @pdf.ibox 0.85, 12.00, 4.35, 1.27, "IDENTIFICAÇÃO E ASSINATURA DO RECEBEDOR"
46 |
47 | @pdf.ibox 1.70, 4.50, 16.35, 0.42, '',
48 | "NF-e\n" +
49 | "N°. " + @xml['ide/nNF'] + "\n" +
50 | "SÉRIE " + @xml['ide/serie'], {:align => :center, :valign => :center}
51 | end
52 |
53 | def render_emitente
54 | @pdf.ibox 3.92, 6.46, 0.25, 2.54, '',
55 | @xml['emit/xNome'] + "\n" +
56 | @xml['enderEmit/xLgr'] + ", " + @xml['enderEmit/nro'] + "\n" +
57 | @xml['enderEmit/xBairro'] + " - " + @xml['enderEmit/CEP'] + "\n" +
58 | @xml['enderEmit/xMun'] + "/" + @xml['enderEmit/UF'] + "\n" +
59 | @xml['enderEmit/fone'] + " " + @xml['enderEmit/email'], {:align => :center, :valign => :center}
60 |
61 | @pdf.ibox 3.92, 3.08, 6.71, 2.54
62 |
63 | @pdf.ibox 0.60, 3.08, 6.71, 2.54, '', "DANFE", {:size => 12, :align => :center, :border => 0, :style => :bold}
64 | @pdf.ibox 1.20, 3.08, 6.71, 3.14, '', "DOCUMENTO AUXILIAR DA NOTA FISCAL ELETRÔNICA", {:size => 8, :align => :center, :border => 0}
65 | @pdf.ibox 0.60, 3.08, 6.71, 4.34, '', "#{@xml['ide/tpNF']} - " + (@xml['ide/tpNF'] == '0' ? 'ENTRADA' : 'SAÍDA'), {:size => 8, :align => :center, :border => 0}
66 |
67 | @pdf.ibox 1.00, 3.08, 6.71, 4.94, '',
68 | "N°. " + @xml['ide/nNF'] + "\n" +
69 | "SÉRIE " + @xml['ide/serie'], {:size => 8, :align => :center, :valign => :center, :border => 0, :style => :bold}
70 |
71 | @pdf.ibox 2.20, 11.02, 9.79, 2.54
72 | @pdf.ibarcode 1.50, 8.00, 10.4010, 4.44, @xml['chNFe']
73 | @pdf.ibox 0.85, 11.02, 9.79, 4.74, "CHAVE DE ACESSO", @xml['chNFe'].gsub(/\D/, '').gsub(/(\d)(?=(\d\d\d\d)+(?!\d))/, "\\1 "), {:style => :bold, :align => :center}
74 | @pdf.ibox 0.85, 11.02, 9.79, 5.60 , '', "Consulta de autenticidade no portal nacional da NF-e www.nfe.fazenda.gov.br/portal ou no site da Sefaz Autorizadora", {:align => :center, :size => 8}
75 | @pdf.ibox 0.85, 10.54, 0.25, 6.46, "NATUREZA DA OPERAÇÃO", @xml['ide/natOp']
76 | @pdf.ibox 0.85, 10.02, 10.79, 6.46, "PROTOCOLO DE AUTORIZAÇÃO DE USO", @xml['infProt/nProt'] + ' ' + Helper.format_datetime(@xml['infProt/dhRecbto']) , {:align => :center}
77 | @pdf.ibox 0.85, 6.86, 0.25, 7.31, "INSCRIÇÃO ESTADUAL", @xml['emit/IE']
78 | @pdf.ibox 0.85, 6.86, 7.11, 7.31, "INSC.ESTADUAL DO SUBST. TRIBUTÁRIO", @xml['emit/IEST']
79 | @pdf.ibox 0.85, 6.84, 13.97, 7.31, "CNPJ", @xml['emit/CNPJ']
80 | end
81 |
82 | def render_titulo
83 | @pdf.ititle 0.42, 10.00, 0.25, 8.16, "DESTINATÁRIO / REMETENTE"
84 |
85 | @pdf.ibox 0.85, 12.32, 0.25, 8.58, "NOME/RAZÃO SOCIAL", @xml['dest/xNome']
86 | @pdf.ibox 0.85, 5.33, 12.57, 8.58, "CNPJ/CPF", @xml['dest/CNPJ'] if @xml['dest/CNPJ'] != ''
87 | @pdf.ibox 0.85, 5.33, 12.57, 8.58, "CNPJ/CPF", @xml['dest/CPF'] if @xml['dest/CPF'] != ''
88 | @pdf.ibox 0.85, 5.33, 12.57, 8.58, "CNPJ/CPF/Passaporte", @xml['dest/idEstrangeiro'] if @xml['dest/idEstrangeiro'] != ''
89 | @pdf.ibox 0.85, 2.92, 17.90, 8.58, "DATA DA EMISSÃO", (not @xml['ide/dEmi'].empty?) ? Helper.format_date(@xml['ide/dEmi']) : Helper.format_date(@xml['ide/dhEmi']) , {:align => :right}
90 | @pdf.ibox 0.85, 10.16, 0.25, 9.43, "ENDEREÇO", @xml['enderDest/xLgr'] + " " + @xml['enderDest/nro']
91 | @pdf.ibox 0.85, 4.83, 10.41, 9.43, "BAIRRO", @xml['enderDest/xBairro']
92 | @pdf.ibox 0.85, 2.67, 15.24, 9.43, "CEP", @xml['enderDest/CEP']
93 | @pdf.ibox 0.85, 2.92, 17.90, 9.43, "DATA DA SAÍDA/ENTRADA", (not @xml['ide/dSaiEnt'].empty?) ? Helper.format_date(@xml['ide/dSaiEnt']) : Helper.format_date(@xml['ide/dhSaiEnt']), {:align => :right}
94 | @pdf.ibox 0.85, 7.11, 0.25, 10.28, "MUNICÍPIO", @xml['enderDest/xMun']
95 | @pdf.ibox 0.85, 4.06, 7.36, 10.28, "FONE/FAX", @xml['enderDest/fone']
96 | @pdf.ibox 0.85, 1.14, 11.42, 10.28, "UF", @xml['enderDest/UF']
97 | @pdf.ibox 0.85, 5.33, 12.56, 10.28, "INSCRIÇÃO ESTADUAL", @xml['dest/IE']
98 | @pdf.ibox 0.85, 2.92, 17.90, 10.28, "HORA DE SAÍDA", Helper.format_time(@xml['ide/hSaiEnt']), {:align => :right}
99 | @pdf.ibox 0.85, 2.92, 17.90, 10.28, "HORA DE SAÍDA", (not @xml['ide/hSaiEnt'].empty?) ? Helper.format_time(@xml['ide/hSaiEnt']) : Helper.extract_time_from_date(@xml['ide/dhSaiEnt']) , {:align => :right}
100 | end
101 |
102 | def render_faturas
103 | @pdf.ititle 0.42, 10.00, 0.25, 11.12, "FATURA / DUPLICATAS"
104 | @pdf.ibox 0.85, 20.57, 0.25, 11.51
105 |
106 | x = 0.25
107 | y = 11.51
108 | @xml.collect('xmlns', 'dup') do |det|
109 | @pdf.ibox 0.85, 2.12, x, y, '', 'Núm.:', { :size => 6, :border => 0, :style => :italic }
110 | @pdf.ibox 0.85, 2.12, x + 0.70, y, '', det.css('nDup').text, { :size => 6, :border => 0 }
111 | @pdf.ibox 0.85, 2.12, x, y + 0.20, '', 'Venc.:', { :size => 6, :border => 0, :style => :italic }
112 | dtduplicata = det.css('dVenc').text
113 | dtduplicata = dtduplicata[8,2] + '/' + dtduplicata[5, 2] + '/' + dtduplicata[0, 4]
114 | @pdf.ibox 0.85, 2.12, x + 0.70, y + 0.20, '', dtduplicata, { :size => 6, :border => 0 }
115 | @pdf.ibox 0.85, 2.12, x, y + 0.40, '', 'Valor: R$', { :size => 6, :border => 0, :style => :italic }
116 | @pdf.inumeric 0.85, 1.25, x + 0.70, y + 0.40, '', det.css('vDup').text, { :size => 6, :border => 0 }
117 | x = x + 2.30
118 | end
119 |
120 | @xml.collect('xmlns', 'fat') do |det|
121 | @pdf.ibox 0.85, 2.12, x, y, '', 'Núm.:', { :size => 4, :border => 0, :style => :italic }
122 | @pdf.ibox 0.85, 2.12, x + 0.70, y, '', det.css('nFat').text, { :size => 4, :border => 0 }
123 |
124 | @pdf.ibox 0.85, 2.12, x, y + 0.20, '', 'vOrig.: R$', { :size => 4, :border => 0, :style => :italic }
125 | @pdf.inumeric 0.85, 1.25, x + 0.70, y + 0.18, '', det.css('vOrig').text, { :size => 4, :border => 0 }
126 |
127 | @pdf.ibox 0.85, 2.12, x, y + 0.40, '', 'vDesc: R$', { :size => 4, :border => 0, :style => :italic }
128 | @pdf.inumeric 0.85, 1.25, x + 0.70, y + 0.36, '', det.css('vDesc').text, { :size => 4, :border => 0 }
129 |
130 | @pdf.ibox 0.85, 2.12, x, y + 0.55, '', 'vLiq: R$', { :size => 4, :border => 0, :style => :italic }
131 | @pdf.inumeric 0.85, 1.25, x + 0.70, y + 0.54, '', det.css('vLiq').text, { :size => 4, :border => 0 }
132 |
133 | x = x + 2.30
134 | end
135 | end
136 |
137 | def render_calculo_do_imposto
138 | @pdf.ititle 0.42, 5.60, 0.25, 12.36, "CÁLCULO DO IMPOSTO"
139 |
140 | @pdf.inumeric 0.85, 4.06, 0.25, 12.78, "BASE DE CÁLCULO DO ICMS", @xml['ICMSTot/vBC']
141 | @pdf.inumeric 0.85, 4.06, 4.31, 12.78, "VALOR DO ICMS", @xml['ICMSTot/vICMS']
142 | @pdf.inumeric 0.85, 4.06, 8.37, 12.78, "BASE DE CÁLCULO DO ICMS ST", @xml['ICMSTot/vBCST']
143 | @pdf.inumeric 0.85, 4.06, 12.43, 12.78, "VALOR DO ICMS ST", @xml['ICMSTot/vST']
144 | @pdf.inumeric 0.85, 4.32, 16.49, 12.78, "VALOR TOTAL DOS PRODUTOS", @xml['ICMSTot/vProd']
145 | @pdf.inumeric 0.85, 3.46, 0.25, 13.63, "VALOR DO FRETE", @xml['ICMSTot/vFrete']
146 | @pdf.inumeric 0.85, 3.46, 3.71, 13.63, "VALOR DO SEGURO", @xml['ICMSTot/vSeg']
147 | @pdf.inumeric 0.85, 3.46, 7.17, 13.63, "DESCONTO", @xml['ICMSTot/vDesc']
148 | @pdf.inumeric 0.85, 3.46, 10.63, 13.63, "OUTRAS DESPESAS ACESSORIAS", @xml['ICMSTot/vOutro']
149 | @pdf.inumeric 0.85, 3.46, 14.09, 13.63, "VALOR DO IPI", @xml['ICMSTot/vIPI']
150 | @pdf.inumeric 0.85, 3.27, 17.55, 13.63, "VALOR TOTAL DA NOTA", @xml['ICMSTot/vNF'], :style => :bold
151 | end
152 |
153 | def render_transportadora_e_volumes
154 | @pdf.ititle 0.42, 10.00, 0.25, 14.48, "TRANSPORTADOR / VOLUMES TRANSPORTADOS"
155 |
156 | @pdf.ibox 0.85, 9.02, 0.25, 14.90, "RAZÃO SOCIAL", @xml['transporta/xNome']
157 | @pdf.ibox 0.85, 2.79, 9.27, 14.90, "FRETE POR CONTA", descricao_modalidade_frete(@xml['transp/modFrete'])
158 | @pdf.ibox 0.85, 1.78, 12.06, 14.90, "CODIGO ANTT", @xml['veicTransp/RNTC']
159 | @pdf.ibox 0.85, 2.29, 13.84, 14.90, "PLACA DO VEÍCULO", @xml['veicTransp/placa']
160 | @pdf.ibox 0.85, 0.76, 16.13, 14.90, "UF", @xml['veicTransp/UF']
161 | @pdf.ibox 0.85, 3.94, 16.89, 14.90, "CNPJ/CPF", @xml['transporta/CNPJ']
162 | @pdf.ibox 0.85, 9.02, 0.25, 15.75, "ENDEREÇO", @xml['transporta/xEnder']
163 | @pdf.ibox 0.85, 6.86, 9.27, 15.75, "MUNICÍPIO", @xml['transporta/xMun']
164 | @pdf.ibox 0.85, 0.76, 16.13, 15.75, "UF", @xml['transporta/UF']
165 | @pdf.ibox 0.85, 3.94, 16.89, 15.75, "INSCRIÇÂO ESTADUAL", @xml['transporta/IE']
166 |
167 | @vol = 0
168 |
169 | quantidade = 0
170 | peso_bruto = 0
171 | peso_liquido = 0
172 |
173 | especie = nil
174 | marca = nil
175 |
176 | @xml.collect('xmlns', 'vol') do |det|
177 | @vol += 1
178 | quantidade += det.css('qVol').text.to_f
179 | peso_bruto += det.css('pesoB').text.to_f
180 | peso_liquido += det.css('pesoL').text.to_f
181 |
182 | especie ||= det.css('esp').text
183 | marca ||= det.css('marca').text
184 | end
185 |
186 | if @vol == 0
187 | @pdf.ibox 0.85, 2.80, 0.25, 16.60, "QUANTIDADE"
188 | @pdf.ibox 0.85, 5.00, 3.05, 16.60, "ESPÉCIE"
189 | @pdf.ibox 0.85, 3.05, 8.05, 16.60, "MARCA"
190 | @pdf.ibox 0.85, 3.00, 11.10, 16.60, "NUMERAÇÃO"
191 | @pdf.ibox 0.85, 3.43, 14.10, 16.60, "PESO BRUTO"
192 | @pdf.ibox 0.85, 3.30, 17.53, 16.60, "PESO LÍQUIDO"
193 | else
194 | @pdf.ibox 0.85, 2.80, 0.25, 16.60, "QUANTIDADE", (quantidade.round == quantidade ? quantidade.to_i : quantidade).to_s
195 | @pdf.ibox 0.85, 5.00, 3.05, 16.60, "ESPÉCIE", especie
196 | @pdf.ibox 0.85, 3.05, 8.05, 16.60, "MARCA", marca
197 | @pdf.ibox 0.85, 3.00, 11.10, 16.60, "NUMERAÇÃO"
198 | @pdf.inumeric 0.85, 3.43, 14.10, 16.60, "PESO BRUTO", peso_bruto.to_s, {:decimals => 3}
199 | @pdf.inumeric 0.85, 3.30, 17.53, 16.60, "PESO LÍQUIDO", peso_liquido.to_s, {:decimals => 3}
200 | end
201 | end
202 |
203 | def render_cabecalho_dos_produtos(page_number)
204 | base_y = page_number == 1 ? 17.45 : 8.2
205 | height = page_number == 1 ? 6.70 : 17.2
206 |
207 | @pdf.ititle 0.42, 10.00, 0.25, base_y, "DADOS DO PRODUTO / SERVIÇO"
208 |
209 | @pdf.ibox height, 2.00, 0.25, base_y + 0.42, "CÓDIGO"
210 | @pdf.ibox height, 4.90, 2.25, base_y + 0.42, "DESCRIÇÃO"
211 | @pdf.ibox height, 1.30, 7.15, base_y + 0.42, "NCM"
212 | @pdf.ibox height, 0.80, 8.45, base_y + 0.42, "CST"
213 | @pdf.ibox height, 1.00, 9.25, base_y + 0.42, "CFOP"
214 | @pdf.ibox height, 1.00, 10.25, base_y + 0.42, "UNID"
215 | @pdf.ibox height, 1.30, 11.25, base_y + 0.42, "QUANT"
216 | @pdf.ibox height, 1.50, 12.55, base_y + 0.42, "VALOR UNIT"
217 | @pdf.ibox height, 1.50, 14.05, base_y + 0.42, "VALOR TOT"
218 | @pdf.ibox height, 1.50, 15.55, base_y + 0.42, "BASE CÁLC"
219 | @pdf.ibox height, 1.00, 17.05, base_y + 0.42, "VL ICMS"
220 | @pdf.ibox height, 1.00, 18.05, base_y + 0.42, "VL IPI"
221 | @pdf.ibox height, 0.90, 19.05, base_y + 0.42, "% ICMS"
222 | @pdf.ibox height, 0.86, 19.95, base_y + 0.42, "% IPI"
223 | end
224 |
225 | def render_calculo_do_issqn
226 | @pdf.ititle 0.42, 10.00, 0.25, 24.64, "CÁLCULO DO ISSQN"
227 |
228 | @pdf.ibox 0.85, 5.08, 0.25, 25.06, "INSCRIÇÃO MUNICIPAL", @xml['emit/IM']
229 | @pdf.ibox 0.85, 5.08, 5.33, 25.06, "VALOR TOTAL DOS SERVIÇOS", @xml['total/vServ'].empty? ? @xml['total/ISSQNtot/vServ'] : @xml['total/vServ']
230 | @pdf.ibox 0.85, 5.08, 10.41, 25.06, "BASE DE CÁLCULO DO ISSQN", @xml['total/vBCISS'].empty? ? @xml['total/ISSQNtot/vBC'] : @xml['total/vBCISS']
231 | @pdf.ibox 0.85, 5.28, 15.49, 25.06, "VALOR DO ISSQN", @xml['total/ISSTot'].empty? ? @xml['total/ISSQNtot/vISS'] : @xml['total/ISSTot']
232 | end
233 |
234 | def render_dados_adicionais_box
235 | @pdf.ititle 0.42, 10.00, 0.25, 25.91, "DADOS ADICIONAIS"
236 | @pdf.ibox 3.07, 12.93, 0.25, 26.33, "INFORMAÇÕES COMPLEMENTARES", '', {:size => 8, :valign => :top}
237 |
238 | @pdf.ibox 3.07, 7.62, 13.17, 26.33, "RESERVADO AO FISCO"
239 | end
240 |
241 | def render_dados_adicionais
242 | info_adicional = ""
243 |
244 | if @vol > 1
245 | info_adicional += "TRANSPORTADOR/VOLUMES TRANSPORTADOS\n"
246 |
247 | y = 26.67
248 | info_adicional += @xml.inject 'xmlns', 'vol', "" do |info, det|
249 | y = y + 0.15
250 |
251 | info +
252 | "QUANT.: #{det.css('qVol').text} " +
253 | "ESPÉCIE: #{det.css('esp').text} " +
254 | "MARCA: #{det.css('marca').text} " +
255 | "PESO B.: #{det.css('pesoB').text} " +
256 | "PESO LÍQ.: #{det.css('pesoL').text}\n"
257 | end
258 |
259 | info_adicional += "\nOUTRAS INFORMAÇÕES: "
260 | end
261 |
262 | info_adicional += @xml['infAdic/infCpl']
263 |
264 | if @xml.css('entrega')
265 | info_adicional += " LOCAL DA ENTREGA: " +
266 | @xml['entrega/xLgr'] + " " +
267 | @xml['entrega/nro'] + " " +
268 | "Bairro/Distrito: " + @xml['entrega/xBairro'] + " " +
269 | "Municipio: " + @xml['entrega/xMun'] + " " +
270 | "UF: " + @xml['entrega/UF'] + " " +
271 | "País: Brasil"
272 | end
273 |
274 | if @xml['infAdic/infAdFisco'] != ""
275 | info_adicional += "\n#{@xml['infAdic/infAdFisco']}"
276 | end
277 |
278 | @pdf.bounding_box [(0.33).cm, Helper.invert(26.78.cm)], height: 2.7.cm, width: 12.7.cm do
279 | @pdf.font_size 6
280 | @pdf.text info_adicional, align: :justify
281 | end
282 | end
283 |
284 | def render_produtos
285 | @pdf.font_size(6) do
286 | @produtos_box = @pdf.itable 6.37, 21.50, 0.25, 18.17,
287 | @xml.collect('xmlns', 'det') { |det|
288 | [
289 | det.css('prod/cProd').text, #I02
290 | Descricao.generate(det), #I04
291 | #{}" ",
292 | det.css('prod/NCM').text, #I05
293 | Cst.to_danfe(det), #N11
294 | det.css('prod/CFOP').text, #I08
295 | det.css('prod/uCom').text, #I09
296 | Helper.format_quantity(det.css('prod/qCom').text),
297 | Helper.numerify(det.css('prod/vUnCom').text), #I10a
298 | Helper.numerify(det.css('prod/vProd').text), #I11
299 | Helper.numerify_default_zero(det.css('ICMS/*/vBC').text), #N15
300 | Helper.numerify_default_zero(det.css('ICMS/*/vICMS').text), #N17
301 | Helper.numerify_default_zero(det.css('IPI/*/vIPI').text), #O14
302 | Helper.numerify_default_zero(det.css('ICMS/*/pICMS').text), #N16
303 | Helper.numerify_default_zero(det.css('IPI/*/pIPI').text) #O13
304 | ]
305 | },
306 | :column_widths => {
307 | 0 => 2.00.cm,
308 | 1 => 4.90.cm,
309 | 2 => 1.30.cm,
310 | 3 => 0.80.cm,
311 | 4 => 1.00.cm,
312 | 5 => 1.00.cm,
313 | 6 => 1.30.cm,
314 | 7 => 1.50.cm,
315 | 8 => 1.50.cm,
316 | 9 => 1.50.cm,
317 | 10 => 1.00.cm,
318 | 11 => 1.00.cm,
319 | 12 => 0.90.cm,
320 | 13 => 0.86.cm
321 | },
322 | :cell_style => {:padding => 2, :border_width => 0} do |table|
323 | table.column(6..13).style(:align => :right)
324 | table.column(0..13).border_width = 1
325 | table.column(0..13).borders = [:top]
326 | table.before_rendering_page do |page|
327 | if @pdf.page_number == 1
328 | @pdf.bounds.instance_variable_set(:@y, (22.2).cm)
329 | @pdf.bounds.instance_variable_set(:@height, (16.8).cm)
330 | else
331 | @pdf.bounds.instance_variable_set(:@y, (21).cm)
332 | end
333 | end
334 | end
335 | end
336 | end
337 |
338 | def descricao_modalidade_frete(modalidade)
339 | case modalidade
340 | when '1'
341 | "1 - Destinatário (FOB)"
342 | when '2'
343 | "2- Terceiros"
344 | when '3'
345 | "3- Remetente (Transp. Próprio)"
346 | when '4'
347 | "4- Remetente (Transp.Dest)"
348 | when '9'
349 | "9 - Sem frete"
350 | else
351 | "0 - Remetente (CIF)"
352 | end
353 | end
354 | end
355 | end
356 |
--------------------------------------------------------------------------------
/lib/ruby_danfe/danfe_nfce_generator.rb:
--------------------------------------------------------------------------------
1 | # encoding:utf-8
2 | require 'digest/sha1'
3 |
4 | module RubyDanfe
5 | class DanfeNfceGenerator
6 | def initialize(xml)
7 | @xml = xml
8 | @pdf = Document.new(page_size: [390, 845])
9 | end
10 |
11 | def generatePDF
12 | @pdf.repeat :all do
13 | render_cabecalho
14 | render_info_fixas
15 | render_detalhes_venda
16 | render_totais
17 | render_tributos
18 | render_mensagem_fiscal
19 | render_consumidor
20 | render_qrcode
21 | end
22 |
23 | render_produtos
24 |
25 | @pdf
26 | end
27 |
28 | private
29 | def render_cabecalho
30 |
31 | # ibox(h, w, x, y, title = '', info = '', options = {})
32 |
33 | @pdf.ibox 3, 12, 0.9, 1
34 |
35 | @pdf.ibox 2.85, 3, 1.5, 2, "", "NFC-e", {:size => 12, :align => :center, :border => 0, :style => :bold}
36 |
37 | @pdf.ibox 4.92, 7, 4, 0, '',
38 | @xml['emit/xNome'] + "\n" +
39 | "CNPJ: " + @xml['emit/CNPJ'] + "\n" +
40 | @xml['enderEmit/xLgr'] + ", " + @xml['enderEmit/nro'] + "\n" +
41 | @xml['enderEmit/xBairro']+ " " + "-" + " " + @xml['enderEmit/xMun'] + "/" + @xml['enderEmit/UF'] + "\n" +
42 | "Fone: " + @xml['enderEmit/fone'] + "\n" +
43 | "CEP: " + @xml['enderEmit/CEP'] + " - " + "IE: " + @xml['emit/IE'], {:align => :center, :valign => :center, size: 8, border: 0}
44 | end
45 |
46 | def render_info_fixas
47 | @pdf.ibox 2, 12, 0.9, 4, '',
48 | "DANFE NFC-e - Documento Auxiliar da Nota Fiscal Eletrônica" + "\n" + "para Consumidor Final" + "\n \n" +
49 | "Não permite aproveitamento de crédito de ICMS", {align: :center, :valign => :center, size: 8}
50 | end
51 |
52 | def render_detalhes_venda
53 | render_cabecalho_dos_produtos
54 |
55 | totais = @xml.css('total')
56 |
57 | @pdf.inumeric 0.70, 4, 0.9, 15.8, "Subtotal", totais.css('vProd').text, {:size => 6}
58 | @pdf.inumeric 0.70, 4, 4.9, 15.8, "Desconto", totais.css('vDesc').text, {:size => 6}
59 | @pdf.inumeric 0.70, 4, 8.9, 15.8, "Troco", totais.css('vTroco').text, {:size => 6}
60 | end
61 |
62 | def render_cabecalho_dos_produtos
63 | @pdf.ibox 9.55, 1.3, 0.9, 6.1, "CÓDIGO", "",{:size => 8, :align => :center, :style => :bold}
64 | @pdf.ibox 9.55, 1.3, 2.2, 6.1, "UNIDADE"
65 | @pdf.ibox 9.55, 5.1, 3.5, 6.1, "DESCRIÇÃO"
66 | @pdf.ibox 9.55, 1.3, 8.6, 6.1, "QUANT"
67 | @pdf.ibox 9.55, 1.5, 9.9, 6.1, "VALOR UNIT"
68 | @pdf.ibox 9.55, 1.5, 11.4, 6.1, "VALOR TOTAL"
69 |
70 | @pdf.horizontal_line 26, 365, at: 630
71 | end
72 |
73 | def render_produtos
74 | @pdf.font_size(6) do
75 | @pdf.itable 9.37, 21.50, 0.9, 6.6,
76 | @xml.collect('xmlns', 'det') { |det|
77 | [
78 | det.css('prod/cProd').text, # CÓDIGO
79 | det.css('prod/uCom').text, # UNIDADE
80 | det.css('prod/xProd').text, # DESCRICAO
81 | Helper.numerify(det.css('prod/qCom').text), # QUANTIDADE
82 | Helper.numerify(det.css('prod/vUnCom').text), # VALOR UNIT
83 | Helper.numerify(det.css('prod/vProd').text), # VALOR TOTAL
84 | ]
85 | },
86 | :column_widths => {
87 | 0 => 1.30.cm,
88 | 1 => 1.30.cm,
89 | 2 => 5.10.cm,
90 | 3 => 1.30.cm,
91 | 4 => 1.50.cm,
92 | 5 => 1.50.cm
93 | },
94 | :cell_style => {:padding => 2, :border_width => 0} do |table|
95 | table.column(6..13).style(:align => :right)
96 | table.column(0..13).border_width = 1
97 | table.column(0..13).borders = [:bottom]
98 | end
99 | end
100 | end
101 |
102 | def get_produtos(produto, row = [])
103 | row << produto.css('cProd').text
104 | row << produto.css('uCom').text
105 | row << produto.css('xProd').text
106 | row << produto.css('qCom').text
107 | row << produto.css('vUnCom').text
108 | row << produto.css('vProd').text
109 | return row
110 | end
111 |
112 | def render_totais
113 | qtde_produtos = @xml.css('det').count
114 | forma_pgto = get_forma_pgto
115 | valor_total = Helper.numerify(@xml.css('total').css('vProd').text)
116 | vlr_pago = Helper.numerify(@xml.css('vPag').text)
117 |
118 | @pdf.ibox 2, 12, 0.9, 16.7, '',
119 | "QTD. TOTAL DE ITENS: #{qtde_produtos}" + "\n" + "FORMA DE PAGAMENTO: #{forma_pgto}" + "\n" + "VALOR TOTAL (R$): #{valor_total}" + "\n" + "VALOR PAGO (R$): #{vlr_pago}", {align: :right, valign: :right, size: 6, border: 0, style: :bold}
120 | end
121 |
122 | def get_forma_pgto
123 | cod_forma_pgto = @xml.css('tPag').text
124 | case cod_forma_pgto
125 | when "01" then "Dinheiro"
126 | when "02" then "Cheque"
127 | when "03" then "Cartão de Crédito"
128 | when "04" then "Cartão de Débito"
129 | when "05" then "Crédito Loja"
130 | when "10" then "Vale Alimentação"
131 | when "11" then "Vale Refeição"
132 | when "12" then "Vale Presente"
133 | when "13" then "Vale Combustível"
134 | when "99" then "Outros"
135 | end
136 | end
137 |
138 | def render_tributos
139 | totais = @xml.css('total')
140 | soma_tributos = totais.css('vII').text.to_f + totais.css('vIPI').text.to_f + totais.css('vIPI').text.to_f + totais.css('vPIS').text.to_f
141 | + totais.css('vCOFINS').text.to_f + totais.css('vOutro').text.to_f
142 |
143 | @pdf.ibox 0.9, 12, 0.9, 18, 'Tributos',
144 | "Informação dos Tributos Totais Incidentes (Lei Federal 12.741 /2012): #{soma_tributos}", {align: :center, :valign => :center, size: 7}
145 | end
146 |
147 | def render_mensagem_fiscal
148 | numero_nota = @xml.css('nNF').text
149 | serie = @xml.css('serie').text
150 | data = @xml.css('dhEmi').text
151 | data_emissao = Date.parse(data).strftime('%d/%m/%Y %I:%M:%S')
152 |
153 | chave_acesso = get_chave
154 | cabecalho = ""
155 |
156 | tipo_emissao = @xml.css('tpEmis')
157 | if tipo_emissao != nil && tipo_emissao.text != "1"
158 | cabecalho = "EMITIDA EM CONTINGENCIA" + "\n \n"
159 | end
160 |
161 | @pdf.ibox 3, 12, 0.9, 18.9, 'Mensagem Fiscal',
162 | "#{cabecalho}" +
163 | "Número #{numero_nota} | Série #{serie} | Emissão #{data_emissao} - Via Consumidor" +
164 | "\n \n" + "Consulte pela Chave de Acesso em #{get_url_consulta}" +
165 | "\n \n" + "CHAVE DE ACESSO:" +
166 | "\n \n" + chave_acesso + "\n", {align: :center, :valign => :center, size: 7}
167 | end
168 |
169 | def get_chave
170 | chave = @xml.css('infNFe').attr("Id").value.gsub(/^(NFe|CTe)/, "")
171 | return "%s %s %s %s %s %s %s %s %s %s %s" %[chave[0..3], chave[4..7], chave[8..11], chave[12..15], chave[16..19], chave[20..23], chave[24..27], chave[28..31], chave[32..35], chave[36..39], chave[40..43]]
172 | end
173 |
174 | def render_consumidor
175 | consumidor = @xml.xpath("//dest")
176 | nome = @xml.regex_string(consumidor.to_s.downcase, "//xnome").text.split.map(&:capitalize).join(' ')
177 |
178 | endereco = @xml.regex_string(consumidor.to_s.downcase, "//xlgr").text + " - " + @xml.regex_string(consumidor.to_s.downcase, "//xbairro").text
179 | endereco += " - " + @xml.regex_string(consumidor.to_s.downcase, "//xmun").text + " - " + @xml.regex_string(consumidor.to_s.downcase, "//uf").text.downcase
180 | endereco = endereco.split.map(&:capitalize).join(' ')
181 | endereco = endereco.upcase
182 |
183 | if consumidor.any?
184 | documento = @xml.css('dest idEstrangeiro, dest CPF, dest CNPJ').text
185 | tipo_documento, documento =
186 | case documento.length
187 | when 11 then ["CPF", "%s.%s.%s-%s" % documento.match(/(...)(...)(...)(..)/).captures]
188 | when 14 then ["CNPJ", "%s.%s.%s/%s-%s" % documento.match(/(..)(...)(...)(....)(..)/).captures]
189 | else ["ID Estrangeiro", documento]
190 | end
191 |
192 | consumidor_msg = nome
193 | consumidor_msg += " - #{tipo_documento}: #{documento}"
194 | consumidor_msg += "\n" + endereco
195 | else
196 | consumidor_msg = "CONSUMIDOR NÃO IDENTIFICADO"
197 | end
198 |
199 | @pdf.ibox 1.3, 12, 0.9, 21.9, 'Consumidor',
200 | consumidor_msg, {align: :center, :valign => :top, size: 7}
201 | end
202 |
203 | def render_qrcode
204 | @pdf.iqrcode 5.18, 28, get_qrcode_url, 20
205 |
206 | data = @xml.css('dhRecbto').text
207 | data_receb = Date.parse(data).strftime('%d/%m/%Y %I:%M:%S')
208 |
209 | protocolo = @xml.css('nProt').text
210 | msg_protocolo = "Protocolo de Autorização: #{protocolo} - Data: #{data_receb}"
211 |
212 | @pdf.ibox 0.7, 12, 0.9, 23.3, '', msg_protocolo, size: 6, align: :center, valign: :center
213 | end
214 |
215 | def get_qrcode_url
216 | ender_consulta = get_ender_consulta
217 | end
218 |
219 | def get_ender_consulta
220 | url = get_url_qr_code
221 |
222 | params = {
223 | "chNFe" => get_chave.gsub(/ /, ""),
224 | "nVersao" => @xml.css('nfeProc').attr("versao"),
225 | "tpAmb" => @xml['ide/tpAmb'],
226 | "dhEmi" => str_to_hex(@xml['ide/dhEmi']),
227 | "vNF" => @xml['ICMSTot/vNF'],
228 | "vICMS" => @xml['ICMSTot/vICMS'],
229 | "digVal" => str_to_hex(@xml['nfe/DigestValue']),
230 | "cIdToken" => '000001',
231 | }
232 |
233 | unless @xml.css('dest').empty?
234 | params["cDest"] = @xml.css('dest idEstrangeiro, dest CPF, dest CNPJ').text
235 | end
236 |
237 | params_string = params.to_a.map{|p| p.join("=")}.join("&")
238 |
239 | hash_token = Digest::SHA1.base64digest params_string
240 |
241 | url + params_string + "&cHashQRCode=" + hash_token
242 | end
243 |
244 | def get_url_qr_code
245 | case @xml.css('emit').css('UF').text.upcase
246 | when "AC" then "http://www.sefaznet.ac.gov.br/nfe/NFe.jsp?opc=3"
247 | when "AM" then "http://sistemas.sefaz.am.gov.br/nfceweb/consultarNFCe.jsp?"
248 | when "MA" then "http://www.nfce.sefaz.ma.gov.br/portal/consultarNFCe.jsp?"
249 | when "MT" then "http://www.sefaz.mt.gov.br/nfe/portal/consultanfce?"
250 | when "RN" then "http://www.nfe.rn.gov.br/portal/consultarNFCe.jsp?"
251 | when "RO" then "http://www.nfce.sefin.ro.gov.br/consultanfce/consulta.jsp?"
252 | when "RS" then "https://www.sefaz.rs.gov.br/NFCE/NFCE-COM.aspx?"
253 | when "SE" then "http://www.nfe.se.gov.br/portal/consultarNFCe.jsp?"
254 | end
255 | end
256 |
257 | def get_url_consulta
258 | case @xml.css('emit').css('UF').text.upcase
259 | when "AC" then "http://www.sefaznet.ac.gov.br/nfe/NFe.jsp?opc=3"
260 | when "AM" then "http://sistemas.sefaz.am.gov.br/nfceweb/consultarNFCe.jsp"
261 | when "MA" then "http://www.nfce.sefaz.ma.gov.br/portal/consultarNFCe.jsp"
262 | when "MT" then "http://www.sefaz.mt.gov.br/nfe/portal/consultanfce"
263 | when "RN" then "http://www.nfe.rn.gov.br/portal/consultarNFCe.jsp"
264 | when "RO" then "http://www.nfce.sefin.ro.gov.br"
265 | when "RS" then "https://www.sefaz.rs.gov.br/NFCE/NFCE-COM.aspx"
266 | when "SE" then "http://www.nfe.se.gov.br/portal/consultarNFCe.jsp"
267 | end
268 | end
269 |
270 | def str_to_hex str
271 | str.split("").reduce("") do |str, char|
272 | str + char.ord.to_s(16)
273 | end
274 | end
275 | end
276 | end
277 |
--------------------------------------------------------------------------------
/lib/ruby_danfe/danfse_generator.rb:
--------------------------------------------------------------------------------
1 | # coding: utf-8
2 | module RubyDanfe
3 | class DanfseGenerator
4 | def initialize(xml)
5 | @xml = xml
6 | @pdf = Document.new
7 | @vol = 0
8 | end
9 |
10 | attr_reader :municipios
11 |
12 | def municipios
13 | lib_path = File.expand_path("../../", __FILE__)
14 | @municipios ||= JSON.parse(File.read(File.join(lib_path, 'municipios.json')))
15 | end
16 |
17 | def generatePDF
18 | render_titulo
19 | render_prestador
20 | render_tomador
21 | render_intermediario
22 | render_discriminacao
23 | render_valor_total
24 | render_outras
25 | @pdf
26 | end
27 |
28 | private
29 | def render_titulo
30 | @pdf.ibox 2.55, 16.10, 0.25, 0.42, '',
31 | "PREFEITURA DO MUNICÍPIO DE #{municipios[@xml['InfNfse/PrestadorServico/Endereco/CodigoMunicipio']].upcase} \n" +
32 | "Secretaria Municipal da Fazenda \n" +
33 | "NOTA FISCAL ELETRÔNICA DE SERVIÇOS - NFS-e \n" +
34 | "RPS n° #{@xml['IdentificacaoRps/Numero']}, emitido em #{@xml['DataEmissaoRps']}", {:align => :center, :valign => :center}
35 |
36 | @pdf.ibox 0.85, 4.47, 16.35, 0.42, "NÚMERO DA NOTA", "#{@xml['InfNfse/Numero'].rjust(8,'0')}"
37 | @pdf.ibox 0.85, 4.47, 16.35, 1.27, "DATA E HORA DE EMISSÃO", "#{@xml['InfNfse/DataEmissao'].gsub('T', ' ')}"
38 | @pdf.ibox 0.85, 4.47, 16.35, 2.12, "CÓDIGO DE VERIFICAÇÃO", "#{@xml['CodigoVerificacao']}"
39 | end
40 |
41 | def render_prestador
42 | @pdf.ibox 4.25, 20.57, 0.25, 2.97
43 | @pdf.ibox 0.85, 20.57, 0.25, 2.97, '', 'PRESTADOR DE SERVIÇOS', {border: 0, style: :bold,:align => :center, :valign => :center}
44 | @pdf.ibox 0.85, 20.57, 0.25, 3.82, "Nome/Razão Social", "#{@xml['PrestadorServico/RazaoSocial']}", {border: 0}
45 | @pdf.ibox 0.85, 12, 0.25, 4.67, "CPF/CNPJ", "#{@xml['PrestadorServico/IdentificacaoPrestador/Cnpj'] || @xml['PrestadorServico/IdentificacaoPrestador/Cpf']}", {border: 0}
46 | @pdf.ibox 0.85, 4.47, 12, 4.67, "Inscrição Municipal", "#{@xml['IdentificacaoPrestador/InscricaoMunicipal']}", {border: 0}
47 | @pdf.ibox 0.85, 20.57, 0.25, 5.52, "Endereço", "#{@xml['PrestadorServico/Endereco/Endereco']}", {border: 0}
48 | @pdf.ibox 0.85, 10, 0.25, 6.37, "Município", "#{municipios[@xml['PrestadorServico/Endereco/CodigoMunicipio']]}", {border: 0}
49 | @pdf.ibox 0.85, 4.47, 10, 6.37, "UF", "#{@xml['PrestadorServico/Endereco/Uf']}", {border: 0}
50 | @pdf.ibox 0.85, 4.47, 15, 6.37, "E-mail", "#{@xml['PrestadorServico/Contato/Email']}", {border: 0}
51 | end
52 |
53 | def render_tomador
54 | @pdf.ibox 4.25, 20.57, 0.25, 7.22
55 | @pdf.ibox 0.85, 20.57, 0.25, 7.22, '', 'TOMADOR DE SERVIÇOS', {border: 0, style: :bold,:align => :center, :valign => :center}
56 | @pdf.ibox 0.85, 20.57, 0.25, 8.07, "Nome/Razão Social", "#{@xml['TomadorServico/RazaoSocial']}", {border: 0}
57 | @pdf.ibox 0.85, 12, 0.25, 8.92, "CPF/CNPJ", "#{@xml['TomadorServico/IdentificacaoTomador/CpfCnpj/Cnpj'] || @xml['TomadorServico/IdentificacaoTomador/CpfCnpj/Cpf']}", {border: 0}
58 | @pdf.ibox 0.85, 4.47, 12, 8.92, "Inscrição Municipal", "#{@xml['IdentificacaoTomador/InscricaoMunicipal']}", {border: 0}
59 | @pdf.ibox 0.85, 20.57, 0.25, 9.77, "Endereço", "#{@xml['TomadorServico/Endereco/Endereco']}", {border: 0}
60 | @pdf.ibox 0.85, 10, 0.25, 10.62, "Município", "#{municipios[@xml['TomadorServico/Endereco/CodigoMunicipio']]}", {border: 0}
61 | @pdf.ibox 0.85, 4.47, 10, 10.62, "UF", "#{@xml['TomadorServico/Endereco/Uf']}", {border: 0}
62 | @pdf.ibox 0.85, 4.47, 15, 10.62, "E-mail", "#{@xml['TomadorServico/Contato/Email']}", {border: 0}
63 | end
64 |
65 | def render_intermediario
66 | @pdf.ibox 1.70, 20.57, 0.25, 11.47
67 | @pdf.ibox 0.85, 20.57, 0.25, 11.47, '', 'INTERMEDIÁRIO DE SERVIÇOS', {border: 0, style: :bold,:align => :center, :valign => :center}
68 | @pdf.ibox 0.85, 12, 0.25, 12.32, "Nome/Razão Social", "#{@xml['IdentificacaoIntermediarioServico/RazaoSocial']}", {border: 0}
69 | @pdf.ibox 0.85, 8, 12.25, 12.32, "CPF/CNPJ", "#{@xml['IdentificacaoIntermediarioServico/CpfCnpj/Cnpj'] || @xml['IdentificacaoIntermediarioServico/CpfCnpj/Cpf']}", {border: 0}
70 | end
71 |
72 | def render_discriminacao
73 | @pdf.ibox 9.35, 20.57, 0.25, 13.17
74 | @pdf.ibox 0.85, 20.57, 0.25, 13.17, '', 'DISCRIMINAÇÃO DOS SERVIÇOS', {border: 0, style: :bold,:align => :center, :valign => :center}
75 | @pdf.ibox 8, 19.57, 0.75, 14.02, "", "#{@xml['Servico/Discriminacao']}", {border: 0}
76 | end
77 |
78 | def render_valor_total
79 | @pdf.ibox 1.70, 20.57, 0.25, 22.52
80 | @pdf.ibox 0.85, 20.57, 0.25, 22.52, '', "VALOR TOTAL DO SERVIÇO = R$#{Helper.numerify(@xml['Servico/Valores/ValorServicos'])}", {border: 0, style: :bold,:align => :center, :valign => :center}
81 | @pdf.inumeric 0.85, 4.06, 0.25, 23.37, "INSS", @xml['Servico/Valores/ValorInss']
82 | @pdf.inumeric 0.85, 4.06, 4.31, 23.37, "IRRF", @xml['Servico/Valores/ValorIr']
83 | @pdf.inumeric 0.85, 4.06, 8.37, 23.37, "CSLL", @xml['Servico/Valores/ValorCsll']
84 | @pdf.inumeric 0.85, 4.06, 12.43, 23.37, "COFINS", @xml['Servico/Valores/ValorCofins']
85 | @pdf.inumeric 0.85, 4.32, 16.49, 23.37, "PIS/PASEP", @xml['Servico/Valores/ValorPis']
86 | @pdf.ibox 0.85, 20.57, 0.25, 24.22, "Código do Serviço", @xml['Servico/CodigoTributacaoMunicipio']
87 | @pdf.inumeric 0.85, 3.46, 0.25, 25.07, "Valor Total das Deduções", @xml['Servico/Valores/ValorDeducoes']
88 | @pdf.inumeric 0.85, 3.46, 3.71, 25.07 , "Base de Cálculo", @xml['Servico/Valores/BaseCalculo']
89 | @pdf.ibox 0.85, 3.46, 7.17, 25.07, "Alíquota", @xml['Servico/Valores/Aliquota']
90 | @pdf.inumeric 0.85, 3.46, 10.63, 25.07, "Valor do ISS", @xml['Servico/Valores/ValorIss']
91 | @pdf.inumeric 0.85, 6.73, 14.09, 25.07, "Crédito", @xml['InfNfse/ValorCredito']
92 | @pdf.ibox 0.85, 10.38, 0.25, 25.92, "Muncípio da Prestação do Serviço", municipios[@xml['OrgaoGerador/CodigoMunicipio']], :style => :bold
93 | @pdf.ibox 0.85, 10.19, 10.63, 25.92, "Número Inscrição da Obra", @xml['DadosConstrucaoCivil/CodigoObra'], :style => :bold
94 | end
95 |
96 | def render_outras
97 | @pdf.ibox 2.55, 20.57, 0.25, 26.77
98 | @pdf.ibox 0.85, 20.57, 0.25, 26.77, '', 'OUTRAS INFORMAÇÕES', {border: 0, style: :bold,:align => :center, :valign => :center}
99 | @pdf.ibox 1.70, 19.57, 0.75, 27.62, "", "#{@xml['InfNfse/OutrasInformacoes']}", {border: 0}
100 | end
101 | end
102 | end
103 |
--------------------------------------------------------------------------------
/lib/ruby_danfe/descricao.rb:
--------------------------------------------------------------------------------
1 | #encoding: utf-8
2 |
3 | module RubyDanfe
4 | class Descricao
5 | LINEBREAK = "\n"
6 |
7 | def self.generate(det)
8 | descricao = "#{det.css('prod/xProd').text}"
9 |
10 | if need_infAdProd(det)
11 | descricao += LINEBREAK
12 | descricao += det.css('infAdProd').text
13 | end
14 |
15 | if need_fci(det)
16 | descricao += LINEBREAK
17 | descricao += "FCI: #{det.css('prod/nFCI').text}"
18 | end
19 |
20 | if need_veicProd(det)
21 | veicProd = det.css('veicProd')
22 |
23 | descricao += LINEBREAK
24 | descricao += "Chassi: #{veicProd.css('chassi').text} "
25 | descricao += "Motor: #{veicProd.css('nMotor').text} "
26 | descricao += "AnoFab: #{veicProd.css('anoFab').text} "
27 | descricao += "AnoMod: #{veicProd.css('anoMod').text} "
28 | descricao += "Cor: #{veicProd.css('xCor').text}"
29 | end
30 |
31 | if need_st(det)
32 | descricao += LINEBREAK
33 | descricao += "ST: MVA: #{det.css('ICMS/*/pMVAST').text}% "
34 | descricao += "* Alíq: #{det.css('ICMS/*/pICMSST').text}% "
35 | descricao += "* BC: #{det.css('ICMS/*/vBCST').text} "
36 | descricao += "* Vlr: #{det.css('ICMS/*/vICMSST').text}"
37 | end
38 |
39 | descricao
40 | end
41 |
42 | private
43 | def self.need_infAdProd(det)
44 | !det.css('infAdProd').text.empty?
45 | end
46 |
47 | def self.need_fci(det)
48 | !det.css('prod/nFCI').text.empty?
49 | end
50 |
51 | def self.need_veicProd(det)
52 | !det.css('prod/veicProd').text.empty?
53 | end
54 |
55 | def self.need_st(det)
56 | det.css('ICMS/*/vBCST').text.to_i > 0
57 | end
58 |
59 | end
60 | end
61 |
--------------------------------------------------------------------------------
/lib/ruby_danfe/document.rb:
--------------------------------------------------------------------------------
1 | module RubyDanfe
2 | class Document
3 | def initialize(opts = {})
4 | default_opts = {
5 | :page_size => 'A4',
6 | :page_layout => :portrait,
7 | :left_margin => 0,
8 | :right_margin => 0,
9 | :top_margin => 0,
10 | :botton_margin => 0
11 | }
12 |
13 | @document = Prawn::Document.new(default_opts.merge(opts))
14 |
15 | @document.font "Times-Roman"
16 | end
17 |
18 | def method_missing(method_name, *args, &block)
19 | @document.send(method_name, *args, &block)
20 | end
21 |
22 | def respond_to_missing?(method_name, include_private = false)
23 | @document.respond_to?(method_name, include_private) || super
24 | end
25 |
26 | def ititle(h, w, x, y, title)
27 | self.text_box title, :size => 10, :at => [x.cm, Helper.invert(y.cm) - 2], :width => w.cm, :height => h.cm, :style => :bold
28 | end
29 |
30 | def ibarcode(h, w, x, y, info)
31 | info = info.gsub(/\D/, '')
32 | Barby::Code128C.new(info).annotate_pdf(self, :x => x.cm, :y => Helper.invert(y.cm), :width => w.cm, :height => h.cm) if info != ''
33 | end
34 |
35 | def iqrcode(x, y, info, size = nil)
36 | Barby::QrCode.new(info, :level => :q, :size => size).annotate_pdf(self, :x => x.cm, :y => Helper.invert(y.cm)) if info != ''
37 | end
38 |
39 | def irectangle(h, w, x, y)
40 | self.stroke_rectangle [x.cm, Helper.invert(y.cm)], w.cm, h.cm
41 | end
42 |
43 | def ibox(h, w, x, y, title = '', info = '', options = {})
44 | box [x.cm, Helper.invert(y.cm)], w.cm, h.cm, title, info, options
45 | end
46 |
47 | def idate(h, w, x, y, title = '', info = '', options = {})
48 | tt = info.gsub(/T.*/, '').split('-')
49 | ibox h, w, x, y, title, "#{tt[2]}/#{tt[1]}/#{tt[0]}", options
50 | end
51 |
52 | def box(at, w, h, title = '', info = '', options = {})
53 | options = {
54 | :align => :left,
55 | :size => 10,
56 | :style => nil,
57 | :valign => :top,
58 | :border => 1
59 | }.merge(options)
60 | self.stroke_rectangle at, w, h if options[:border] == 1
61 | self.text_box title, :size => 6, :style => :italic, :at => [at[0] + 2, at[1] - 2], :width => w - 4, :height => 8 if title != ''
62 | self.text_box info, :size => options[:size], :at => [at[0] + 2, at[1] - (title != '' ? 14 : 4) ], :width => w - 4, :height => h - (title != '' ? 14 : 4), :align => options[:align], :style => options[:style], :valign => options[:valign]
63 | end
64 |
65 | def inumeric(h, w, x, y, title = '', info = '', options = {})
66 | numeric [x.cm, Helper.invert(y.cm)], w.cm, h.cm, title, info, options
67 | end
68 |
69 | def numeric(at, w, h, title = '', info = '', options = {})
70 | options = {:decimals => 2}.merge(options)
71 | info = Helper.numerify(info, options[:decimals]) if info != ''
72 | box at, w, h, title, info, options.merge({:align => :right})
73 | end
74 |
75 | def itable(h, w, x, y, data, options = {}, &block)
76 | self.bounding_box [x.cm, Helper.invert(y.cm)], :width => w.cm, :height => h.cm do
77 | self.table data, options do |table|
78 | yield(table)
79 | end
80 | end
81 | end
82 | end
83 | end
84 |
--------------------------------------------------------------------------------
/lib/ruby_danfe/helper.rb:
--------------------------------------------------------------------------------
1 | module RubyDanfe
2 | class Helper
3 | def self.numerify(number, decimals = 2)
4 | number = number.tr("\n","").delete(" ")
5 | return "" if !number || number == ""
6 | int, frac = ("%.#{decimals}f" % number).split(".")
7 | int.gsub!(/(\d)(?=(\d\d\d)+(?!\d))/, "\\1\.")
8 | int + "," + frac
9 | rescue
10 | number
11 | end
12 |
13 | def self.numerify_default_zero(number, decimals = 2)
14 | number = number.tr("\n","").delete(" ")
15 | return "0,00" if !number || number == ""
16 | int, frac = ("%.#{decimals}f" % number).split(".")
17 | int.gsub!(/(\d)(?=(\d\d\d)+(?!\d))/, "\\1\.")
18 | int + "," + frac
19 | rescue
20 | number
21 | end
22 |
23 | def self.invert(y)
24 | 28.7.cm - y
25 | end
26 |
27 | def self.format_quantity(qty)
28 | return Helper.numerify(qty, RubyDanfe.options.quantity_decimals) if RubyDanfe.options.numerify_prod_qcom
29 | qty.gsub!(",", ".")
30 | qty[qty.rindex('.')] = ',' if qty.rindex('.')
31 | qty
32 | end
33 |
34 | def self.format_datetime(string)
35 | formated_datetime = ""
36 |
37 | if not string.empty?
38 | date = extract_date_time(string)
39 | formated_datetime = date.strftime("%d/%m/%Y %H:%M:%S")
40 | end
41 |
42 | formated_datetime
43 | end
44 |
45 | def self.format_date(string)
46 | formated_date = ""
47 |
48 | if not string.empty?
49 | date = Date.strptime(string, "%Y-%m-%d")
50 | formated_date = date.strftime("%d/%m/%Y")
51 | end
52 |
53 | formated_date
54 | end
55 |
56 | def self.format_time(string)
57 | formated_time = ""
58 |
59 | if not string.empty?
60 | time = Time.strptime(string, "%H:%M:%S")
61 | formated_time = time.strftime("%H:%M:%S")
62 | end
63 |
64 | formated_time
65 | end
66 |
67 | def self.extract_time_from_date(string)
68 | formated_time = ""
69 |
70 | if not string.empty?
71 | date = extract_date_time(string)
72 | formated_time = date.strftime("%H:%M:%S")
73 | end
74 |
75 | formated_time
76 | end
77 |
78 | def self.format_cnpj(string)
79 | formated_cnpj = ""
80 |
81 | if not (string.empty? || string.size != 14)
82 | formated_cnpj = string[0,2] + '.' + string[2,3] + '.' + string[5,3] +
83 | '/' + string[8,4] + '-' + string[12,2]
84 | end
85 |
86 | formated_cnpj
87 | end
88 |
89 | private
90 |
91 | def self.extract_date_time(string)
92 | begin
93 | DateTime.strptime(string, "%Y-%m-%dT%H:%M:%S")
94 | rescue ArgumentError
95 | DateTime.strptime(string, "%d/%m/%Y %H:%M:%S")
96 | end
97 | end
98 | end
99 | end
100 |
--------------------------------------------------------------------------------
/lib/ruby_danfe/options.rb:
--------------------------------------------------------------------------------
1 | module RubyDanfe
2 | class Options < OpenStruct
3 |
4 | DEFAULTOPTIONS = {
5 | quantity_decimals: 2,
6 | numerify_prod_qcom: false
7 | }
8 |
9 | def initialize(new_options={})
10 | options = DEFAULTOPTIONS.merge(config_yaml_load)
11 | super options.merge(new_options)
12 | end
13 |
14 | private
15 | def file
16 | File.exist?("config/ruby_danfe.yml") ? File.open("config/ruby_danfe.yml").read : ""
17 | end
18 |
19 | def config_yaml_load
20 | @file_read = YAML.load(file)
21 | @file_read ? (@file_read["ruby_danfe"]||{})["options"] : {}
22 | end
23 | end
24 | end
25 |
--------------------------------------------------------------------------------
/lib/ruby_danfe/railtie.rb:
--------------------------------------------------------------------------------
1 | require "prawn"
2 | require "prawn/table"
3 | require "prawn/measurement_extensions"
4 | require "barby"
5 | require "barby/barcode/code_128"
6 | require 'barby/barcode/qr_code'
7 | require "barby/outputter/prawn_outputter"
8 | require "nokogiri"
9 | require 'ostruct'
10 | require 'yaml'
11 | require 'date'
12 | require 'time'
13 | require 'json'
14 |
15 | require_relative '../ruby_danfe.rb'
16 | require_relative 'options.rb'
17 | require_relative 'helper.rb'
18 | require_relative 'cst.rb'
19 | require_relative 'document.rb'
20 | require_relative 'version.rb'
21 | require_relative 'dacte_generator.rb'
22 | require_relative 'dacteos_generator.rb'
23 | require_relative 'danfe_generator.rb'
24 | require_relative 'danfse_generator.rb'
25 | require_relative 'danfe_nfce_generator.rb'
26 | require_relative 'xml.rb'
27 | require_relative 'descricao.rb'
28 | require_relative 'ruby_danfe.rb'
29 |
--------------------------------------------------------------------------------
/lib/ruby_danfe/ruby_danfe.rb:
--------------------------------------------------------------------------------
1 | # encoding:utf-8
2 | module RubyDanfe
3 | def self.generate(pdf_filename, xml_filename, type = :danfe, new_options = {})
4 | self.options = new_options if !new_options.empty?
5 |
6 | xml_string = File.new(xml_filename)
7 | render_file(pdf_filename, xml_string, type)
8 | end
9 |
10 | def self.render(xml_string, type = :danfe, new_options = {})
11 | self.options = new_options if !new_options.empty?
12 |
13 | pdf = generatePDF(xml_string, type)
14 | pdf.render
15 | end
16 |
17 | def self.render_file(pdf_filename, xml_string, type = :danfe, new_options = {})
18 | self.options = new_options if !new_options.empty?
19 |
20 | pdf = generatePDF(xml_string, type)
21 | pdf.render_file pdf_filename
22 | end
23 |
24 | def self.options
25 | @options ||= RubyDanfe::Options.new
26 | end
27 |
28 | def self.options=(new_options = {})
29 | @options = RubyDanfe::Options.new(new_options)
30 | end
31 |
32 | private
33 | def self.generatePDF(xml_string, type = :danfe, new_options = {})
34 | self.options = new_options if !new_options.empty?
35 |
36 | xml = XML.new(xml_string)
37 |
38 | generator =
39 | case type
40 | when :danfe then DanfeGenerator.new(xml)
41 | when :danfe_nfce then DanfeNfceGenerator.new(xml)
42 | when :dacte then DacteGenerator.new(xml)
43 | when :danfse then DanfseGenerator.new(xml)
44 | when :dacteos then DacteosGenerator.new(xml)
45 | else raise "unknown type #{type}"
46 | end
47 | generator.generatePDF
48 | end
49 | end
50 |
--------------------------------------------------------------------------------
/lib/ruby_danfe/version.rb:
--------------------------------------------------------------------------------
1 | module RubyDanfe
2 | VERSION = "1.15.4"
3 | end
4 |
--------------------------------------------------------------------------------
/lib/ruby_danfe/xml.rb:
--------------------------------------------------------------------------------
1 | module RubyDanfe
2 | class XML
3 | def css(xpath)
4 | @xml.css(xpath)
5 | end
6 |
7 | def xpath(regex)
8 | doc = Nokogiri::HTML(@xml.to_s)
9 | return doc.xpath(regex)
10 | end
11 |
12 | def regex_string(search_string, regex)
13 | doc = Nokogiri::HTML(search_string)
14 | return doc.xpath(regex)
15 | end
16 |
17 | def initialize(xml)
18 | @xml = Nokogiri::XML(xml)
19 | end
20 |
21 | def [](xpath)
22 | node = @xml.css(xpath)
23 | return node ? node.text : ""
24 | end
25 |
26 | def render
27 | if @xml.at_css('infNFe/ide')
28 | RubyDanfe.render @xml.to_s, :danfe
29 | elsif @xml.at_css('InfNfse/Numero')
30 | RubyDanfe.render @xml.to_s, :danfse
31 | else
32 | if @xml.at_css('CTeOS')
33 | RubyDanfe.render @xml.to_s, :dacteos
34 | else
35 | RubyDanfe.render @xml.to_s, :dacte
36 | end
37 | end
38 | end
39 |
40 | def collect(ns, tag, &block)
41 | result = []
42 | # Tenta primeiro com uso de namespace
43 | begin
44 | @xml.xpath("//#{ns}:#{tag}").each do |det|
45 | result << yield(det)
46 | end
47 | rescue
48 | # Caso dê erro, tenta sem
49 | @xml.xpath("//#{tag}").each do |det|
50 | result << yield(det)
51 | end
52 | end
53 | result
54 | end
55 |
56 | def inject(ns, tag, acc, &block)
57 | # Tenta primeiro com uso de namespace
58 | begin
59 | @xml.xpath("//#{ns}:#{tag}").each do |det|
60 | acc = yield(acc, det)
61 | end
62 | rescue
63 | # Caso dê erro, tenta sem
64 | @xml.xpath("//#{tag}").each do |det|
65 | acc = yield(acc, det)
66 | end
67 | end
68 | acc
69 | end
70 |
71 | def attrib(node, attrib)
72 | begin
73 | return @xml.css(node).attr(attrib).text
74 | rescue
75 | ""
76 | end
77 | end
78 | end
79 | end
80 |
--------------------------------------------------------------------------------
/ruby_danfe.gemspec:
--------------------------------------------------------------------------------
1 | # coding: utf-8
2 | $:.push File.expand_path("../lib", __FILE__)
3 | require "ruby_danfe/version"
4 |
5 | Gem::Specification.new do |spec|
6 | spec.name = "ruby_danfe"
7 | spec.version = RubyDanfe::VERSION
8 | spec.summary = "DANFE and DACTE pdf generator for Brazilian invoices and transportation docs."
9 | spec.author = "Eduardo Reboucas"
10 | spec.email = "eduardo.reboucas@gmail.com"
11 | spec.homepage = "http://github.com/mcfox/ruby_danfe"
12 | spec.license = "MIT"
13 |
14 | spec.files = `git ls-files`.split("\n")
15 | spec.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
16 | spec.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
17 | spec.require_paths = ["lib"]
18 |
19 |
20 | spec.add_dependency "nokogiri", "> 1.8.5"
21 | spec.add_dependency "prawn", "~> 1.2"
22 | spec.add_dependency "prawn-table", "> 0.2"
23 | spec.add_dependency "barby", "> 0.5"
24 | spec.add_dependency "rqrcode", "> 0.10"
25 | spec.add_dependency "rake"
26 |
27 | spec.add_development_dependency "pry"
28 | spec.add_development_dependency "rspec", "> 3.0"
29 | spec.add_development_dependency "simplecov"
30 | end
31 |
--------------------------------------------------------------------------------
/spec/features/ruby_danfe_spec.rb:
--------------------------------------------------------------------------------
1 | require "spec_helper"
2 |
3 | describe "RubyDanfe generated pdf files" do
4 | let(:base_dir) { "./spec/fixtures/"}
5 | let(:output_pdf) { "#{base_dir}output.pdf" }
6 |
7 | before {
8 | File.delete(output_pdf) if File.exist?(output_pdf)
9 | RubyDanfe.options = {"quantity_decimals" => 2}
10 | }
11 |
12 | it "renders a basic NF-e with namespace" do
13 | expect(File.exist?(output_pdf)).to be_falsey
14 |
15 | RubyDanfe.generate(output_pdf, "#{base_dir}nfe_with_ns.xml")
16 |
17 | expect("#{base_dir}nfe_with_ns.xml.fixture.pdf").to be_same_file_as(output_pdf)
18 | end
19 |
20 | it "renders another basic NF-e without namespace" do
21 | expect(File.exist?(output_pdf)).to be_falsey
22 |
23 | RubyDanfe.generate(output_pdf, "#{base_dir}nfe_without_ns.xml")
24 |
25 | expect("#{base_dir}nfe_without_ns.xml.fixture.pdf").to be_same_file_as(output_pdf)
26 | end
27 |
28 | it "renders a NF-e having FCI in its items" do
29 | expect(File.exist?(output_pdf)).to be_falsey
30 |
31 | RubyDanfe.generate(output_pdf, "#{base_dir}nfe_with_fci.xml")
32 |
33 | expect("#{base_dir}nfe_with_fci.xml.fixture.pdf").to be_same_file_as(output_pdf)
34 | end
35 |
36 | it "renders a NF-e of Simples Nacional using CSOSN" do
37 | expect(File.exist?(output_pdf)).to be_falsey
38 |
39 | RubyDanfe.generate(output_pdf, "#{base_dir}nfe_simples_nacional.xml")
40 |
41 | expect("#{base_dir}nfe_simples_nacional.xml.fixture.pdf").to be_same_file_as(output_pdf)
42 | end
43 |
44 | it "renders a basic CT-e" do
45 | expect(File.exist?(output_pdf)).to be_falsey
46 |
47 | RubyDanfe.generate(output_pdf, "#{base_dir}cte.xml", :dacte)
48 |
49 | expect("#{base_dir}cte.xml.fixture.pdf").to be_same_file_as(output_pdf)
50 | end
51 |
52 | it "renders a basic NFS-e" do
53 | RubyDanfe.generate(output_pdf, "#{base_dir}nfse.xml", :danfse)
54 |
55 | expect("#{base_dir}nfse.xml.fixture.pdf").to be_same_file_as(output_pdf)
56 | end
57 |
58 | it "renders quantity field with 4 decimals" do
59 | expect(File.exist?(output_pdf)).to be_falsey
60 |
61 | RubyDanfe.generate(output_pdf, "#{base_dir}4_decimals_nfe_simples_nacional.xml", :danfe, {"quantity_decimals" => 4})
62 |
63 | expect("#{base_dir}4_decimals_nfe_simples_nacional.xml.fixture.pdf").to be_same_file_as(output_pdf)
64 | end
65 | end
66 |
--------------------------------------------------------------------------------
/spec/fixtures/4_decimals_nfe_simples_nacional.xml:
--------------------------------------------------------------------------------
1 | 35000000016101-Venda de producao do estabelecimento155112013-12-2813550308116110160891033000109KRON INSTRUMENTOS ELETRICOS LTDAKRON INSTRUMENTOS ELETRICOS LTDARUA ALEXANDRE DE GUSMAO278SOCORRO3550308SAO PAULOSP047600201058BRASIL1155252000111393871117182743287000880Schneider Electric Brasil LtdaAv da Saudade1125Frutal3552403SUMARESP131713201058BRASIL19210463006710083751101Tijolo Macico Tipo A69041000006101MI2.000010.000000000020.00MI2.000010.000000000015.350102990.000.000.00990.000.000.002Tijolo Macico Tipo B69041000006101MI3.000020.000000000060.00MI3.000020.0000000000116.050102990.000.000.00990.000.000.003Tijolo Macico Tipo C69041000006101MI4.000030.0000000000120.00MI4.000030.0000000000132.100102990.000.000.00990.000.000.000.000.000.000.00200.000.000.000.000.000.000.000.000.00200.0053.500112014-01-2740.0022014-02-2640.0032014-03-2840.0042014-04-2740.0052014-05-2740.00DOCUMENTO EMITIDO POR ME OU EPP OPTANTE PELO SIMPLES NACIONAL * NAO GERA DIREITO A CREDITO FISCAL DE IPI * Tributos: R$ 53,50 (26,75%)
2 |
--------------------------------------------------------------------------------
/spec/fixtures/cte.xml:
--------------------------------------------------------------------------------
1 | 420060002256352PRESTACAO SERVICO TRANSP A ESTAB INDUSTRIAL15702252011-07-26T17:34:0011010010.054202404BLUMENAUSC0114213203POMERODESC4313904PANAMBIRS13REMESSA 011862043889317697001880251944646TRANSPORTES WALDEMAR LTDAR HEINRICH HEMMER3047BADENFURT4202404BLUMENAU89070000SCBRASIL62800446001634253821827NALCO BRASIL LTDARUA ALBERTO SPREDEMANN329FUNDOSCENTRO4213203POMERODE89107000SCBRASIL42110762800446001634550010000044551217916180896731640001930900018909BRUNING TECNOMETAL S ARUA VINTE E CINCO DE JULHO2305JACIANDI4313904PANAMBI98280000RSBRASIL146.39146.39FretePeso72.40GRIS3.61SEC/CAT48.27TaxaPedagio5.23ValorLiquido146.39AdValorem16.8800146.3912.0017.572120.80LIQUIDO CORROSIVO ACIDO INORGANICO03VOLUME4.0000080822000234502011-07-290VAHbZ77V2XkfJ/a9HkjUEZU17rw=GpFAhaFZViTVUIdYvgpGm8wIsytVOMjmvEGEb2fVIhryXEnj3kYGUmiWgPGRprUwV/C2bkdFaoioS//v4VEd95xjKD0MuV+uZhih6Q7sLSlkxH3wD2w49VDM9wJVxO9Pp0I4VU28FVbT44QKGjhDSYn+3EqJN1k+VJEhem69lik=MIIGWjCCBUKgAwIBAgIIfE0nfEKvLwowDQYJKoZIhvcNAQEFBQAwdTELMAkGA1UEBhMCQlIxEzARBgNVBAoTCklDUC1CcmFzaWwxNjA0BgNVBAsTLVNlY3JldGFyaWEgZGEgUmVjZWl0YSBGZWRlcmFsIGRvIEJyYXNpbCAtIFJGQjEZMBcGA1UEAxMQQUMgU0VSQVNBIFJGQiB2MTAeFw0xMTA3MDYxMTU3MzVaFw0xMjA3MDUxMTU3MzVaMIHaMQswCQYDVQQGEwJCUjELMAkGA1UECBMCUlMxEjAQBgNVBAcTCUNBUkFaSU5ITzETMBEGA1UEChMKSUNQLUJyYXNpbDE2MDQGA1UECxMtU2VjcmV0YXJpYSBkYSBSZWNlaXRhIEZlZGVyYWwgZG8gQnJhc2lsIC0gUkZCMRYwFAYDVQQLEw1SRkIgZS1DTlBKIEExMRIwEAYDVQQLEwlBUiBTRVJBU0ExMTAvBgNVBAMTKFRSQU5TUE9SVEVTIFdBTERFTUFSIExUREE6ODkzMTc2OTcwMDAxMzIwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMBVCMXNB+b8uHoxu3Wn0Jm6xGjg+v2KRx6IHShapVRdGXxNaPqu6oZ8JRqA18i9+/3J57dvg7BqccMggwhe8179V8nyLeMSbnoGrKQDhzRvZLDM83DQBPtAwdVrDBVoNsfz+/uWjkJ2ooFBCt5EzA1mamPjPNQTggTjGODEoEshAgMBAAGjggMKMIIDBjAJBgNVHRMEAjAAMA4GA1UdDwEB/wQEAwIF4DAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwQwHwYDVR0jBBgwFoAUmt0itvZ36UJvSMJRQKBW4vN0P7swgb0GA1UdEQSBtTCBsoEiQ09OVEFCSUxJREFERUBUV1RSQU5TUE9SVEVTLkNPTS5CUqAZBgVgTAEDAqAQEw5WQUxERU1BUiBLTEVJTqAZBgVgTAEDA6AQEw44OTMxNzY5NzAwMDEzMqA9BgVgTAEDBKA0EzIxMzA1MTk0MTE4MTIzMTM5MDA0MDAwMDAwMDAwMDAwMDAwMDEwMTY4MjM3NjVTU1BSU6AXBgVgTAEDB6AOEwwwMDAwMDAwMDAwMDAwVwYDVR0gBFAwTjBMBgZgTAECAQ0wQjBABggrBgEFBQcCARY0aHR0cDovL3d3dy5jZXJ0aWZpY2Fkb2RpZ2l0YWwuY29tLmJyL3JlcG9zaXRvcmlvL2RwYzCB8wYDVR0fBIHrMIHoMEqgSKBGhkRodHRwOi8vd3d3LmNlcnRpZmljYWRvZGlnaXRhbC5jb20uYnIvcmVwb3NpdG9yaW8vbGNyL3NlcmFzYXJmYnYxLmNybDBEoEKgQIY+aHR0cDovL2xjci5jZXJ0aWZpY2Fkb3MuY29tLmJyL3JlcG9zaXRvcmlvL2xjci9zZXJhc2FyZmJ2MS5jcmwwVKBSoFCGTmh0dHA6Ly9yZXBvc2l0b3Jpby5pY3BicmFzaWwuZ292LmJyL2xjci9TZXJhc2EvcmVwb3NpdG9yaW8vbGNyL3NlcmFzYXJmYnYxLmNybDCBmQYIKwYBBQUHAQEEgYwwgYkwSAYIKwYBBQUHMAKGPGh0dHA6Ly93d3cuY2VydGlmaWNhZG9kaWdpdGFsLmNvbS5ici9jYWRlaWFzL3NlcmFzYXJmYnYxLnA3YjA9BggrBgEFBQcwAYYxaHR0cDovL29jc3AuY2VydGlmaWNhZG9kaWdpdGFsLmNvbS5ici9zZXJhc2FyZmJ2MTANBgkqhkiG9w0BAQUFAAOCAQEAgVHQIzWgqmBMT+0fsh9bpJE45ZTfT+qVQMUtlDN5XNRkOU5mm7xB98svNuVxw7cxehC0CzOte0C3b+slLRdGHkH2ay5awi3FKnhq0O0wPZynzspy6Ily/EqVHaAwFs/Rm1mcisMj0i0ETAy15Cczq1kZGbWsIAVuWTtqvgItZ7Keg1/Pa3m6TdDHm5XcunUFybTSmfL+sDsrIjb3BZZZPxSWTkFg90iPKE3hyy2t9YCtq8Dxu3UIMARHx572LWGDNG4CWmg3SJVUEzF9BB+XS9wGUTE+OH0aM83D7Z3fK8wyoxRhPmEetCeUijjDzih0CJh3u+gufrhpL9/hS1wJDQ==1RS20100930124337421107893176970018805700000000022500600022502011-07-26T17:58:01342110001068545VAHbZ77V2XkfJ/a9HkjUEZU17rw=100Autorizado o uso do CT-e
--------------------------------------------------------------------------------
/spec/fixtures/nfe_date_format_infoadprod_infoadfisco_issues.xml:
--------------------------------------------------------------------------------
1 | 3580000042RETORNO/INDUSTRIALIZAÇÃO EFETUADA PARA OUTRO ESTABELECIMENTO155120952014-03-12135231071101132.2.2159374918000143TECNOLIGAS INDÚSTRIA E COMÉRCIO DE METAIS LTDATECNOLIGASRUA COBALTO19CORREDOR INDUSTRIAL3523107ItaquaquecetubaSP085861201058BRASIL0114648664437902942011062962452100145581238000196DAISA INDUSTRIA METALURGICA LTDAAV HELIO OSSAMU DAIKUARA1800 BVISTA ALEGRE3515004EmbuSP068070001058BRASIL114704552229800652911702RECUPERACAO DE BORRA DE ALUMINIO (TRANSFORMACAO PARA LINGOTES)760200005124KG3323.00001.25000000004153.75KG3323.00001.2500000000101012.84117.9607699951024153.750.2811.63024153.751.1648.1814RETORNO DE MERCADORIA RECEBIDA PARA TRANSFORMACAO PARA LINGOTES DE ALUMINIO760200005902KG5200.00003.000000000015600.00KG5200.00003.000000000010400076999530808MATERIAL DE VOSSA PROPR. CF NF Nº 026.039 DE 07/03/2014, QUE RETORNAM TRANSFORMADOS EM LINGOTES DE ALUMINIO COM QUEBRA = 1.877 KG.0.000.000.000.0019753.750.000.000.000.000.0011.6348.180.0019753.75159374918000143TECNOLIGAS INDUSTRIA E COMERCIO DE METAIS LTDA379029420110RUA COBALTO, 19ItaquaquecetubaSPA GRANELS/MS/N5200.0005200.00020954153.754153.752095/12014-04-114153.75EMPRESA OPTANTE PELO SIMPLES NACIONAL.bAGJFpwJ1TznKGjrfj3nAV6+pIs=SPGXJgTe1J2XByj2l6MmvtXw9W1J0nAu8tf809v6r/appFbkEGeLcvbW26u53DGCSiWTt9oiUmUH
2 | hph/GNYVN1WVDK55UhpetP7xDd5qHsg0X/vyrUXBoT+IZ0O28FF/Ndwu+hCrB6xYwZCGQmGkRQ7G
3 | TZvMvMjvm74/jAE2XNNGZOc0qHPqn0DnIadMD6aYX4eo/Y9JXpPrSzrR1r47MlHfFPP2VsyoQ6+F
4 | 3XHhNW6yfVdxGbsxVvrgAaX41CgbU7mZZwG63Tx3M3COmwFYRuOpZBugvPGOVmgtooDETv9fcrFS
5 | Kyga49JFCoPuYoF3Ch1XnA3gusvc5Q9GZxSfdA==MIIIZDCCBkygAwIBAgIQHCgWAi5evL0ekPewJ3yeijANBgkqhkiG9w0BAQsFADB4MQswCQYDVQQG
6 | EwJCUjETMBEGA1UEChMKSUNQLUJyYXNpbDE2MDQGA1UECxMtU2VjcmV0YXJpYSBkYSBSZWNlaXRh
7 | IEZlZGVyYWwgZG8gQnJhc2lsIC0gUkZCMRwwGgYDVQQDExNBQyBDZXJ0aXNpZ24gUkZCIEc0MB4X
8 | DTEyMDUxMTAwMDAwMFoXDTE1MDUxMDIzNTk1OVowggEMMQswCQYDVQQGEwJCUjETMBEGA1UEChQK
9 | SUNQLUJyYXNpbDELMAkGA1UECBMCU1AxGDAWBgNVBAcUD0lUQVFVQVFVRUNFVFVCQTE2MDQGA1UE
10 | CxQtU2VjcmV0YXJpYSBkYSBSZWNlaXRhIEZlZGVyYWwgZG8gQnJhc2lsIC0gUkZCMRYwFAYDVQQL
11 | FA1SRkIgZS1DTlBKIEEzMSYwJAYDVQQLFB1BdXRlbnRpY2FkbyBwb3IgQVIgR3VhcnVmb3J0ZTFJ
12 | MEcGA1UEAxNAVEVDTk9MSUdBUyBJTkRVU1RSSUEgRSBDT01FUkNJTyBERSBNRVRBSVMgTFREQSBF
13 | UDo1OTM3NDkxODAwMDE0MzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANmyIeuvBdoj
14 | hMC73wPtiu59bW/u2DplnOv1pl9OkyHrd1+k6uHwsLXjDcf54mEJ9fJtZXvp4iVkHiJ1pCw4BEzx
15 | +PhBdzvix5wMGztlcqk2aN7dQtqr/8L7b6ARDpGIRVZoHUCC+6PwxtIYgA/DSFfAe1fqHBQr4vkD
16 | rEcJGZ/EsyZASsUgkdOkzO9/XlUaCGds1nQ3R1kiSeakglgRG6QMwKIYlgV/N/DYhS/F0Yioa1Go
17 | 16zpo7OaOh1LBgxtLaEbtqWcE3Sd7GMcnSI2qnFshSjOKVj0RNQgFgZVSDofqjvLscLBxkS820qH
18 | O+Mj2Sn8DCY387i4ngxIcydq4gkCAwEAAaOCA1IwggNOMIG3BgNVHREEga8wgaygOAYFYEwBAwSg
19 | LwQtMTUxMDE5NjIwMTI4ODU5MDgzMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwoCMGBWBMAQMC
20 | oBoEGEFHTkFMRE8gQk9ORVRURSBQT0xJRE9SSaAZBgVgTAEDA6AQBA41OTM3NDkxODAwMDE0M6AX
21 | BgVgTAEDB6AOBAwwMDAwMDAwMDAwMDCBF3RlY25vbGlnYXNAdGVycmEuY29tLmJyMAkGA1UdEwQC
22 | MAAwHwYDVR0jBBgwFoAULpHq1m3lslmC3DiFKXY0FlY80D4wDgYDVR0PAQH/BAQDAgXgMH8GA1Ud
23 | IAR4MHYwdAYGYEwBAgMGMGowaAYIKwYBBQUHAgEWXGh0dHA6Ly9pY3AtYnJhc2lsLmNlcnRpc2ln
24 | bi5jb20uYnIvcmVwb3NpdG9yaW8vZHBjL0FDX0NlcnRpc2lnbl9SRkIvRFBDX0FDX0NlcnRpc2ln
25 | bl9SRkIucGRmMIIBFgYDVR0fBIIBDTCCAQkwV6BVoFOGUWh0dHA6Ly9pY3AtYnJhc2lsLmNlcnRp
26 | c2lnbi5jb20uYnIvcmVwb3NpdG9yaW8vbGNyL0FDQ2VydGlzaWduUkZCRzQvTGF0ZXN0Q1JMLmNy
27 | bDBWoFSgUoZQaHR0cDovL2ljcC1icmFzaWwub3V0cmFsY3IuY29tLmJyL3JlcG9zaXRvcmlvL2xj
28 | ci9BQ0NlcnRpc2lnblJGQkc0L0xhdGVzdENSTC5jcmwwVqBUoFKGUGh0dHA6Ly9yZXBvc2l0b3Jp
29 | by5pY3BicmFzaWwuZ292LmJyL2xjci9DZXJ0aXNpZ24vQUNDZXJ0aXNpZ25SRkJHNC9MYXRlc3RD
30 | UkwuY3JsMB0GA1UdJQQWMBQGCCsGAQUFBwMCBggrBgEFBQcDBDCBmwYIKwYBBQUHAQEEgY4wgYsw
31 | XwYIKwYBBQUHMAKGU2h0dHA6Ly9pY3AtYnJhc2lsLmNlcnRpc2lnbi5jb20uYnIvcmVwb3NpdG9y
32 | aW8vY2VydGlmaWNhZG9zL0FDX0NlcnRpc2lnbl9SRkJfRzQucDdjMCgGCCsGAQUFBzABhhxodHRw
33 | Oi8vb2NzcC5jZXJ0aXNpZ24uY29tLmJyMA0GCSqGSIb3DQEBCwUAA4ICAQDPdVSjPZ7tdTx4pCHV
34 | OOmbEJ5PP5RkTvZ1FCspjJ5jNSNqrGAp/dm19OeTg0rBeqZ+SJgA6TuinpgtGL+vwtMquDGeLLef
35 | n7Df/OKtrLJkfK+vfTpK6MuJBahmI8nyHv5ouoSBEpJ8byDo1a+OSgXAaYsBasC0I3shpdLdzZ1h
36 | k35x6kUlEirQyHMtbxlOAw+HfzQmv+1qOZpt3ElbC1CtR1Bun56JC5YuiOAd03OhJP01JAnzw5Ze
37 | XnAfmEQh35310+PLTnJAD8mdPNMXdZAXBhIspyDMy/gM2ou5R/9k5coK2fTcwjqH0atL9ezGnBqB
38 | vH9txy8ArcdWrosjLuNrbOq4fqrK8PjUZKVptBYMh4nEMwf8uI2ega1E+0TEwIFx7TnVvUR3U3DO
39 | u2Zl/U+9Pc16LBRAubafO68PnGn9IeEgLE5dL1mkG34lHxhU4oLF7q631divGR4B5DIA/UjhiRnJ
40 | nsGL+STa2q3i5sOMfuhhhr3UIVg/xkbeFZHx+NK/1BJe1/eDmiK4eofAYVCzhb1yRHWotDJMQ6yq
41 | dVvIdpia77H57h02bwtd0YoQ8yC8daVH0roZONE2klI55XrThX7GV372Vm/K03anTZS9KKDpzXMu
42 | THTsT17MV8IxuMX21LRkitKSO4Y6l+C6Y09bT/MX/rQSBNopxtLgBPu8iQ==1SP_NFE_PL_006q351403593749180001435500100000209518000004202014-03-12T10:41:31135140152647164bAGJFpwJ1TznKGjrfj3nAV6+pIs=100Autorizado o uso da NF-e
--------------------------------------------------------------------------------
/spec/fixtures/nfe_simples_nacional.xml:
--------------------------------------------------------------------------------
1 | 35000000016101-Venda de producao do estabelecimento155112013-12-2813550308116110160891033000109KRON INSTRUMENTOS ELETRICOS LTDAKRON INSTRUMENTOS ELETRICOS LTDARUA ALEXANDRE DE GUSMAO278SOCORRO3550308SAO PAULOSP047600201058BRASIL1155252000111393871117182743287000880Schneider Electric Brasil LtdaAv da Saudade1125Frutal3552403SUMARESP131713201058BRASIL19210463006710083751101Tijolo Macico Tipo A69041000006101MI2.000010.000000000020.00MI2.000010.000000000015.350102990.000.000.00990.000.000.002Tijolo Macico Tipo B69041000006101MI3.000020.000000000060.00MI3.000020.0000000000116.050102990.000.000.00990.000.000.003Tijolo Macico Tipo C69041000006101MI4.000030.0000000000120.00MI4.000030.0000000000132.100102990.000.000.00990.000.000.000.000.000.000.00200.000.000.000.000.000.000.000.000.00200.0053.500112014-01-2740.0022014-02-2640.0032014-03-2840.0042014-04-2740.0052014-05-2740.00DOCUMENTO EMITIDO POR ME OU EPP OPTANTE PELO SIMPLES NACIONAL * NAO GERA DIREITO A CREDITO FISCAL DE IPI * Tributos: R$ 53,50 (26,75%)
2 |
--------------------------------------------------------------------------------
/spec/fixtures/nfe_with_fci.xml:
--------------------------------------------------------------------------------
1 | 3563472050VENDA DE PRODUCAO DO ESTABELECIMENTO1551445252013-10-18135503081151105.060891033000109KRON INSTRUMENTOS ELETRICOS LTDAKRONRUA ALEXANDRE DE GUSMAO278SOCORRO3550308SAO PAULOSP047600201058BRASIL1155252000111393871117382743287000880SCHNEIDER ELECTRIC BRASIL LTDAAV. DA SAUDADE1125FRUTAL3552403SUMARESP131713201058BRASIL1921046300671008375110nfemerc.sumare@br.schneider-electric.comF211130101000AMPERIMETRO FM72PC 300/5A COD 3491192843 RL90303329005101PC1.0049.2349.23PC1.0049.231980019211012232531-74B2-4FDD-87A6-CF0AD3E55386500349.2312.005.909995049.235.002.460149.230.650.320149.233.001.4849.235.900.000.0049.230.000.000.000.002.460.321.480.0051.69050547058000128POST MASTER COMERCIAL LTDA111768652113RUA VIEIRA DE MORAES 558SAO PAULOSP1CAIXAKRON11.0001.0000044525/012013-12-1751.69FRETE CIF / INDUSTRIALIZACAO PEDIDO 98001921 VENC. DAS DUPLICATAS 01/ 10 / 20 DO MES - VIA DEPOSITO [EMAIL=nfemerc.sumare@br.schneider-electric.com]98001921dndW1koiOiYKZkXf7cWtg5vfL2Y=JXN6WtG/sLQgtEI0n0BhajaphVDAX99A+QcrC3XxTkP4vZ/yHpwr2ngvs3t0M1uLECymakCxjT/qMmanJDiaAGxfWmBJkdgDFa80zJ2RoS9RqF48QmNXHfDNtjwwgw12RlFC8reLWGw7qXD9Nre5E9bTWJqEH4RHhKcg/akiWsQ2uy6M2O/m3IgznCG6wMnhaE98BbXTqcHLrvRignT86HQssaV6DDVm2kXyL1FM8YMZF3TtbsMQ8PJs70FrwddVzFIPoYxSq7iBw40ZdveuexYApVYJdyUssBZcxnlWtaS9aOWpd1fqHiQy5fKRRycBwOdMEPcQXGKqkNUs1hlUtg==MIIIQjCCBiqgAwIBAgIQdHnQdADNdDiHWqCYm1mh6zANBgkqhkiG9w0BAQsFADB4MQswCQYDVQQGEwJCUjETMBEGA1UEChMKSUNQLUJyYXNpbDE2MDQGA1UECxMtU2VjcmV0YXJpYSBkYSBSZWNlaXRhIEZlZGVyYWwgZG8gQnJhc2lsIC0gUkZCMRwwGgYDVQQDExNBQyBDZXJ0aXNpZ24gUkZCIEc0MB4XDTEzMDIyNTAwMDAwMFoXDTE0MDIyNDIzNTk1OVowgfExCzAJBgNVBAYTAkJSMRMwEQYDVQQKFApJQ1AtQnJhc2lsMQswCQYDVQQIEwJTUDESMBAGA1UEBxQJU0FPIFBBVUxPMTYwNAYDVQQLFC1TZWNyZXRhcmlhIGRhIFJlY2VpdGEgRmVkZXJhbCBkbyBCcmFzaWwgLSBSRkIxFjAUBgNVBAsUDVJGQiBlLUNOUEogQTExIjAgBgNVBAsUGUF1dGVudGljYWRvIHBvciBBUiBGQUNFU1AxODA2BgNVBAMTL0tST04gSU5TVFJVTUVOVE9TIEVMRVRSSUNPUyBMVERBOjYwODkxMDMzMDAwMTA5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAs7JenW0yMGg/bzp+ByFBjxG2nxE9DvzegNzr9NzH+ob+9nCm2iCDaB12dytrPD9aJYXE9Y4AcO+R8a5iUkTaGS4fGAfT11JSNyFLmatR+Z5AJZZ4j0N6g5moRWxOShPjoqxPf43IpAFwQrb2AhWi+wrTtwbS89jvVonGQvEdQsS1zkzX7KWvvy2bFcUCupvXd+TP0aIdyi2XjCkpGT0j3T1qvZrz2WnbhWW4VqZVfXiVZyYhijgbi+IO7s5wrYVTJCZtNvoffRsmGh+aTTlGgapjatWN+3u+M885Y4umFBqEmGgWxoidO1xXiURYhkLF5w2wlxJlwcC0qsF2wpuPOwIDAQABo4IDTDCCA0gwgbEGA1UdEQSBqTCBpqA4BgVgTAEDBKAvBC0yOTA3MTk1NTAxMjU1MzE4ODU2MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDCgJQYFYEwBAwKgHAQaRkVSTkFORE8gTUFSQ0hFVFRJIEJFRElDS1OgGQYFYEwBAwOgEAQONjA4OTEwMzMwMDAxMDmgFwYFYEwBAwegDgQMMDAwMDAwMDAwMDAwgQ9jcGRAa3Jvbi5jb20uYnIwCQYDVR0TBAIwADAfBgNVHSMEGDAWgBQukerWbeWyWYLcOIUpdjQWVjzQPjAOBgNVHQ8BAf8EBAMCBeAwfwYDVR0gBHgwdjB0BgZgTAECAQwwajBoBggrBgEFBQcCARZcaHR0cDovL2ljcC1icmFzaWwuY2VydGlzaWduLmNvbS5ici9yZXBvc2l0b3Jpby9kcGMvQUNfQ2VydGlzaWduX1JGQi9EUENfQUNfQ2VydGlzaWduX1JGQi5wZGYwggEWBgNVHR8EggENMIIBCTBXoFWgU4ZRaHR0cDovL2ljcC1icmFzaWwuY2VydGlzaWduLmNvbS5ici9yZXBvc2l0b3Jpby9sY3IvQUNDZXJ0aXNpZ25SRkJHNC9MYXRlc3RDUkwuY3JsMFagVKBShlBodHRwOi8vaWNwLWJyYXNpbC5vdXRyYWxjci5jb20uYnIvcmVwb3NpdG9yaW8vbGNyL0FDQ2VydGlzaWduUkZCRzQvTGF0ZXN0Q1JMLmNybDBWoFSgUoZQaHR0cDovL3JlcG9zaXRvcmlvLmljcGJyYXNpbC5nb3YuYnIvbGNyL0NlcnRpc2lnbi9BQ0NlcnRpc2lnblJGQkc0L0xhdGVzdENSTC5jcmwwHQYDVR0lBBYwFAYIKwYBBQUHAwIGCCsGAQUFBwMEMIGbBggrBgEFBQcBAQSBjjCBizBfBggrBgEFBQcwAoZTaHR0cDovL2ljcC1icmFzaWwuY2VydGlzaWduLmNvbS5ici9yZXBvc2l0b3Jpby9jZXJ0aWZpY2Fkb3MvQUNfQ2VydGlzaWduX1JGQl9HNC5wN2MwKAYIKwYBBQUHMAGGHGh0dHA6Ly9vY3NwLmNlcnRpc2lnbi5jb20uYnIwDQYJKoZIhvcNAQELBQADggIBAK22zXyUD+FxXBLcP99DfElExHg7a8ZIqCNQs58pG5xR5rNYib46z6tGmEsWCbgViagokqdyQmLNAfE/t1UqOdu4dxMoQM2m5O3Nk/PDOaVVe5y93dFBOr5xMQsfQFtcHbWO0QTeJdG0Uh0LxhRVriPH9JmvAMPUjUl9W/+/hIjohh/zVDyX8WfBKRvVqn/RbFaBSyoYiLDBQWZ4FecrcqX/IXViSDM4d6jFS7+6OSFHgxzl08M4zAqaaSD51IQ3N9fcdhTolVAgHSNNMou88eJaRhbMGtX5qciiUbDTgaX69VbPWeSKtA3TpHKMvNidZTfhhu8X/MxqztTpEEUrKfxRLkIUdVkho3a2/GfD3ePcy7k+Zexu2u1vTkXSGXKDvrJkowOXI11Xob6CP6ZNCCaftdQ+8WA+kZpthjILhY6G7jYy20OFiPTPLwC70funz+wkAB2upX7fMkxctTuAEEbecwcshJS4IgOJCOWPjuOFVMrCOKi1xgPZTxmmHZ9JcVik2Z7JlwV2r+j2sjAYYCFExipw2PmbTDtSL3worhASMsllWYaSmGM524aPEWXiemR0zfKEUuS5wDBdFJrsZkjJDIFJs0AmP2rXf2ftoN73g/ap2ycqbgpt5NYBhhN1az9sc/n6062WatrXVrj94Vx8j+8j6L42Qwx+PrB9Fzrr1SP_NFE_PL_006q351310608910330001095500100004452516347205052013-10-18T13:54:04135130636167763dndW1koiOiYKZkXf7cWtg5vfL2Y=100Autorizado o uso da NF-e
--------------------------------------------------------------------------------
/spec/fixtures/nfe_with_ns.xml:
--------------------------------------------------------------------------------
1 | 2500013415Vendas de producao do estabelecimento1552134152011-10-292011-10-2912507507111110Integrat12345678901234ACME SAACME-PBRUA HORTENCIO RIBEIRO DE LUNA3333DISTRITO INDUSTRIAL2507507Joao PessoaPB580814001058BRASIL8321062200160158257398765432101234EDITORA BLEBLEBLE LTDARUA URBANO SANTOS, N755 (ANT 160)0CUMBICA3518800GuarulhosSP071823201058BRASIL1127901347336322171116
2 | 00005LIVRO POR LIT GRAMATICA PROD TEXTO 3a SERIE ALUNO490199006101UN28080.00003.9400110635.20UN28080.00003.9400100030.000.000.00010.000.000.00010.000.000.00
3 | 00005LIVRO POR LIT GRAMATICA PROD TEXTO 3a SERIE ALUNO490199006101UN28080.00003.9400110635.20UN28080.00003.9400100030.000.000.00010.000.000.00010.000.000.0000005LIVRO POR LIT GRAMATICA PROD TEXTO 3a SERIE ALUNO490199006101UN28080.00003.9400110635.20UN28080.00003.9400100030.000.000.00010.000.000.00010.000.000.0000005LIVRO POR LIT GRAMATICA PROD TEXTO 3a SERIE ALUNO490199006101UN28080.00003.9400110635.20UN28080.00003.9400100030.000.000.00010.000.000.00010.000.000.0000005LIVRO POR LIT GRAMATICA PROD TEXTO 3a SERIE ALUNO490199006101UN28080.00003.9400110635.20UN28080.00003.9400100030.000.000.00010.000.000.00010.000.000.0000005LIVRO POR LIT GRAMATICA PROD TEXTO 3a SERIE ALUNO490199006101UN28080.00003.9400110635.20UN28080.00003.9400100030.000.000.00010.000.000.00010.000.000.0000005LIVRO POR LIT GRAMATICA PROD TEXTO 3a SERIE ALUNO490199006101UN28080.00003.9400110635.20UN28080.00003.9400100030.000.000.00010.000.000.00010.000.000.0000005LIVRO POR LIT GRAMATICA PROD TEXTO 3a SERIE ALUNO490199006101UN28080.00003.9400110635.20UN28080.00003.9400100030.000.000.00010.000.000.00010.000.000.0000005LIVRO POR LIT GRAMATICA PROD TEXTO 3a SERIE ALUNO490199006101UN28080.00003.9400110635.20UN28080.00003.9400100030.000.000.00010.000.000.00010.000.000.0000005LIVRO POR LIT GRAMATICA PROD TEXTO 3a SERIE ALUNO490199006101UN28080.00003.9400110635.20UN28080.00003.9400100030.000.000.00010.000.000.00010.000.000.0000005LIVRO POR LIT GRAMATICA PROD TEXTO 3a SERIE ALUNO490199006101UN28080.00003.9400110635.20UN28080.00003.9400100030.000.000.00010.000.000.00010.000.000.0000005LIVRO POR LIT GRAMATICA PROD TEXTO 3a SERIE ALUNO490199006101UN28080.00003.9400110635.20UN28080.00003.9400100030.000.000.00010.000.000.00010.000.000.0000005LIVRO POR LIT GRAMATICA PROD TEXTO 3a SERIE ALUNO490199006101UN28080.00003.9400110635.20UN28080.00003.9400100030.000.000.00010.000.000.00010.000.000.0000005LIVRO POR LIT GRAMATICA PROD TEXTO 3a SERIE ALUNO490199006101UN28080.00003.9400110635.20UN28080.00003.9400100030.000.000.00010.000.000.00010.000.000.0000005LIVRO POR LIT GRAMATICA PROD TEXTO 3a SERIE ALUNO490199006101UN28080.00003.9400110635.20UN28080.00003.9400100030.000.000.00010.000.000.00010.000.000.00
4 | 0.000.000.000.00110635.200.000.000.000.000.000.000.000.00110635.20010849477000108TRANSPRINT - TRANSPORTADORA E LOGISTICA LTDA148613972111Rua do TatuapeSAO PAULOSP00000000SP00000026VOLUMES(s)DIVERSOS025000.00025000.00013415//1110635.20110635.2013415//1-12012-02-26110635.20Obs: PEDIDO DE COMPRA: 308.996 MATERIAL IMUNE CONFORME ART.150 INCISO VI ALINEA D DA CONSTITUICAO FEDERAL.9jeTTSaza8lMT2Xk5hbWx86Fbp4=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1SVRS20110801092042251110123456789012345500200001341510001341512011-10-29T14:37:093251100128663209jeTTSaza8lMT2Xk5hbWx86Fbp4=100Autorizado o uso da NF-e
5 |
--------------------------------------------------------------------------------
/spec/fixtures/nfe_without_ns.xml:
--------------------------------------------------------------------------------
1 |
2 | 3191136050REMESSA MERC. P/ CONSERTO055100121182013-02-22131186011171105.099984626000136ACME SAACMEVIA EXPRESSA DE CONTAGEM3850CINCAO3118601CONTAGEMMG323704851058BRASIL31339966001862422430000398765432101234BLABLABLA LTDAAV. MARGINAL DO RIB. DOS CRISTAIS200JORDANESIA3509205CAJAMARSP077600001058BRASIL3130698013241029868119F-MERCPCMONITOR DE ARCO ELETRICO COD:1-VAMP2213A3AAA NS: V221-00663085369090006915pc1.004491.254491.25pc1.004491.25109030.000.000.0040.000.000.00999510707F-MERCPCDETECTOR FALHA ISOLAMENTO COD:1-XD312127-01 NS: 1518385V185369090006915pc1.001588.701588.70pc1.001588.70109030.000.000.0040.000.000.00999510707F-MERCPCMONITOR DE ARCO ELETRICO COD:1-VAMP2213A3AAA NS: V221-00682485369090006915pc1.004038.754038.75pc1.004038.75109030.000.000.0040.000.000.009995107070.000.000.000.0010118.700.000.000.000.000.000.000.000.0010118.70020147617000141JAMEF TRANSPORTADORA LTDA0624426220024RUA DR JOSE AMERICO CANCADO BAHIA 1810CONTAGEMMG2.10.00010.000MATERIAL DE NOSSA PROPRIEDADE QUE SEGUE PARA REPAROS, DEVENDO RETORNAR AO NOSSO ESTABELECIMENTO. **** ICMS SUSPENSO CONF.ART.19 ITEM 1 ANEXO III DEC.43080 IPI SUSPENSO CONF.ART.42 INCISO XIII DEC.4544 DEZ/02 ROMA-491 | Cod.Repart.Fiscal: 00001CAmkmMtOyPC1hfWU/LLGQUdAZ6Q=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113_0_61311302123456789012345510000001211819113605072013-02-22T09:32:54131131006404486CAmkmMtOyPC1hfWU/LLGQUdAZ6Q=100Autorizado o uso da NF-e
--------------------------------------------------------------------------------
/spec/fixtures/nfse.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | 56293
7 | VKLN-H5PH
8 | 2018-09-03T11:30:07
9 |
10 | 59566
11 | A
12 | 1
13 |
14 | 2018-09-03
15 | 1
16 | 2
17 | 2
18 | 2018-09-03T00:00:00
19 |
20 |
21 | 2464
22 | 22.17
23 | 2
24 | 49.28
25 | 2464
26 | 0.02
27 | 2441.83
28 |
29 | 1602
30 | 160202
31 | Serviços prestados por condutores autônomos de táxi......:2.464,00
32 | Dispensa da retencao da CSLL conforme o art. 39 da Lei 10.865/2004.
33 | Servico nao sujeito a retencao de PIS e COFINS conforme Lei 10.833/2003
34 | combinada com o IN nr 381/2003 e nao contida no RIR /99 Art 647
35 | Conforme lei 12.649/2012 as cooperativas ficam isentas do PIS e da COFINS sobre os valores devidos aos
36 | cooperados
37 | BASE IRRF.........: 2.464,00
38 | PARTE TRIBUTAVEL..: 1.478,40
39 | VALOR IRRF........: 22,17
40 | CODIGO DO CLIENTE.: [ 004219 ] VENCIMENTO..: 24/09/2018
41 | PROCON-RJ - TEL 151 - RUA DA AJUDA, 5 - CENTRO - RIO DE JANEIRO - CEP - 20040-000
42 | CODECON ALERJ - TEL 0800 282 7060 - RUA DA ALFANDEGA, 8 - TERREO- CENTRO - RIO DE JANEIRO
43 |
44 | 3304557
45 |
46 |
47 |
48 | 30921357000173
49 | 982989
50 |
51 | COOPATAXI COOP DE CONS E TRAB DOS MOT AUT DE TAXI DO MUN DO RIO DE JANEIRO LTDA
52 | COOPATAXI
53 |
54 | RUA HERCULANO PENA 667
55 | 667
56 | CAVALCANTI
57 | 3304557
58 | RJ
59 | 21381410
60 |
61 |
62 | 32884343
63 | faturamento@coopataxi.com.br
64 |
65 |
66 |
67 |
68 |
69 | 03597703000137
70 |
71 | 2764032
72 |
73 | SITA INC DO BRASIL LTDA
74 |
75 | AVN RIO BRANCO 53, SAL 801 802 901 E 902
76 | 53
77 | SAL 801 802 901 E 902
78 | CENTRO
79 | 3304557
80 | RJ
81 | 20090004
82 |
83 |
84 | 2132637215
85 | invoices-brazil@sita.aero
86 |
87 |
88 |
89 | 3304557
90 | RJ
91 |
92 |
93 |
94 |
95 |
96 |
--------------------------------------------------------------------------------
/spec/lib/cst_spec.rb:
--------------------------------------------------------------------------------
1 | require "spec_helper"
2 |
3 | describe RubyDanfe::Cst do
4 | let(:xml_cst) do
5 | xml = <<-eos
6 |
7 |
8 |
9 | 5
10 | 00
11 | 3
12 | 49.23
13 | 12.00
14 | 5.90
15 |
16 |
17 |
18 | eos
19 |
20 | Nokogiri::XML(xml)
21 | end
22 |
23 | let(:xml_csosn) do
24 | xml = <<-eos
25 |
26 |
27 |
28 | 4
29 | 102
30 |
31 |
32 |
33 | eos
34 |
35 | Nokogiri::XML(xml)
36 | end
37 |
38 | describe ".to_danfe" do
39 | context "when CST" do
40 | it "returns origin + CST" do
41 | expect(RubyDanfe::Cst.to_danfe(xml_cst)).to eq "500"
42 | end
43 | end
44 |
45 | context "when CSOSN" do
46 | it "returns origin + CSOSN" do
47 | expect(RubyDanfe::Cst.to_danfe(xml_csosn)).to eq "4102"
48 | end
49 | end
50 | end
51 | end
52 |
--------------------------------------------------------------------------------
/spec/lib/descricao_spec.rb:
--------------------------------------------------------------------------------
1 | #encoding: utf-8
2 |
3 | require "spec_helper"
4 |
5 | describe RubyDanfe::Descricao do
6 | LINEBREAK = "\n"
7 |
8 | let(:xml_fci) do
9 | xml = <<-eos
10 |
11 |
12 | MONITOR DE ARCO ELETRICO
13 | 12232531-74B2-4FDD-87A6-CF0AD3E55386
14 |
15 |
16 | eos
17 |
18 | Nokogiri::XML(xml)
19 | end
20 |
21 | let(:xml_st) do
22 | xml = <<-eos
23 |
24 |
25 | MONITOR DE ARCO ELETRICO
26 |
27 |
28 | 96.73
29 |
30 |
31 | 56.00
32 | 479.82
33 | 17.00
34 | 29.28
35 |
36 |
37 |
38 |
39 | eos
40 |
41 | Nokogiri::XML(xml)
42 | end
43 |
44 | let(:xml_infAdProd) do
45 | xml = <<-eos
46 |
47 |
48 | MONITOR DE ARCO ELETRICO
49 |
50 | Informações adicionais do produto
51 |
52 | eos
53 |
54 | Nokogiri::XML(xml)
55 | end
56 |
57 | let(:xml_veicProd) do
58 | xml = <<-eos
59 |
60 |
61 | MOTOCICLETA
62 |
63 | 32A1SF354S6FASD213ASD5
64 | PRETA
65 | DSA5DA-321503
66 | 2018
67 | 2018
68 |
69 |
70 |
71 | eos
72 |
73 | Nokogiri::XML(xml)
74 | end
75 |
76 | let(:xml_IFC_ST_infAdProd) do
77 | xml = <<-eos
78 |
79 |
80 | MONITOR DE ARCO ELETRICO
81 | 12232531-74B2-4FDD-87A6-CF0AD3E55386
82 |
83 |
84 | 96.73
85 |
86 |
87 | 56.00
88 | 479.82
89 | 17.00
90 | 29.28
91 |
92 |
93 |
94 | Informações adicionais do produto
95 |
96 | eos
97 |
98 | Nokogiri::XML(xml)
99 | end
100 |
101 | describe ".generate" do
102 | context "when have FCI" do
103 | it "returns product + FCI" do
104 | string = "MONITOR DE ARCO ELETRICO"
105 | string += LINEBREAK
106 | string +="FCI: 12232531-74B2-4FDD-87A6-CF0AD3E55386"
107 | expect(RubyDanfe::Descricao.generate(xml_fci)).to eq string
108 | end
109 | end
110 |
111 | context "when have ST" do
112 | it "returns product + ST" do
113 | string = "MONITOR DE ARCO ELETRICO"
114 | string += LINEBREAK
115 | string += "ST: MVA: 56.00% "
116 | string += "* Alíq: 17.00% "
117 | string += "* BC: 479.82 "
118 | string += "* Vlr: 29.28"
119 | expect(RubyDanfe::Descricao.generate(xml_st)).to eq string
120 | end
121 | end
122 |
123 | context "when have infAdProd" do
124 | it "returns product + infAdProd" do
125 | string = "MONITOR DE ARCO ELETRICO"
126 | string += LINEBREAK
127 | string += "Informações adicionais do produto"
128 | expect(RubyDanfe::Descricao.generate(xml_infAdProd)).to eq string
129 | end
130 | end
131 |
132 | context "when have veicProd" do
133 | it "returns product + veicProd" do
134 | string = "MOTOCICLETA"
135 | string += LINEBREAK
136 | string += "Chassi: 32A1SF354S6FASD213ASD5 "
137 | string += "Motor: DSA5DA-321503 "
138 | string += "AnoFab: 2018 "
139 | string += "AnoMod: 2018 "
140 | string += "Cor: PRETA"
141 | expect(RubyDanfe::Descricao.generate(xml_veicProd)).to eq string
142 | end
143 | end
144 |
145 | context "when have FCI + ST + infAdProd" do
146 | it "returns product + FCI + ST + infAdProd" do
147 | string = "MONITOR DE ARCO ELETRICO"
148 | string += LINEBREAK
149 | string += "Informações adicionais do produto"
150 | string += LINEBREAK
151 | string +="FCI: 12232531-74B2-4FDD-87A6-CF0AD3E55386"
152 | string += LINEBREAK
153 | string += "ST: MVA: 56.00% "
154 | string += "* Alíq: 17.00% "
155 | string += "* BC: 479.82 "
156 | string += "* Vlr: 29.28"
157 | expect(RubyDanfe::Descricao.generate(xml_IFC_ST_infAdProd)).to eq string
158 | end
159 | end
160 | end
161 | end
162 |
--------------------------------------------------------------------------------
/spec/lib/helper_spec.rb:
--------------------------------------------------------------------------------
1 | require "spec_helper"
2 |
3 | describe RubyDanfe::Helper do
4 | describe ".format_datetime" do
5 | context "when date format is %Y-%m-%d" do
6 | it "returns a formated string" do
7 | string = "2013-10-18T13:54:04"
8 | expect(RubyDanfe::Helper.format_datetime(string)).to eq "18/10/2013 13:54:04"
9 | end
10 | end
11 |
12 | context "when date format is %d/%m/%Y" do
13 | it "returns a formated string" do
14 | string = "25/02/2016 09:22:26"
15 | expect(RubyDanfe::Helper.format_datetime(string)).to eq "25/02/2016 09:22:26"
16 | end
17 | end
18 | end
19 |
20 | describe ".format_date" do
21 | it "returns a formated string" do
22 | string = "2013-10-18"
23 | expect(RubyDanfe::Helper.format_date(string)).to eq "18/10/2013"
24 | end
25 |
26 | it "returns a formated string" do
27 | string = ""
28 | expect(RubyDanfe::Helper.format_date(string)).to eq ""
29 | end
30 | end
31 |
32 | describe ".format_time" do
33 | it "returns a formated string" do
34 | string = "22:30:45"
35 | expect(RubyDanfe::Helper.format_time(string)).to eq "22:30:45"
36 | end
37 |
38 | it "returns a formated string" do
39 | string = ""
40 | expect(RubyDanfe::Helper.format_time(string)).to eq ""
41 | end
42 | end
43 |
44 | describe ".format_quantity" do
45 | context "with RubyDanfe.options.numerify_prod_qcom false" do
46 | before(:each) {
47 | RubyDanfe.options.numerify_prod_qcom = false
48 | }
49 | it "should replace last dot for comma" do
50 | expect(RubyDanfe::Helper.format_quantity("100.00")).to eq "100,00"
51 | end
52 | it "should replace all commas for dot except the last one" do
53 | expect(RubyDanfe::Helper.format_quantity("2,100.00")).to eq "2.100,00"
54 | end
55 | it "should do anything if there is no comma and dot" do
56 | expect(RubyDanfe::Helper.format_quantity("100")).to eq "100"
57 | end
58 | it "should keep decimals" do
59 | expect(RubyDanfe::Helper.format_quantity("1.665")).to eq "1,665"
60 | end
61 | end
62 |
63 | context "with RubyDanfe.options.numerify_prod_qcom true" do
64 | context "with quantity_decimals = 4" do
65 | before(:each) {
66 | RubyDanfe.options.numerify_prod_qcom = true
67 | RubyDanfe.options.quantity_decimals = 4
68 | }
69 | it "should format number to 4 decimal places" do
70 | expect(RubyDanfe::Helper.format_quantity("100.00")).to eq "100,0000"
71 | end
72 | it "should format number with thousand separator" do
73 | expect(RubyDanfe::Helper.format_quantity("8956100.00")).to eq "8.956.100,0000"
74 | end
75 | it "should format number without dot and comma" do
76 | expect(RubyDanfe::Helper.format_quantity("200")).to eq "200,0000"
77 | end
78 | end
79 |
80 | context "with quantity_decimals = 3" do
81 | before(:each) {
82 | RubyDanfe.options.numerify_prod_qcom = true
83 | RubyDanfe.options.quantity_decimals = 3
84 | }
85 | it "should format number to 4 decimal places" do
86 | expect(RubyDanfe::Helper.format_quantity("100.00")).to eq "100,000"
87 | end
88 | it "should format number with thousand separator" do
89 | expect(RubyDanfe::Helper.format_quantity("8956100.00")).to eq "8.956.100,000"
90 | end
91 | it "should format number without dot and comma" do
92 | expect(RubyDanfe::Helper.format_quantity("200")).to eq "200,000"
93 | end
94 | end
95 | end
96 | end
97 |
98 | describe ".format_cnpj" do
99 | context "with a valid cnpj" do
100 | it "returns a formated string" do
101 | string = "15704602000105"
102 | expect(RubyDanfe::Helper.format_cnpj(string)).to eq "15.704.602/0001-05"
103 | end
104 | end
105 |
106 | context "with an invalid cnpj" do
107 | it "returns an empty string" do
108 | string = "157046020"
109 | expect(RubyDanfe::Helper.format_cnpj(string)).to eq ""
110 | end
111 | end
112 | end
113 | end
114 |
--------------------------------------------------------------------------------
/spec/lib/options_spec.rb:
--------------------------------------------------------------------------------
1 | require "spec_helper"
2 |
3 | describe RubyDanfe::Options do
4 | it "should return default config set in code" do
5 | options = RubyDanfe::Options.new
6 | expect(options.quantity_decimals).to eq(2)
7 | end
8 |
9 | it "should return config set in params" do
10 | options = RubyDanfe::Options.new({"quantity_decimals" => 4})
11 | expect(options.quantity_decimals).to eq(4)
12 | end
13 | end
14 |
--------------------------------------------------------------------------------
/spec/lib/ruby_danfe_spec.rb:
--------------------------------------------------------------------------------
1 | require "spec_helper"
2 |
3 | describe RubyDanfe do
4 | let(:base_dir) { "./spec/fixtures/"}
5 | let(:output_pdf) { "#{base_dir}output.pdf" }
6 |
7 | before {
8 | File.delete(output_pdf) if File.exist?(output_pdf)
9 | RubyDanfe.options = {"quantity_decimals" => 2}
10 | }
11 |
12 | describe ".generate" do
13 | it "saves the PDF document to file based on a xml file" do
14 | expect(File.exist?(output_pdf)).to be_falsey
15 |
16 | RubyDanfe.generate(output_pdf, "#{base_dir}nfe_with_ns.xml")
17 |
18 | expect("#{base_dir}nfe_with_ns.xml.fixture.pdf").to be_same_file_as(output_pdf)
19 | end
20 | end
21 |
22 | describe ".render" do
23 | it "renders the PDF document to string based on a xml string" do
24 | xml_string = File.new("#{base_dir}nfe_with_ns.xml")
25 |
26 | pdf_string = RubyDanfe.render(xml_string)
27 |
28 | expect(pdf_string).to include '%PDF-1.3'
29 | end
30 | end
31 |
32 | describe ".render_file" do
33 | it "renders the PDF document to file based on a xml string" do
34 | expect(File.exist?(output_pdf)).to be_falsey
35 |
36 | xml_string = File.new("#{base_dir}nfe_with_ns.xml")
37 |
38 | RubyDanfe.render_file(output_pdf, xml_string)
39 |
40 | expect("#{base_dir}nfe_with_ns.xml.fixture.pdf").to be_same_file_as(output_pdf)
41 | end
42 | end
43 | end
44 |
--------------------------------------------------------------------------------
/spec/spec_helper.rb:
--------------------------------------------------------------------------------
1 | require "simplecov"
2 | SimpleCov.start
3 |
4 | require "bundler/setup"
5 | require "ruby_danfe"
6 | require 'rake'
7 |
8 | Bundler.require(:default, :development)
9 | Dir[File.dirname(__FILE__) + "/support/*.rb"].each { |f| require f }
10 |
11 | load File.expand_path("../../Rakefile", __FILE__)
12 | Rake::Task["spec:fixtures:recreate_pdfs"].invoke
13 | # rake spec:fixtures:recreate_pdfs
14 |
15 | RSpec.configure do |config|
16 | config.expect_with :rspec do |c|
17 | c.syntax = :expect
18 | end
19 |
20 | config.order = "random"
21 | end
22 |
--------------------------------------------------------------------------------
/spec/support/be_same_file_as.rb:
--------------------------------------------------------------------------------
1 | RSpec::Matchers.define(:be_same_file_as) do |exected_file_path|
2 | match do |actual_file_path|
3 | expect(md5_hash(actual_file_path)).to eq(md5_hash(exected_file_path))
4 | end
5 |
6 | def md5_hash(file_path)
7 | Digest::MD5.hexdigest(File.read(file_path))
8 | end
9 | end
10 |
--------------------------------------------------------------------------------
/test/cteos.xml:
--------------------------------------------------------------------------------
1 | 33000000185357Prestação de serv. de transp. a não contribuinte671182017-12-04T15:37:35-02:001171001.03301009CAMPOS DOS GOYTACAZESRJ01693301009CAMPOS DOS GOYTACAZESRJ3302403MACAÉRJ2896381700018485105167AUTO VIACAO ESPERANCA LTDAAUTO VIACAO ESPERANCA LTDARUA IVES BAZETTE DOS SANTOS2452GUARUS3301009CAMPOS DOS GOYTACAZES28083485RJ999999999948122295002653FMC- TECHNOLOGIES DO BRASIL LTDA2227370718Rodovia Amaral PeixotoKM187Cabiunas3302403MACAÉ27970020RJ1058Brasil22100.0022100.009090.002210.0020.00442.000.00SERVICO DE TRANSPORTE46.0000000000000000LNW499000778000451RJLCuhPkbUeGfnTyMceIHclO/pvMY=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1RS20171130100518331712289638170001846700100000001810000001872017-12-04T15:37:37-02:00333170022629033LCuhPkbUeGfnTyMceIHclO/pvMY=100Autorizado o uso do CT-e
--------------------------------------------------------------------------------
/test/danfe.xml:
--------------------------------------------------------------------------------
1 | 3580000042RETORNO/INDUSTRIALIZAÇÃO EFETUADA PARA OUTRO ESTABELECIMENTO155120952014-03-12135231071101132.2.2159374918000143TECNOLIGAS INDÚSTRIA E COMÉRCIO DE METAIS LTDATECNOLIGASRUA COBALTO19CORREDOR INDUSTRIAL3523107ItaquaquecetubaSP085861201058BRASIL0114648664437902942011062962452100145581238000196DAISA INDUSTRIA METALURGICA LTDAAV HELIO OSSAMU DAIKUARA1800 BVISTA ALEGRE3515004EmbuSP068070001058BRASIL114704552229800652911702RECUPERACAO DE BORRA DE ALUMINIO (TRANSFORMACAO PARA LINGOTES)760200005124KG3323.00001.25000000004153.75KG3323.00001.2500000000101012.84117.9607699951024153.750.2811.63024153.751.1648.1814RETORNO DE MERCADORIA RECEBIDA PARA TRANSFORMACAO PARA LINGOTES DE ALUMINIO760200005902KG5200.00003.000000000015600.00KG5200.00003.000000000010400076999530808MATERIAL DE VOSSA PROPR. CF NF Nº 026.039 DE 07/03/2014, QUE RETORNAM TRANSFORMADOS EM LINGOTES DE ALUMINIO COM QUEBRA = 1.877 KG.0.000.000.000.0019753.750.000.000.000.000.0011.6348.180.0019753.75159374918000143TECNOLIGAS INDUSTRIA E COMERCIO DE METAIS LTDA379029420110RUA COBALTO, 19ItaquaquecetubaSPA GRANELS/MS/N5200.0005200.00020954153.754153.752095/12014-04-114153.75EMPRESA OPTANTE PELO SIMPLES NACIONAL.bAGJFpwJ1TznKGjrfj3nAV6+pIs=SPGXJgTe1J2XByj2l6MmvtXw9W1J0nAu8tf809v6r/appFbkEGeLcvbW26u53DGCSiWTt9oiUmUH
2 | hph/GNYVN1WVDK55UhpetP7xDd5qHsg0X/vyrUXBoT+IZ0O28FF/Ndwu+hCrB6xYwZCGQmGkRQ7G
3 | TZvMvMjvm74/jAE2XNNGZOc0qHPqn0DnIadMD6aYX4eo/Y9JXpPrSzrR1r47MlHfFPP2VsyoQ6+F
4 | 3XHhNW6yfVdxGbsxVvrgAaX41CgbU7mZZwG63Tx3M3COmwFYRuOpZBugvPGOVmgtooDETv9fcrFS
5 | Kyga49JFCoPuYoF3Ch1XnA3gusvc5Q9GZxSfdA==MIIIZDCCBkygAwIBAgIQHCgWAi5evL0ekPewJ3yeijANBgkqhkiG9w0BAQsFADB4MQswCQYDVQQG
6 | EwJCUjETMBEGA1UEChMKSUNQLUJyYXNpbDE2MDQGA1UECxMtU2VjcmV0YXJpYSBkYSBSZWNlaXRh
7 | IEZlZGVyYWwgZG8gQnJhc2lsIC0gUkZCMRwwGgYDVQQDExNBQyBDZXJ0aXNpZ24gUkZCIEc0MB4X
8 | DTEyMDUxMTAwMDAwMFoXDTE1MDUxMDIzNTk1OVowggEMMQswCQYDVQQGEwJCUjETMBEGA1UEChQK
9 | SUNQLUJyYXNpbDELMAkGA1UECBMCU1AxGDAWBgNVBAcUD0lUQVFVQVFVRUNFVFVCQTE2MDQGA1UE
10 | CxQtU2VjcmV0YXJpYSBkYSBSZWNlaXRhIEZlZGVyYWwgZG8gQnJhc2lsIC0gUkZCMRYwFAYDVQQL
11 | FA1SRkIgZS1DTlBKIEEzMSYwJAYDVQQLFB1BdXRlbnRpY2FkbyBwb3IgQVIgR3VhcnVmb3J0ZTFJ
12 | MEcGA1UEAxNAVEVDTk9MSUdBUyBJTkRVU1RSSUEgRSBDT01FUkNJTyBERSBNRVRBSVMgTFREQSBF
13 | UDo1OTM3NDkxODAwMDE0MzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANmyIeuvBdoj
14 | hMC73wPtiu59bW/u2DplnOv1pl9OkyHrd1+k6uHwsLXjDcf54mEJ9fJtZXvp4iVkHiJ1pCw4BEzx
15 | +PhBdzvix5wMGztlcqk2aN7dQtqr/8L7b6ARDpGIRVZoHUCC+6PwxtIYgA/DSFfAe1fqHBQr4vkD
16 | rEcJGZ/EsyZASsUgkdOkzO9/XlUaCGds1nQ3R1kiSeakglgRG6QMwKIYlgV/N/DYhS/F0Yioa1Go
17 | 16zpo7OaOh1LBgxtLaEbtqWcE3Sd7GMcnSI2qnFshSjOKVj0RNQgFgZVSDofqjvLscLBxkS820qH
18 | O+Mj2Sn8DCY387i4ngxIcydq4gkCAwEAAaOCA1IwggNOMIG3BgNVHREEga8wgaygOAYFYEwBAwSg
19 | LwQtMTUxMDE5NjIwMTI4ODU5MDgzMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwoCMGBWBMAQMC
20 | oBoEGEFHTkFMRE8gQk9ORVRURSBQT0xJRE9SSaAZBgVgTAEDA6AQBA41OTM3NDkxODAwMDE0M6AX
21 | BgVgTAEDB6AOBAwwMDAwMDAwMDAwMDCBF3RlY25vbGlnYXNAdGVycmEuY29tLmJyMAkGA1UdEwQC
22 | MAAwHwYDVR0jBBgwFoAULpHq1m3lslmC3DiFKXY0FlY80D4wDgYDVR0PAQH/BAQDAgXgMH8GA1Ud
23 | IAR4MHYwdAYGYEwBAgMGMGowaAYIKwYBBQUHAgEWXGh0dHA6Ly9pY3AtYnJhc2lsLmNlcnRpc2ln
24 | bi5jb20uYnIvcmVwb3NpdG9yaW8vZHBjL0FDX0NlcnRpc2lnbl9SRkIvRFBDX0FDX0NlcnRpc2ln
25 | bl9SRkIucGRmMIIBFgYDVR0fBIIBDTCCAQkwV6BVoFOGUWh0dHA6Ly9pY3AtYnJhc2lsLmNlcnRp
26 | c2lnbi5jb20uYnIvcmVwb3NpdG9yaW8vbGNyL0FDQ2VydGlzaWduUkZCRzQvTGF0ZXN0Q1JMLmNy
27 | bDBWoFSgUoZQaHR0cDovL2ljcC1icmFzaWwub3V0cmFsY3IuY29tLmJyL3JlcG9zaXRvcmlvL2xj
28 | ci9BQ0NlcnRpc2lnblJGQkc0L0xhdGVzdENSTC5jcmwwVqBUoFKGUGh0dHA6Ly9yZXBvc2l0b3Jp
29 | by5pY3BicmFzaWwuZ292LmJyL2xjci9DZXJ0aXNpZ24vQUNDZXJ0aXNpZ25SRkJHNC9MYXRlc3RD
30 | UkwuY3JsMB0GA1UdJQQWMBQGCCsGAQUFBwMCBggrBgEFBQcDBDCBmwYIKwYBBQUHAQEEgY4wgYsw
31 | XwYIKwYBBQUHMAKGU2h0dHA6Ly9pY3AtYnJhc2lsLmNlcnRpc2lnbi5jb20uYnIvcmVwb3NpdG9y
32 | aW8vY2VydGlmaWNhZG9zL0FDX0NlcnRpc2lnbl9SRkJfRzQucDdjMCgGCCsGAQUFBzABhhxodHRw
33 | Oi8vb2NzcC5jZXJ0aXNpZ24uY29tLmJyMA0GCSqGSIb3DQEBCwUAA4ICAQDPdVSjPZ7tdTx4pCHV
34 | OOmbEJ5PP5RkTvZ1FCspjJ5jNSNqrGAp/dm19OeTg0rBeqZ+SJgA6TuinpgtGL+vwtMquDGeLLef
35 | n7Df/OKtrLJkfK+vfTpK6MuJBahmI8nyHv5ouoSBEpJ8byDo1a+OSgXAaYsBasC0I3shpdLdzZ1h
36 | k35x6kUlEirQyHMtbxlOAw+HfzQmv+1qOZpt3ElbC1CtR1Bun56JC5YuiOAd03OhJP01JAnzw5Ze
37 | XnAfmEQh35310+PLTnJAD8mdPNMXdZAXBhIspyDMy/gM2ou5R/9k5coK2fTcwjqH0atL9ezGnBqB
38 | vH9txy8ArcdWrosjLuNrbOq4fqrK8PjUZKVptBYMh4nEMwf8uI2ega1E+0TEwIFx7TnVvUR3U3DO
39 | u2Zl/U+9Pc16LBRAubafO68PnGn9IeEgLE5dL1mkG34lHxhU4oLF7q631divGR4B5DIA/UjhiRnJ
40 | nsGL+STa2q3i5sOMfuhhhr3UIVg/xkbeFZHx+NK/1BJe1/eDmiK4eofAYVCzhb1yRHWotDJMQ6yq
41 | dVvIdpia77H57h02bwtd0YoQ8yC8daVH0roZONE2klI55XrThX7GV372Vm/K03anTZS9KKDpzXMu
42 | THTsT17MV8IxuMX21LRkitKSO4Y6l+C6Y09bT/MX/rQSBNopxtLgBPu8iQ==1SP_NFE_PL_006q351403593749180001435500100000209518000004202014-03-12T10:41:31135140152647164bAGJFpwJ1TznKGjrfj3nAV6+pIs=100Autorizado o uso da NF-e
--------------------------------------------------------------------------------
/test/generate.rb:
--------------------------------------------------------------------------------
1 | require "../lib/ruby_danfe"
2 |
3 | if ARGV.size == 0
4 | puts "Usage: generate.rb "
5 | exit(1)
6 | end
7 |
8 | type = (ARGV[1] || "danfe").to_sym
9 |
10 | RubyDanfe.generate("#{ARGV[0]}.pdf", ARGV[0], type)
11 |
--------------------------------------------------------------------------------
/test/generate_nfce.rb:
--------------------------------------------------------------------------------
1 | require "../lib/ruby_danfe"
2 |
3 | if ARGV.size == 0
4 | puts "Usage: generate.rb "
5 | exit(1)
6 | end
7 |
8 | RubyDanfe.generate("nfce.pdf", ARGV[0], :danfe_nfce)
--------------------------------------------------------------------------------
/test/nfce.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | 13
6 | 59290096
7 | VENDA DE MERCADORIA
8 | 0
9 | 65
10 | 2
11 | 639
12 | 2013-11-29T16:29:02-04:00
13 | 1
14 | 1
15 | 1302603
16 | 4
17 | 1
18 | 8
19 | 1
20 | 1
21 | 1
22 | 1
23 | 0
24 | ATXOne - 1.0.0.22
25 |
26 |
27 | 02547812000112
28 | EMPRESA DE TESTE
29 | TRES ELEFANTES
30 |
31 | AV CORONEL TEIXEIRA
32 | 5705
33 | LOJA 83/84.1 1 PISO SHOPPING PONTA NEGRA
34 | Ponta Negra
35 | 1302603
36 | MANAUS
37 | AM
38 | 69037000
39 | 1058
40 | BRASIL
41 | 9236677413
42 |
43 | 053429737
44 | 1
45 |
46 |
47 |
48 | 940
49 | 9000000009400
50 | BRINCO VANIA VARIADOS 10
51 | 71171900
52 | 5102
53 | UN
54 | 1.0000
55 | 15.9000000000
56 | 15.90
57 | 9000000009400
58 | UN
59 | 1.0000
60 | 15.9000000000
61 | 1
62 |
63 |
64 |
65 |
66 | 2
67 | 102
68 |
69 |
70 |
71 |
72 | 01
73 | 0.00
74 | 0.00
75 | 0.00
76 |
77 |
78 |
79 |
80 | 01
81 | 0.00
82 | 0.00
83 | 0.00
84 |
85 |
86 |
87 |
88 |
89 |
90 | 0.00
91 | 0.00
92 | 0.00
93 | 0.00
94 | 15.90
95 | 0.00
96 | 0.00
97 | 0.00
98 | 0.00
99 | 0.00
100 | 0.00
101 | 0.00
102 | 0.00
103 | 15.90
104 |
105 |
106 |
107 | 9
108 |
109 |
110 | 01
111 | 15.90
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 | ajtb/i2P6/vr/TT8rbul0os5JZQ=
125 |
126 |
127 | I/TFfNRId9s4ge2d/fp4Lfl3Txb9X4OArxF5LLyLYnuLmvEJL5ALCf85a1jnJUhxVAJzT+pVD0QuMt/VZKhaVUOmE0ZOmv/yxp9J+aQnioig54z444zpwEhc037+fh3EKVelb4dNiD6tHLjf7rykA6p+gZ7JrKKLcAttdQWr40Ei0/tWPnZ4SsDM/G3EdrKRuNlmERbJRTc3+8zhN2n3Tz5stFl1ExGUVJgXUOqKO8h+4rtclWlk9w6K7ZnFE420kjzSuPW4CBz4glZ3EVJk7bOeFRbuaOBH7G/r1zAaSKc80rK7hHcw8cskHf7JXc0rYHTHA65CgdapPeOSLBhhbw==
128 |
129 |
130 | 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
131 |
132 |
133 |
134 |
135 |
136 |
137 | 1
138 | AM2.00
139 | NFe131311188353120001806500200000063915929078898
140 | 2013-11-29T16:29:00
141 | 113130105846418
142 | ajtb/i2P6/vr/TT8rbul0os5JZQ=
143 | 100
144 | Autorizado o uso da NF-e
145 |
146 |
147 |
--------------------------------------------------------------------------------
/test/nfe_simples_nacional.xml:
--------------------------------------------------------------------------------
1 | 35000000016101-Venda de producao do estabelecimento155112013-12-2813550308116110160891033000109KRON INSTRUMENTOS ELETRICOS LTDAKRON INSTRUMENTOS ELETRICOS LTDARUA ALEXANDRE DE GUSMAO278SOCORRO3550308SAO PAULOSP047600201058BRASIL1155252000111393871117182743287000880Schneider Electric Brasil LtdaAv da Saudade1125Frutal3552403SUMARESP131713201058BRASIL19210463006710083751101Tijolo Macico Tipo A69041000006101MI2.000010.000000000020.00MI2.000010.000000000015.350102990.000.000.00990.000.000.002Tijolo Macico Tipo B69041000006101MI3.000020.000000000060.00MI3.000020.0000000000116.050102990.000.000.00990.000.000.003Tijolo Macico Tipo C69041000006101MI4.000030.0000000000120.00MI4.000030.0000000000132.100102990.000.000.00990.000.000.000.000.000.000.00200.000.000.000.000.000.000.000.000.00200.0053.500112014-01-2740.0022014-02-2640.0032014-03-2840.0042014-04-2740.0052014-05-2740.00DOCUMENTO EMITIDO POR ME OU EPP OPTANTE PELO SIMPLES NACIONAL * NAO GERA DIREITO A CREDITO FISCAL DE IPI * Tributos: R$ 53,50 (26,75%)
2 |
--------------------------------------------------------------------------------
/test/nfe_with_fci.xml:
--------------------------------------------------------------------------------
1 | 3563472050VENDA DE PRODUCAO DO ESTABELECIMENTO1551445252013-10-18135503081151105.060891033000109KRON INSTRUMENTOS ELETRICOS LTDAKRONRUA ALEXANDRE DE GUSMAO278SOCORRO3550308SAO PAULOSP047600201058BRASIL1155252000111393871117382743287000880SCHNEIDER ELECTRIC BRASIL LTDAAV. DA SAUDADE1125FRUTAL3552403SUMARESP131713201058BRASIL1921046300671008375110nfemerc.sumare@br.schneider-electric.comF211130101000AMPERIMETRO FM72PC 300/5A COD 3491192843 RL90303329005101PC1.0049.2349.23PC1.0049.231980019211012232531-74B2-4FDD-87A6-CF0AD3E55386500349.2312.005.909995049.235.002.460149.230.650.320149.233.001.4849.235.900.000.0049.230.000.000.000.002.460.321.480.0051.69050547058000128POST MASTER COMERCIAL LTDA111768652113RUA VIEIRA DE MORAES 558SAO PAULOSP1CAIXAKRON11.0001.0000044525/012013-12-1751.69FRETE CIF / INDUSTRIALIZACAO PEDIDO 98001921 VENC. DAS DUPLICATAS 01/ 10 / 20 DO MES - VIA DEPOSITO [EMAIL=nfemerc.sumare@br.schneider-electric.com]98001921dndW1koiOiYKZkXf7cWtg5vfL2Y=JXN6WtG/sLQgtEI0n0BhajaphVDAX99A+QcrC3XxTkP4vZ/yHpwr2ngvs3t0M1uLECymakCxjT/qMmanJDiaAGxfWmBJkdgDFa80zJ2RoS9RqF48QmNXHfDNtjwwgw12RlFC8reLWGw7qXD9Nre5E9bTWJqEH4RHhKcg/akiWsQ2uy6M2O/m3IgznCG6wMnhaE98BbXTqcHLrvRignT86HQssaV6DDVm2kXyL1FM8YMZF3TtbsMQ8PJs70FrwddVzFIPoYxSq7iBw40ZdveuexYApVYJdyUssBZcxnlWtaS9aOWpd1fqHiQy5fKRRycBwOdMEPcQXGKqkNUs1hlUtg==MIIIQjCCBiqgAwIBAgIQdHnQdADNdDiHWqCYm1mh6zANBgkqhkiG9w0BAQsFADB4MQswCQYDVQQGEwJCUjETMBEGA1UEChMKSUNQLUJyYXNpbDE2MDQGA1UECxMtU2VjcmV0YXJpYSBkYSBSZWNlaXRhIEZlZGVyYWwgZG8gQnJhc2lsIC0gUkZCMRwwGgYDVQQDExNBQyBDZXJ0aXNpZ24gUkZCIEc0MB4XDTEzMDIyNTAwMDAwMFoXDTE0MDIyNDIzNTk1OVowgfExCzAJBgNVBAYTAkJSMRMwEQYDVQQKFApJQ1AtQnJhc2lsMQswCQYDVQQIEwJTUDESMBAGA1UEBxQJU0FPIFBBVUxPMTYwNAYDVQQLFC1TZWNyZXRhcmlhIGRhIFJlY2VpdGEgRmVkZXJhbCBkbyBCcmFzaWwgLSBSRkIxFjAUBgNVBAsUDVJGQiBlLUNOUEogQTExIjAgBgNVBAsUGUF1dGVudGljYWRvIHBvciBBUiBGQUNFU1AxODA2BgNVBAMTL0tST04gSU5TVFJVTUVOVE9TIEVMRVRSSUNPUyBMVERBOjYwODkxMDMzMDAwMTA5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAs7JenW0yMGg/bzp+ByFBjxG2nxE9DvzegNzr9NzH+ob+9nCm2iCDaB12dytrPD9aJYXE9Y4AcO+R8a5iUkTaGS4fGAfT11JSNyFLmatR+Z5AJZZ4j0N6g5moRWxOShPjoqxPf43IpAFwQrb2AhWi+wrTtwbS89jvVonGQvEdQsS1zkzX7KWvvy2bFcUCupvXd+TP0aIdyi2XjCkpGT0j3T1qvZrz2WnbhWW4VqZVfXiVZyYhijgbi+IO7s5wrYVTJCZtNvoffRsmGh+aTTlGgapjatWN+3u+M885Y4umFBqEmGgWxoidO1xXiURYhkLF5w2wlxJlwcC0qsF2wpuPOwIDAQABo4IDTDCCA0gwgbEGA1UdEQSBqTCBpqA4BgVgTAEDBKAvBC0yOTA3MTk1NTAxMjU1MzE4ODU2MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDCgJQYFYEwBAwKgHAQaRkVSTkFORE8gTUFSQ0hFVFRJIEJFRElDS1OgGQYFYEwBAwOgEAQONjA4OTEwMzMwMDAxMDmgFwYFYEwBAwegDgQMMDAwMDAwMDAwMDAwgQ9jcGRAa3Jvbi5jb20uYnIwCQYDVR0TBAIwADAfBgNVHSMEGDAWgBQukerWbeWyWYLcOIUpdjQWVjzQPjAOBgNVHQ8BAf8EBAMCBeAwfwYDVR0gBHgwdjB0BgZgTAECAQwwajBoBggrBgEFBQcCARZcaHR0cDovL2ljcC1icmFzaWwuY2VydGlzaWduLmNvbS5ici9yZXBvc2l0b3Jpby9kcGMvQUNfQ2VydGlzaWduX1JGQi9EUENfQUNfQ2VydGlzaWduX1JGQi5wZGYwggEWBgNVHR8EggENMIIBCTBXoFWgU4ZRaHR0cDovL2ljcC1icmFzaWwuY2VydGlzaWduLmNvbS5ici9yZXBvc2l0b3Jpby9sY3IvQUNDZXJ0aXNpZ25SRkJHNC9MYXRlc3RDUkwuY3JsMFagVKBShlBodHRwOi8vaWNwLWJyYXNpbC5vdXRyYWxjci5jb20uYnIvcmVwb3NpdG9yaW8vbGNyL0FDQ2VydGlzaWduUkZCRzQvTGF0ZXN0Q1JMLmNybDBWoFSgUoZQaHR0cDovL3JlcG9zaXRvcmlvLmljcGJyYXNpbC5nb3YuYnIvbGNyL0NlcnRpc2lnbi9BQ0NlcnRpc2lnblJGQkc0L0xhdGVzdENSTC5jcmwwHQYDVR0lBBYwFAYIKwYBBQUHAwIGCCsGAQUFBwMEMIGbBggrBgEFBQcBAQSBjjCBizBfBggrBgEFBQcwAoZTaHR0cDovL2ljcC1icmFzaWwuY2VydGlzaWduLmNvbS5ici9yZXBvc2l0b3Jpby9jZXJ0aWZpY2Fkb3MvQUNfQ2VydGlzaWduX1JGQl9HNC5wN2MwKAYIKwYBBQUHMAGGHGh0dHA6Ly9vY3NwLmNlcnRpc2lnbi5jb20uYnIwDQYJKoZIhvcNAQELBQADggIBAK22zXyUD+FxXBLcP99DfElExHg7a8ZIqCNQs58pG5xR5rNYib46z6tGmEsWCbgViagokqdyQmLNAfE/t1UqOdu4dxMoQM2m5O3Nk/PDOaVVe5y93dFBOr5xMQsfQFtcHbWO0QTeJdG0Uh0LxhRVriPH9JmvAMPUjUl9W/+/hIjohh/zVDyX8WfBKRvVqn/RbFaBSyoYiLDBQWZ4FecrcqX/IXViSDM4d6jFS7+6OSFHgxzl08M4zAqaaSD51IQ3N9fcdhTolVAgHSNNMou88eJaRhbMGtX5qciiUbDTgaX69VbPWeSKtA3TpHKMvNidZTfhhu8X/MxqztTpEEUrKfxRLkIUdVkho3a2/GfD3ePcy7k+Zexu2u1vTkXSGXKDvrJkowOXI11Xob6CP6ZNCCaftdQ+8WA+kZpthjILhY6G7jYy20OFiPTPLwC70funz+wkAB2upX7fMkxctTuAEEbecwcshJS4IgOJCOWPjuOFVMrCOKi1xgPZTxmmHZ9JcVik2Z7JlwV2r+j2sjAYYCFExipw2PmbTDtSL3worhASMsllWYaSmGM524aPEWXiemR0zfKEUuS5wDBdFJrsZkjJDIFJs0AmP2rXf2ftoN73g/ap2ycqbgpt5NYBhhN1az9sc/n6062WatrXVrj94Vx8j+8j6L42Qwx+PrB9Fzrr1SP_NFE_PL_006q351310608910330001095500100004452516347205052013-10-18T13:54:04135130636167763dndW1koiOiYKZkXf7cWtg5vfL2Y=100Autorizado o uso da NF-e
2 |
--------------------------------------------------------------------------------
/test/nfe_with_ns.xml:
--------------------------------------------------------------------------------
1 | 2500013415Vendas de producao do estabelecimento1552134152011-10-292011-10-2912507507111110Integrat12345678901234ACME SAACME-PBRUA HORTENCIO RIBEIRO DE LUNA3333DISTRITO INDUSTRIAL2507507Joao PessoaPB580814001058BRASIL8321062200160158257398765432101234EDITORA BLEBLEBLE LTDARUA URBANO SANTOS, N755 (ANT 160)0CUMBICA3518800GuarulhosSP071823201058BRASIL1127901347336322171116
2 | 00005LIVRO POR LIT GRAMATICA PROD TEXTO 3a SERIE ALUNO490199006101UN28080.00003.9400110635.20UN28080.00003.9400100030.000.000.00010.000.000.00010.000.000.00
3 | 00005LIVRO POR LIT GRAMATICA PROD TEXTO 3a SERIE ALUNO490199006101UN28080.00003.9400110635.20UN28080.00003.940010202456.00100.00479.8217.0029.28010.000.000.00010.000.000.00
4 | 0.000.00479.820.00110635.200.000.000.000.000.000.000.000.00110635.20010849477000108TRANSPRINT - TRANSPORTADORA E LOGISTICA LTDA148613972111Rua do TatuapeSAO PAULOSP00000000SP00000026VOLUMES(s)DIVERSOS025000.00025000.00013415//1110635.20110635.2013415//1-12012-02-26110635.20Obs: PEDIDO DE COMPRA: 308.996 MATERIAL IMUNE CONFORME ART.150 INCISO VI ALINEA D DA CONSTITUICAO FEDERAL.9jeTTSaza8lMT2Xk5hbWx86Fbp4=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1SVRS20110801092042251110123456789012345500200001341510001341512011-10-29T14:37:093251100128663209jeTTSaza8lMT2Xk5hbWx86Fbp4=100Autorizado o uso da NF-e
5 |
--------------------------------------------------------------------------------
/test/nfe_without_ns.xml:
--------------------------------------------------------------------------------
1 |
2 | 3191136050REMESSA MERC. P/ CONSERTO055100121182013-02-22131186011171105.099984626000136ACME SAACMEVIA EXPRESSA DE CONTAGEM3850CINCAO3118601CONTAGEMMG323704851058BRASIL31339966001862422430000398765432101234BLABLABLA LTDAAV. MARGINAL DO RIB. DOS CRISTAIS200JORDANESIA3509205CAJAMARSP077600001058BRASIL3130698013241029868119F-MERCPCMONITOR DE ARCO ELETRICO COD:1-VAMP2213A3AAA NS: V221-00663085369090006915pc1.004491.254491.25pc1.004491.25109030.000.000.0040.000.000.00999510707F-MERCPCDETECTOR FALHA ISOLAMENTO COD:1-XD312127-01 NS: 1518385V185369090006915pc1.001588.701588.70pc1.001588.70109030.000.000.0040.000.000.00999510707F-MERCPCMONITOR DE ARCO ELETRICO COD:1-VAMP2213A3AAA NS: V221-00682485369090006915pc1.004038.754038.75pc1.004038.75109030.000.000.0040.000.000.009995107070.000.000.000.0010118.700.000.000.000.000.000.000.000.0010118.70020147617000141JAMEF TRANSPORTADORA LTDA0624426220024RUA DR JOSE AMERICO CANCADO BAHIA 1810CONTAGEMMG2.10.00010.000MATERIAL DE NOSSA PROPRIEDADE QUE SEGUE PARA REPAROS, DEVENDO RETORNAR AO NOSSO ESTABELECIMENTO. **** ICMS SUSPENSO CONF.ART.19 ITEM 1 ANEXO III DEC.43080 IPI SUSPENSO CONF.ART.42 INCISO XIII DEC.4544 DEZ/02 ROMA-491 | Cod.Repart.Fiscal: 00001CAmkmMtOyPC1hfWU/LLGQUdAZ6Q=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113_0_61311302123456789012345510000001211819113605072013-02-22T09:32:54131131006404486CAmkmMtOyPC1hfWU/LLGQUdAZ6Q=100Autorizado o uso da NF-e
--------------------------------------------------------------------------------