br_invoices_pdf 0.2.6 → 0.2.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (64) hide show
  1. checksums.yaml +4 -4
  2. data/.codeclimate.yml +17 -0
  3. data/.rubocop.yml +1 -0
  4. data/CHANGELOG.md +3 -0
  5. data/Gemfile +2 -0
  6. data/Rakefile +2 -0
  7. data/bin/console +1 -0
  8. data/br_invoices_pdf.gemspec +1 -0
  9. data/lib/br_invoices_pdf.rb +12 -0
  10. data/lib/br_invoices_pdf/cfe.rb +2 -1
  11. data/lib/br_invoices_pdf/cfe/parser.rb +5 -3
  12. data/lib/br_invoices_pdf/cfe/parser/access_key.rb +3 -1
  13. data/lib/br_invoices_pdf/cfe/parser/cnpj.rb +3 -1
  14. data/lib/br_invoices_pdf/cfe/parser/company_attributes.rb +3 -1
  15. data/lib/br_invoices_pdf/cfe/parser/cpf.rb +3 -1
  16. data/lib/br_invoices_pdf/cfe/parser/document_number.rb +3 -1
  17. data/lib/br_invoices_pdf/cfe/parser/fisco_obs.rb +3 -1
  18. data/lib/br_invoices_pdf/cfe/parser/payment.rb +3 -1
  19. data/lib/br_invoices_pdf/cfe/parser/payments.rb +6 -16
  20. data/lib/br_invoices_pdf/cfe/parser/products_data.rb +4 -2
  21. data/lib/br_invoices_pdf/cfe/parser/sat.rb +3 -1
  22. data/lib/br_invoices_pdf/cfe/renderer.rb +4 -18
  23. data/lib/br_invoices_pdf/cfe/renderer/base_renderer.rb +5 -62
  24. data/lib/br_invoices_pdf/cfe/renderer/company_identification.rb +3 -0
  25. data/lib/br_invoices_pdf/cfe/renderer/fisco_info.rb +3 -0
  26. data/lib/br_invoices_pdf/cfe/renderer/header.rb +3 -0
  27. data/lib/br_invoices_pdf/cfe/renderer/payment_forms.rb +6 -12
  28. data/lib/br_invoices_pdf/cfe/renderer/product_table.rb +4 -48
  29. data/lib/br_invoices_pdf/cfe/renderer/qr_code.rb +5 -9
  30. data/lib/br_invoices_pdf/cfe/renderer/taxes_info.rb +5 -2
  31. data/lib/br_invoices_pdf/cfe/renderer/totals.rb +3 -24
  32. data/lib/br_invoices_pdf/errors/invalid_document_type.rb +2 -0
  33. data/lib/br_invoices_pdf/generator.rb +2 -0
  34. data/lib/br_invoices_pdf/nfce.rb +11 -0
  35. data/lib/br_invoices_pdf/nfce/parser.rb +33 -0
  36. data/lib/br_invoices_pdf/nfce/parser/additional_info.rb +17 -0
  37. data/lib/br_invoices_pdf/nfce/parser/company.rb +25 -0
  38. data/lib/br_invoices_pdf/nfce/parser/customer.rb +32 -0
  39. data/lib/br_invoices_pdf/nfce/parser/emission_details.rb +51 -0
  40. data/lib/br_invoices_pdf/nfce/parser/payments.rb +30 -0
  41. data/lib/br_invoices_pdf/nfce/parser/products.rb +39 -0
  42. data/lib/br_invoices_pdf/nfce/parser/totals.rb +25 -0
  43. data/lib/br_invoices_pdf/nfce/renderer.rb +37 -0
  44. data/lib/br_invoices_pdf/nfce/renderer/base_renderer.rb +22 -0
  45. data/lib/br_invoices_pdf/nfce/renderer/company_identification.rb +37 -0
  46. data/lib/br_invoices_pdf/nfce/renderer/customer_identification.rb +47 -0
  47. data/lib/br_invoices_pdf/nfce/renderer/fiscal_message.rb +46 -0
  48. data/lib/br_invoices_pdf/nfce/renderer/header.rb +32 -0
  49. data/lib/br_invoices_pdf/nfce/renderer/payment_forms.rb +73 -0
  50. data/lib/br_invoices_pdf/nfce/renderer/product_table.rb +23 -0
  51. data/lib/br_invoices_pdf/nfce/renderer/qr_code.rb +56 -0
  52. data/lib/br_invoices_pdf/nfce/renderer/taxes_info.rb +28 -0
  53. data/lib/br_invoices_pdf/nfce/renderer/totals.rb +30 -0
  54. data/lib/br_invoices_pdf/util/base_renderer.rb +121 -0
  55. data/lib/br_invoices_pdf/util/enum.rb +20 -0
  56. data/lib/br_invoices_pdf/util/mount_params.rb +26 -0
  57. data/lib/br_invoices_pdf/util/nfce_check_urls.rb +102 -0
  58. data/lib/br_invoices_pdf/util/pdf_renderer.rb +33 -0
  59. data/lib/br_invoices_pdf/util/product_table.rb +57 -0
  60. data/lib/br_invoices_pdf/util/xml_locate.rb +21 -0
  61. data/lib/br_invoices_pdf/version.rb +3 -1
  62. data/nfce.xml +160 -0
  63. metadata +32 -4
  64. data/lib/br_invoices_pdf/cfe/parser/base_parser.rb +0 -19
@@ -1,7 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module BrInvoicesPdf
2
4
  module Cfe
3
5
  module Renderer
4
6
  module Header
7
+ extend Util::BaseRenderer
5
8
  extend BaseRenderer
6
9
 
7
10
  module_function
@@ -1,19 +1,16 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module BrInvoicesPdf
2
4
  module Cfe
3
5
  module Renderer
4
6
  module PaymentForms
7
+ extend Util::BaseRenderer
5
8
  extend BaseRenderer
6
9
 
7
10
  module_function
8
11
 
9
12
  def execute(pdf, data)
10
- pdf.font_size(6) do
11
- width = page_content_width(pdf)
12
- table_data = payments_table_data(data)
13
- render_table(pdf, table_data, width)
14
- end
15
-
16
- pdf.move_down(5)
13
+ execute_payment_form(pdf, payments_table_data(data))
17
14
  end
18
15
 
19
16
  def render_table(pdf, table_data, width)
@@ -33,13 +30,10 @@ module BrInvoicesPdf
33
30
  end
34
31
  private_class_method :format_table
35
32
 
36
- PAYMENTS_TABLE_BASE_DATA = [['FORMA DE PAGAMENTO', 'VALOR']].freeze
37
33
  def payments_table_data(data)
38
- payments_data = data[:payments].reduce(PAYMENTS_TABLE_BASE_DATA) do |result, cur|
39
- result + [[cur[:type], format_currency(cur[:amount])]]
40
- end
34
+ payments_data = mount_payment_data(data)
41
35
 
42
- add_default_values(payments_data, data[:payment])
36
+ add_default_values(payments_data, data[:totals])
43
37
  end
44
38
  private_class_method :payments_table_data
45
39
 
@@ -1,7 +1,11 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module BrInvoicesPdf
2
4
  module Cfe
3
5
  module Renderer
4
6
  module ProductTable
7
+ extend Util::BaseRenderer
8
+ extend Util::ProductTable
5
9
  extend BaseRenderer
6
10
 
7
11
  module_function
@@ -15,54 +19,6 @@ module BrInvoicesPdf
15
19
 
16
20
  pdf.move_down(5)
17
21
  end
18
-
19
- def format_table(pdf, table_data)
20
- width = page_content_width(pdf)
21
- pdf.table(table_data, width: width) do |table|
22
- format_row(table.row(0))
23
- format_columns(table)
24
- end
25
- end
26
- private_class_method :format_table
27
-
28
- def format_row(row)
29
- row.font_style = :bold
30
- row.align = :center
31
- end
32
- private_class_method :format_row
33
-
34
- # :reek:FeatureEnvy
35
- def format_columns(table)
36
- table.columns(0..5).valign = :center
37
- table.columns([2, 4, 5]).align = :right
38
- table.column(3).align = :center
39
- table_widths(table, table.width)
40
- end
41
- private_class_method :format_columns
42
-
43
- # :reek:FeatureEnvy
44
- def table_widths(table, width)
45
- table.column(0).width = width * 0.16
46
- table.columns([2, 3]).width = width * 0.155
47
- table.column([4, 5]).width = width * 0.135
48
- end
49
- private_class_method :table_widths
50
-
51
- PRODUCT_TABLE_BASE_DATA = [['CÓD.', 'DESCRIÇÃO', 'QTD.', 'UND.', 'V.UNIT', 'V.TOT']].freeze
52
- # :reek:FeatureEnvy
53
- def product_table_data(data)
54
- data[:products].reduce(PRODUCT_TABLE_BASE_DATA) do |result, cur|
55
- result + [[
56
- cur[:code],
57
- cur[:description],
58
- format_number(cur[:quantity]),
59
- cur[:unit_label],
60
- format_currency(cur[:unit_value]),
61
- format_currency(cur[:total_value])
62
- ]]
63
- end
64
- end
65
- private_class_method :product_table_data
66
22
  end
67
23
  end
68
24
  end
@@ -1,12 +1,15 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module BrInvoicesPdf
2
4
  module Cfe
3
5
  module Renderer
4
6
  module QrCode
7
+ extend Util::BaseRenderer
5
8
  extend BaseRenderer
6
9
 
7
10
  module_function
8
11
 
9
- SAT_QRCODE_SEPARATOR = '|'.freeze
12
+ SAT_QRCODE_SEPARATOR = '|'
10
13
  BARCODE_HEIGHT = 50
11
14
 
12
15
  def execute(pdf, data)
@@ -50,19 +53,12 @@ module BrInvoicesPdf
50
53
  end
51
54
  private_class_method :generate_qr_code
52
55
 
53
- def generate_qr_code_data(qr_code_string, qrcode_size)
54
- qrcode = RQRCode::QRCode.new(qr_code_string)
55
- blob = qrcode.as_png(size: qrcode_size.to_i, border_modules: 0).to_blob
56
- StringIO.new(blob)
57
- end
58
- private_class_method :generate_qr_code_data
59
-
60
56
  # rubocop:disable Metrics/AbcSize
61
57
  def generate_qr_code_string(access_key, data)
62
58
  sat_params = data[:sat_params]
63
59
  access_key + SAT_QRCODE_SEPARATOR + sat_params[:emission_date] +
64
60
  SAT_QRCODE_SEPARATOR + sat_params[:emission_hour] +
65
- SAT_QRCODE_SEPARATOR + data[:payment][:total].delete('.') + SAT_QRCODE_SEPARATOR +
61
+ SAT_QRCODE_SEPARATOR + data[:totals][:total].delete('.') + SAT_QRCODE_SEPARATOR +
66
62
  data[:company_attributes][:cnpj] + SAT_QRCODE_SEPARATOR +
67
63
  sat_params[:document_qr_code_signature]
68
64
  end
@@ -1,14 +1,17 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module BrInvoicesPdf
2
4
  module Cfe
3
5
  module Renderer
4
6
  module TaxesInfo
7
+ extend Util::BaseRenderer
5
8
  extend BaseRenderer
6
9
 
7
10
  module_function
8
11
 
9
12
  def execute(pdf, data)
10
13
  box(pdf, [0, pdf.cursor], page_content_width(pdf)) do
11
- tribute_values(pdf, data[:payment])
14
+ tribute_values(pdf, data[:totals])
12
15
  sat_params = data[:sat_params]
13
16
  sat_number(pdf, sat_params[:sat_number])
14
17
  date_values(pdf, sat_params)
@@ -17,7 +20,7 @@ module BrInvoicesPdf
17
20
 
18
21
  def date_values(pdf, data)
19
22
  time = data[:emission_date] + data[:emission_hour]
20
- pdf.text(DateTime.parse(time).strftime('%d/%m/%Y %H:%M:%S'), align: :center)
23
+ pdf.text(Date.parse(time).strftime('%d/%m/%Y %H:%M:%S'), align: :center)
21
24
  end
22
25
  private_class_method :date_values
23
26
 
@@ -1,7 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module BrInvoicesPdf
2
4
  module Cfe
3
5
  module Renderer
4
6
  module Totals
7
+ extend Util::BaseRenderer
5
8
  extend BaseRenderer
6
9
 
7
10
  module_function
@@ -12,30 +15,6 @@ module BrInvoicesPdf
12
15
  pdf.move_down(5)
13
16
  end
14
17
 
15
- def insert_box_info(pdf, data, xpos = 0)
16
- third_width = page_content_width(pdf) * 0.333333333
17
- ypos = pdf.cursor
18
- box_info(data[:payment]).each do |(title, value)|
19
- insert_box(pdf, title: title, value: value, xpos: xpos, ypos: ypos, third_width: third_width)
20
- xpos += third_width
21
- end
22
- end
23
- private_class_method :insert_box_info
24
-
25
- # :reek:FeatureEnvy
26
- def insert_box(pdf, params)
27
- box(pdf, [params[:xpos], params[:ypos]], params[:third_width]) do
28
- insert_texts(pdf, params[:title], params[:value])
29
- end
30
- end
31
- private_class_method :insert_box
32
-
33
- def insert_texts(pdf, title, value)
34
- pdf.text(title, style: :italic)
35
- pdf.text(value, align: :right)
36
- end
37
- private_class_method :insert_texts
38
-
39
18
  def box_info(data_payment)
40
19
  [
41
20
  ['Total bruto dos itens', format_currency(data_payment[:total_price])],
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module BrInvoicesPdf
2
4
  module Errors
3
5
  class InvalidDocumentType < StandardError
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module BrInvoicesPdf
2
4
  class Generator
3
5
  PDF_OPTIONS = { page_size: 'A4', margin: [40, 75] }.freeze
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'br_invoices_pdf/nfce/parser'
4
+ require 'br_invoices_pdf/nfce/renderer/base_renderer'
5
+ require 'br_invoices_pdf/nfce/renderer'
6
+
7
+ module BrInvoicesPdf
8
+ module Nfce
9
+ BrInvoicesPdf.register(:nfce, Nfce::Renderer, Nfce::Parser)
10
+ end
11
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'br_invoices_pdf/nfce/parser/company'
4
+ require 'br_invoices_pdf/nfce/parser/products'
5
+ require 'br_invoices_pdf/nfce/parser/payments'
6
+ require 'br_invoices_pdf/nfce/parser/customer'
7
+ require 'br_invoices_pdf/nfce/parser/totals'
8
+ require 'br_invoices_pdf/nfce/parser/additional_info'
9
+ require 'br_invoices_pdf/nfce/parser/emission_details'
10
+
11
+ module BrInvoicesPdf
12
+ module Nfce
13
+ module Parser
14
+ module_function
15
+
16
+ PARSERS = {
17
+ company: Company,
18
+ products: Products,
19
+ payments: Payments,
20
+ customer: Customer,
21
+ totals: Totals,
22
+ additional_info: AdditionalInfo,
23
+ emission_details: EmissionDetails
24
+ }.freeze
25
+
26
+ def parse(xml)
27
+ PARSERS.reduce({}) do |response, (param, parser)|
28
+ { **response, param => parser.execute(xml) }
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BrInvoicesPdf
4
+ module Nfce
5
+ module Parser
6
+ module AdditionalInfo
7
+ extend Util::XmlLocate
8
+
9
+ module_function
10
+
11
+ def execute(xml)
12
+ locate_element(xml, 'NFe/infAdic/infCpl')
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BrInvoicesPdf
4
+ module Nfce
5
+ module Parser
6
+ module Company
7
+ extend Util::XmlLocate
8
+ extend Util::MountParams
9
+
10
+ module_function
11
+
12
+ EMIT_ROOT_PATH = "#{Util::XmlLocate::ROOT_PATH}/emit"
13
+
14
+ def execute(xml)
15
+ {
16
+ name: locate_element(xml, "#{EMIT_ROOT_PATH}/xNome"),
17
+ cnpj: locate_element(xml, "#{EMIT_ROOT_PATH}/CNPJ"),
18
+ state_number: locate_element(xml, "#{EMIT_ROOT_PATH}/IE"),
19
+ address: mount(xml, address_params(EMIT_ROOT_PATH, 'Emit'))
20
+ }
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BrInvoicesPdf
4
+ module Nfce
5
+ module Parser
6
+ module Customer
7
+ extend Util::XmlLocate
8
+ extend Util::MountParams
9
+
10
+ module_function
11
+
12
+ DEST_ROOT_PATH = "#{Util::XmlLocate::ROOT_PATH}/dest"
13
+
14
+ def execute(xml)
15
+ identification_type = identification_type_by(xml)
16
+ {
17
+ identification_type: identification_type,
18
+ identification: locate_element(xml, "#{DEST_ROOT_PATH}/#{identification_type}"),
19
+ address: mount(xml, address_params(DEST_ROOT_PATH, 'Dest'))
20
+ }
21
+ end
22
+
23
+ def identification_type_by(xml)
24
+ return 'CNPJ' if locate_element(xml, "#{DEST_ROOT_PATH}/CNPJ")
25
+ return 'CPF' if locate_element(xml, "#{DEST_ROOT_PATH}/CPF")
26
+ return 'idEstrangeiro' if locate_element(xml, "#{DEST_ROOT_PATH}/idEstrangeiro")
27
+ end
28
+ private_class_method :identification_type_by
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,51 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BrInvoicesPdf
4
+ module Nfce
5
+ module Parser
6
+ module EmissionDetails
7
+ extend Util::XmlLocate
8
+
9
+ module_function
10
+
11
+ EMISSION_ROOT_PATH = "#{Util::XmlLocate::ROOT_PATH}/ide"
12
+
13
+ EMISSION_TYPES = {
14
+ '1': 'Emissão normal',
15
+ '2': 'Contingência FS-IA',
16
+ '3': 'Contingência SCAN',
17
+ '4': 'Contingência DPEC',
18
+ '5': 'Contingência FS-DA, com impressão do DANFE em formulário de segurança',
19
+ '6': 'Contingência SVC-AN',
20
+ '7': 'Contingência SVC-RS',
21
+ '9': 'Contingência off-line da NFC-e'
22
+ }.freeze
23
+
24
+ def execute(xml)
25
+ {
26
+ type: EMISSION_TYPES[locate_element(xml, "#{EMISSION_ROOT_PATH}/tpEmis").to_sym],
27
+ number: locate_element(xml, "#{EMISSION_ROOT_PATH}/nNF"),
28
+ serie: locate_element(xml, "#{EMISSION_ROOT_PATH}/serie"),
29
+ emission_timestamp: locate_element_to_date(xml, "#{EMISSION_ROOT_PATH}/dhEmi"),
30
+ receival_timestamp: locate_element_to_date(xml, 'protNFe/infProt/dhRecbto'),
31
+ check_url: check_url(xml),
32
+ access_key: locate_element(xml, 'protNFe/infProt/chNFe'),
33
+ qrcode_url: xml.locate('NFe/infNFeSupl/qrCode').first.nodes.first.value,
34
+ authorization_protocol: locate_element(xml, 'protNFe/infProt/nProt')
35
+ }
36
+ end
37
+
38
+ def check_url(xml)
39
+ check_urls = Util::NfceCheckUrls::URLS[locate_element(xml, "#{EMISSION_ROOT_PATH}/cUF").to_sym]
40
+ check_urls[locate_element(xml, "#{EMISSION_ROOT_PATH}/tpAmb").to_sym]
41
+ end
42
+ private_class_method :check_url
43
+
44
+ def locate_element_to_date(xml, path)
45
+ Time.new(locate_element(xml, path)).utc
46
+ end
47
+ private_class_method :locate_element_to_date
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BrInvoicesPdf
4
+ module Nfce
5
+ module Parser
6
+ module Payments
7
+ extend Util::XmlLocate
8
+
9
+ module_function
10
+
11
+ ROOT_PATH = Util::XmlLocate::ROOT_PATH
12
+
13
+ def execute(xml)
14
+ node_payments = xml.locate("#{ROOT_PATH}/pag")
15
+
16
+ node_payments.map(&method(:payment_by))
17
+ end
18
+
19
+ def payment_by(element)
20
+ {
21
+ type: Util::Enum::PAYMENT_TYPES[locate_element(element, 'tPag')],
22
+ amount: locate_element(element, 'vPag'),
23
+ cashback: locate_element(element, 'vTroco')
24
+ }
25
+ end
26
+ private_class_method :payment_by
27
+ end
28
+ end
29
+ end
30
+ end