br_danfe 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (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