br_danfe 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (55) hide show
  1. checksums.yaml +15 -0
  2. data/.gitignore +7 -0
  3. data/.rspec +1 -0
  4. data/.travis.yml +8 -0
  5. data/Gemfile +5 -0
  6. data/README.md +116 -0
  7. data/Rakefile +39 -0
  8. data/br_danfe.gemspec +27 -0
  9. data/config/locales/pt-BR.yml +125 -0
  10. data/lib/br_danfe.rb +12 -0
  11. data/lib/br_danfe/cep.rb +7 -0
  12. data/lib/br_danfe/cnpj.rb +7 -0
  13. data/lib/br_danfe/cpf.rb +7 -0
  14. data/lib/br_danfe/cst.rb +28 -0
  15. data/lib/br_danfe/danfe_generator.rb +54 -0
  16. data/lib/br_danfe/dest.rb +21 -0
  17. data/lib/br_danfe/det.rb +69 -0
  18. data/lib/br_danfe/document.rb +103 -0
  19. data/lib/br_danfe/dup.rb +25 -0
  20. data/lib/br_danfe/emit.rb +45 -0
  21. data/lib/br_danfe/helper.rb +38 -0
  22. data/lib/br_danfe/icmstot.rb +19 -0
  23. data/lib/br_danfe/ie.rb +68 -0
  24. data/lib/br_danfe/infadic.rb +53 -0
  25. data/lib/br_danfe/issqn.rb +12 -0
  26. data/lib/br_danfe/options.rb +22 -0
  27. data/lib/br_danfe/phone.rb +11 -0
  28. data/lib/br_danfe/plate.rb +7 -0
  29. data/lib/br_danfe/ruby_danfe.rb +42 -0
  30. data/lib/br_danfe/ticket.rb +10 -0
  31. data/lib/br_danfe/transp.rb +18 -0
  32. data/lib/br_danfe/version.rb +3 -0
  33. data/lib/br_danfe/vol.rb +23 -0
  34. data/lib/br_danfe/xml.rb +32 -0
  35. data/lib/br_danfe/xprod.rb +41 -0
  36. data/spec/features/ruby_danfe_spec.rb +48 -0
  37. data/spec/fixtures/nfe_simples_nacional.xml +1 -0
  38. data/spec/fixtures/nfe_with_extra_volumes.xml +4 -0
  39. data/spec/fixtures/nfe_with_fci.xml +1 -0
  40. data/spec/fixtures/nfe_with_ns.xml +4 -0
  41. data/spec/fixtures/nfe_without_ns.xml +2 -0
  42. data/spec/lib/cep_spec.rb +10 -0
  43. data/spec/lib/cnpj_spec.rb +10 -0
  44. data/spec/lib/cpf_spec.rb +10 -0
  45. data/spec/lib/cst_spec.rb +51 -0
  46. data/spec/lib/helper_spec.rb +84 -0
  47. data/spec/lib/ie_spec.rb +230 -0
  48. data/spec/lib/options_spec.rb +13 -0
  49. data/spec/lib/phone_spec.rb +19 -0
  50. data/spec/lib/plate_spec.rb +10 -0
  51. data/spec/lib/ruby_danfe_spec.rb +40 -0
  52. data/spec/lib/xprod_spec.rb +124 -0
  53. data/spec/spec_helper.rb +17 -0
  54. data/spec/support/be_same_file_as.rb +9 -0
  55. metadata +223 -0
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ N2U5NDM0ZjY5YWVmMGFjYjk2M2JhZGE3NzBjNDcyODc0ZjcxYmQyNg==
5
+ data.tar.gz: !binary |-
6
+ MTJkNDIyMWMzYWJjMjVlNzQ0ODdmNmZlZDI4MDM5OWM2MTQ1NDQ0Mg==
7
+ !binary "U0hBNTEy":
8
+ metadata.gz: !binary |-
9
+ NThlMmQ2NmMxZjQ3NDgxYzkzNzU2MjkwMTE3MDE0OWE3M2Q1NzU3YzAzNThh
10
+ YmFhMjEyZDVjOTQzMzQ1NzY5NDQ0ZjgxMDQzNDg5NzdlNGFhMmE1OGIyYjFl
11
+ MmJkNTMxYzAyMzM2YWUzMWZhYTI3MWQ1ZDU1N2FkYjY0MjA4ZjY=
12
+ data.tar.gz: !binary |-
13
+ MzljOWMyYTQ4YjIzMjM5M2YzNTczZjgyZTE1YmIwYmE5MDA2NTZiN2YzMGY1
14
+ NjY2NTQ5ZDhjODlmNmZjYzM0NDM4MDE2ZDY4ODczMjQ2NGRiZjEwNWMxY2Nh
15
+ NWQ5ODRmNjVlNGNjZjViYTZiNzI5ZTE2MzA3YjlhNTYzZTQwZjE=
@@ -0,0 +1,7 @@
1
+ .idea
2
+ .DS_store
3
+ *sublime-*
4
+ Gemfile.lock
5
+ pkg
6
+ *.pdf
7
+ coverage
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color --format documentation --order rand
@@ -0,0 +1,8 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.9.3
4
+ - 2.0.0
5
+ - 2.1.0
6
+ - jruby-19mode
7
+ gemfile:
8
+ - Gemfile
data/Gemfile ADDED
@@ -0,0 +1,5 @@
1
+ source "http://rubygems.org"
2
+
3
+ gemspec
4
+
5
+ gem "rake"
@@ -0,0 +1,116 @@
1
+ # BrDanfe
2
+
3
+ [![Code Climate](https://codeclimate.com/github/asseinfo/br_danfe.png)](https://codeclimate.com/github/asseinfo/br_danfe) [![Build Status](https://travis-ci.org/asseinfo/br_danfe.png?branch=master)](https://travis-ci.org/asseinfo/br_danfe)
4
+
5
+ This gem generates PDF files for Brazilian DANFE (_Documento Auxiliar da Nota Fiscal Eletrônica_) from a valid NF-e XML.
6
+
7
+ This gem requires `ruby >= 1.9.x`.
8
+
9
+ It's a fork of [Ruby DANFE](http://github.com/taxweb/ruby_danfe) project.
10
+
11
+ The difference is that this project doesn't support DACTE (_Documento Auxiliar do Conhecimento de Transporte Eletrônico_) or NFC-e (_Nota Fiscal do Consumidor Eletrônica_). It's only focused on DANFE.
12
+
13
+ ## Installing
14
+
15
+ gem install ruby_danfe
16
+
17
+ ## Usage
18
+
19
+ If you have the xml saved in a file:
20
+
21
+ require "br_danfe"
22
+ BrDanfe.generate("sample.pdf", "sample.xml")
23
+
24
+ If you have the xml in a variable:
25
+
26
+ xml = BrDanfe::XML.new(my_xml_string)
27
+ pdf = BrDanfe.generatePDF(xml)
28
+ pdf.render_file "output.pdf"
29
+
30
+ ## I18n
31
+
32
+ By default, your rails application must be configured to `pt-Br`.
33
+
34
+ If you need to customize some message or field label, you can override the content of pt-Br.yml file.
35
+
36
+ ## Development
37
+
38
+ ### Installing dependencies
39
+
40
+ You can install all necessaries dependencies using bunder like above:
41
+
42
+ $ bundle install
43
+
44
+ ### Tests
45
+
46
+ #### Manual tests
47
+
48
+ You can use it following the steps above:
49
+
50
+ $ rake pdf_from["spec/fixtures/nfe_with_ns.xml","./output.pdf"]
51
+
52
+ You can also use an special version of irb with all classes pre-loaded. Just use:
53
+
54
+ $ rake console
55
+ I18n.locale = "pt-BR"
56
+ BrDanfe.generate("output.pdf", "test/nfe_with_ns.xml")
57
+
58
+ or
59
+
60
+ $ rake console
61
+
62
+ I18n.locale = "pt-BR"
63
+
64
+ my_xml_string = ""
65
+ file = File.new("test/nfe_with_ns.xml", "r")
66
+ while (line = file.gets)
67
+ my_xml_string = my_xml_string + line
68
+ end
69
+ file.close
70
+
71
+ xml = BrDanfe::XML.new(my_xml_string)
72
+ pdf = BrDanfe.generatePDF(xml)
73
+
74
+ pdf.render_file "output.pdf"
75
+
76
+ #### Automated tests with RSpec
77
+
78
+ You can run all specs using:
79
+
80
+ $ rspec
81
+
82
+ In the `spec/fixtures` folder, you are going to find some xml files. Each one represent a different NF-e context.
83
+
84
+ Each xml file must have its respective pdf file.
85
+
86
+ If you did some change that caused general visual changes at output pdfs, so you have to rebuild all fixtures pdf files.
87
+
88
+ You can do this automagically running the following taks:
89
+
90
+ $ rake spec:fixtures:recreate_pdfs
91
+
92
+ #### Code coverage
93
+
94
+ Code coverage is available through of SimpleCov. Just run `rspec` and open the coverage report in your browser.
95
+
96
+ ### Building and publishing
97
+
98
+ You can build using one of the above tasks
99
+
100
+ $ rake build # Build br_danfe-X.X.X.gem into the pkg directory
101
+ $ rake install # Build and install br_danfe-X.X.X.gem into system gems
102
+ $ rake release # Create tag vX.X.X and build and push br_danfe-X.X.X.gem to Rubygems
103
+
104
+ ## Contributing
105
+
106
+ We encourage you to contribute to BrDanfe!
107
+
108
+ 1. Fork it
109
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
110
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
111
+ 4. Push to the branch (`git push origin my-new-feature`)
112
+ 5. Create new Pull Request
113
+
114
+ ## License
115
+
116
+ BrDanfe is released under the [MIT License](http://www.opensource.org/licenses/MIT).
@@ -0,0 +1,39 @@
1
+ require "rspec/core/rake_task"
2
+ require "bundler/gem_tasks"
3
+ require "br_danfe"
4
+
5
+ task default: :spec
6
+ RSpec::Core::RakeTask.new
7
+
8
+ I18n.locale = "pt-BR"
9
+
10
+ desc "Open an irb session preloaded BrDanfe classes"
11
+ task :console do
12
+ sh "irb -rubygems -I lib -r br_danfe.rb"
13
+ end
14
+
15
+ desc "Generate a pdf from a xml file"
16
+ task :pdf_from, :source_xml, :target_pdf do |t, args|
17
+ xml_file = args[:source_xml]
18
+ pdf_file = args[:target_pdf] || xml_file + ".pdf"
19
+
20
+ puts "\n\n\n"
21
+ puts "Reading #{xml_file}"
22
+ puts "Creating #{pdf_file}"
23
+
24
+ BrDanfe.generate("#{pdf_file}", "#{xml_file}")
25
+
26
+ puts "File #{pdf_file} created successfully\n\n\n"
27
+ end
28
+
29
+ namespace :spec do
30
+ namespace :fixtures do
31
+ desc "Recreate all pdfs fixtures. Use this task always that output pdf format is changed."
32
+ task :recreate_pdfs do
33
+ Dir["spec/fixtures/nfe*.xml"].each do |f|
34
+ puts "Recreating #{f}.fixture.pdf"
35
+ BrDanfe.generate("#{f}.fixture.pdf", "#{f}")
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,27 @@
1
+ # coding: utf-8
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "br_danfe/version"
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = "br_danfe"
7
+ spec.version = BrDanfe::VERSION
8
+ spec.summary = "DANFE pdf generator for Brazilian invoices."
9
+ spec.author = "ASSEINFO"
10
+ spec.email = "asseinfo@asseinfo.com.br"
11
+ spec.homepage = "http://github.com/asseinfo/br_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
+ spec.add_dependency "nokogiri"
20
+ spec.add_dependency "prawn"
21
+ spec.add_dependency "barby"
22
+ spec.add_dependency "i18n"
23
+
24
+ spec.add_development_dependency "pry"
25
+ spec.add_development_dependency "rspec"
26
+ spec.add_development_dependency "simplecov"
27
+ end
@@ -0,0 +1,125 @@
1
+ pt-BR:
2
+ danfe:
3
+ chNFe: "CHAVE DE ACESSO"
4
+ infProt: "PROTOCOLO DE AUTORIZAÇÃO DE USO"
5
+ others:
6
+ without_fiscal_value: "SEM VALOR FISCAL"
7
+ page: "FOLHA %{current} de %{total}"
8
+ danfe: "DOCUMENTO AUXILIAR DA NOTA FISCAL ELETRÔNICA"
9
+ sefaz: "Consulta de autenticidade no portal nacional da NF-e www.nfe.fazenda.gov.br/portal ou no site da Sefaz Autorizadora"
10
+ ide:
11
+ dEmi: "DATA DA EMISSÃO"
12
+ dSaiEnt: "DATA DA SAÍDA/ENTRADA"
13
+ hSaiEnt: "HORA DE SAÍDA"
14
+ tpNF:
15
+ entry: "ENTRADA"
16
+ departure: "SAÍDA"
17
+ document: "N°. %{nNF}\nSÉRIE %{serie}"
18
+ natOp: "NATUREZA DA OPERAÇÃO"
19
+ dest:
20
+ title: "DESTINATÁRIO / REMETENTE"
21
+ xNome: "NOME/RAZÃO SOCIAL"
22
+ CNPJ: "CNPJ/CPF"
23
+ CPF: "CNPJ/CPF"
24
+ IE: "INSCRIÇÃO ESTADUAL"
25
+ enderDest:
26
+ UF: "UF"
27
+ xLgr: "ENDEREÇO"
28
+ xBairro: "BAIRRO"
29
+ CEP: "CEP"
30
+ xMun: "MUNICÍPIO"
31
+ fone: "FONE/FAX"
32
+ emit:
33
+ IM: "INSCRIÇÃO MUNICIPAL"
34
+ IE: "INSCRIÇÃO ESTADUAL"
35
+ IE_ST: "INSC.ESTADUAL DO SUBST. TRIBUTÁRIO"
36
+ CNPJ: "CNPJ"
37
+ dup:
38
+ title: "FATURA / DUPLICATAS"
39
+ nDup: "Núm.:"
40
+ vDup: "Valor: R$"
41
+ dVenc: "Venc.:"
42
+ ICMSTot:
43
+ title: "CÁLCULO DO IMPOSTO"
44
+ vBC: "BASE DE CÁLCULO DO ICMS"
45
+ vICMS: "VALOR DO ICMS"
46
+ vBCST: "BASE DE CÁLCULO DO ICMS ST"
47
+ vST: "VALOR DO ICMS ST"
48
+ vProd: "VALOR TOTAL DOS PRODUTOS"
49
+ vFrete: "VALOR DO FRETE"
50
+ vSeg: "VALOR DO SEGURO"
51
+ vDesc: "DESCONTO"
52
+ vOutro: "OUTRAS DESPESAS ACESSORIAS"
53
+ vIPI: "VALOR DO IPI"
54
+ vNF: "VALOR TOTAL DA NOTA"
55
+ transporta:
56
+ title: "TRANSPORTADOR / VOLUMES TRANSPORTADOS"
57
+ xNome: "RAZÃO SOCIAL"
58
+ CNPJ: "CNPJ/CPF"
59
+ xEnder: "ENDEREÇO"
60
+ xMun: "MUNICÍPIO"
61
+ UF: "UF"
62
+ IE: "INSCRIÇÂO ESTADUAL"
63
+ transp:
64
+ modFrete:
65
+ title: "FRETE POR CONTA"
66
+ emitter: "0 - EMITENTE"
67
+ recipient: "1 - DEST."
68
+ third_party: "2 - TERCEIROS"
69
+ no_freight: "9 - SEM FRETE"
70
+ veicTransp:
71
+ RNTC: "CODIGO ANTT"
72
+ placa: "PLACA DO VEÍCULO"
73
+ UF: "UF"
74
+ vol:
75
+ qVol: "QUANTIDADE"
76
+ esp: "ESPÉCIE"
77
+ marca: "MARCA"
78
+ nVol: "NUMERAÇÃO"
79
+ pesoB: "PESO BRUTO"
80
+ pesoL: "PESO LÍQUIDO"
81
+ det:
82
+ title: "DADOS DO PRODUTO / SERVIÇO"
83
+ prod:
84
+ cProd: "CÓDIGO"
85
+ xProd: "DESCRIÇÃO"
86
+ NCM: "NCM"
87
+ CFOP: "CFOP"
88
+ uCom: "UNID"
89
+ qCom: "QUANT"
90
+ vUnCom: "VALOR UNIT"
91
+ vProd: "VALOR TOT"
92
+ xProdST: "ST: MVA: %{pMVAST}% * Alíq: %{pICMSST}% * BC: %{vBCST} * Vlr: %{vICMSST}"
93
+ xProdFCI: "FCI: %{nFCI}"
94
+ ICMS:
95
+ CST: "CST"
96
+ vBC: "BASE CÁLC"
97
+ vICMS: "VL ICMS"
98
+ pICMS: "% ICMS"
99
+ IPI:
100
+ vIPI: "VL IPI"
101
+ pIPI: "% IPI"
102
+ issqn:
103
+ title: "CÁLCULO DO ISSQN"
104
+ total:
105
+ vServ: "VALOR TOTAL DOS SERVIÇOS"
106
+ vBCISS: "BASE DE CÁLCULO DO ISSQN"
107
+ ISSTot: "VALOR DO ISSQN"
108
+ infAdic:
109
+ title: "DADOS ADICIONAIS"
110
+ infCpl: "INFORMAÇÕES COMPLEMENTARES"
111
+ reserved: "RESERVADO AO FISCO"
112
+ others: "OUTRAS INFORMAÇÕES"
113
+ vol:
114
+ title: "CONTINUAÇÃO TRANSPORTADOR/VOLUMES TRANSPORTADOS"
115
+ qVol: "QUANT.:"
116
+ esp: "ESP.:"
117
+ marca: "MARCA:"
118
+ nVol: "NUM.:"
119
+ pesoB: "PESO B.:"
120
+ pesoL: "PESO LÍQ.:"
121
+ ticket:
122
+ xNome: "RECEBEMOS DE %{xNome} OS PRODUTOS CONSTANTES DA NOTA FISCAL INDICADA ABAIXO"
123
+ received_at: "DATA DE RECEBIMENTO"
124
+ receiver: "IDENTIFICAÇÃO E ASSINATURA DO RECEBEDOR"
125
+ document: "NF-e\nN°. %{nNF}\nSÉRIE %{serie}"
@@ -0,0 +1,12 @@
1
+ require "prawn"
2
+ require "prawn/measurement_extensions"
3
+ require "barby"
4
+ require "barby/barcode/code_128"
5
+ require "barby/outputter/prawn_outputter"
6
+ require "nokogiri"
7
+ require "yaml"
8
+ require "ostruct"
9
+ require "i18n"
10
+
11
+ Dir[File.dirname(__FILE__) + "/**/*.rb"].each { |f| require f }
12
+ I18n.load_path << File.expand_path("../../config/locales/pt-BR.yml", __FILE__)
@@ -0,0 +1,7 @@
1
+ module BrDanfe
2
+ class Cep
3
+ def self.format(cep)
4
+ cep.sub(/(\d{2})(\d{3})(\d{3})/, "\\1.\\2-\\3")
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ module BrDanfe
2
+ class Cnpj
3
+ def self.format(cnpj)
4
+ cnpj.sub(/(\d{2})(\d{3})(\d{3})(\d{4})(\d{2})/, "\\1.\\2.\\3/\\4-\\5")
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ module BrDanfe
2
+ class Cpf
3
+ def self.format(cpf)
4
+ cpf.sub(/(\d{3})(\d{3})(\d{3})(\d{2})/, "\\1.\\2.\\3-\\4")
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,28 @@
1
+ module BrDanfe
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
@@ -0,0 +1,54 @@
1
+ module BrDanfe
2
+ class DanfeGenerator
3
+ def initialize(xml)
4
+ @xml = xml
5
+ @pdf = Document.new
6
+
7
+ create_watermark
8
+ end
9
+
10
+ def generatePDF
11
+ @pdf.stamp("without_fiscal_value") if Helper.without_fiscal_value?(@xml)
12
+
13
+ @pdf.repeat :all do
14
+ Ticket.render(@pdf, @xml)
15
+ Emit.render(@pdf, @xml)
16
+ Dest.render(@pdf, @xml)
17
+ Dup.render(@pdf, @xml)
18
+ Icmstot.render(@pdf, @xml)
19
+ Transp.render(@pdf, @xml)
20
+ nVol = Vol.render(@pdf, @xml)
21
+ Det.render_header(@pdf, @xml)
22
+ Issqn.render(@pdf, @xml)
23
+ Infadic.render(@pdf, @xml, nVol)
24
+ end
25
+
26
+ Det.render_body(@pdf, @xml)
27
+
28
+ @pdf.page_count.times do |i|
29
+ @pdf.go_to_page(i + 1)
30
+ @pdf.ibox 1.00, 2.08, 8.71, 5.54, "",
31
+ I18n.t("danfe.others.page", current: i+1, total: @pdf.page_count),
32
+ {size: 8, align: :center, valign: :center, border: 0, style: :bold}
33
+ end
34
+
35
+ @pdf
36
+ end
37
+
38
+ private
39
+ def create_watermark
40
+ @pdf.create_stamp("without_fiscal_value") do
41
+ @pdf.fill_color "7d7d7d"
42
+ @pdf.text_box I18n.t("danfe.others.without_fiscal_value"),
43
+ size: 2.2.cm,
44
+ width: @pdf.bounds.width,
45
+ height: @pdf.bounds.height,
46
+ align: :center,
47
+ valign: :center,
48
+ at: [0, @pdf.bounds.height],
49
+ rotate: 45,
50
+ rotate_around: :center
51
+ end
52
+ end
53
+ end
54
+ end