br_invoices_pdf 0.2.6.alpha.18 → 0.2.6.alpha.19
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.codeclimate.yml +17 -0
- data/.rubocop.yml +1 -0
- data/CHANGELOG.md +1 -0
- data/Gemfile +2 -0
- data/Rakefile +2 -0
- data/bin/console +1 -0
- data/br_invoices_pdf.gemspec +1 -0
- data/lib/br_invoices_pdf/cfe/parser/access_key.rb +3 -1
- data/lib/br_invoices_pdf/cfe/parser/cnpj.rb +3 -1
- data/lib/br_invoices_pdf/cfe/parser/company_attributes.rb +3 -1
- data/lib/br_invoices_pdf/cfe/parser/cpf.rb +3 -1
- data/lib/br_invoices_pdf/cfe/parser/document_number.rb +3 -1
- data/lib/br_invoices_pdf/cfe/parser/fisco_obs.rb +3 -1
- data/lib/br_invoices_pdf/cfe/parser/payment.rb +3 -1
- data/lib/br_invoices_pdf/cfe/parser/payments.rb +6 -16
- data/lib/br_invoices_pdf/cfe/parser/products_data.rb +4 -2
- data/lib/br_invoices_pdf/cfe/parser/sat.rb +3 -1
- data/lib/br_invoices_pdf/cfe/parser.rb +5 -3
- data/lib/br_invoices_pdf/cfe/renderer/base_renderer.rb +5 -62
- data/lib/br_invoices_pdf/cfe/renderer/company_identification.rb +3 -0
- data/lib/br_invoices_pdf/cfe/renderer/fisco_info.rb +3 -0
- data/lib/br_invoices_pdf/cfe/renderer/header.rb +3 -0
- data/lib/br_invoices_pdf/cfe/renderer/payment_forms.rb +6 -12
- data/lib/br_invoices_pdf/cfe/renderer/product_table.rb +4 -48
- data/lib/br_invoices_pdf/cfe/renderer/qr_code.rb +5 -9
- data/lib/br_invoices_pdf/cfe/renderer/taxes_info.rb +5 -2
- data/lib/br_invoices_pdf/cfe/renderer/totals.rb +3 -24
- data/lib/br_invoices_pdf/cfe/renderer.rb +4 -18
- data/lib/br_invoices_pdf/cfe.rb +2 -1
- data/lib/br_invoices_pdf/errors/invalid_document_type.rb +2 -0
- data/lib/br_invoices_pdf/generator.rb +2 -0
- data/lib/br_invoices_pdf/nfce/parser/additional_info.rb +17 -0
- data/lib/br_invoices_pdf/nfce/parser/company.rb +25 -0
- data/lib/br_invoices_pdf/nfce/parser/customer.rb +32 -0
- data/lib/br_invoices_pdf/nfce/parser/emission_details.rb +51 -0
- data/lib/br_invoices_pdf/nfce/parser/payments.rb +30 -0
- data/lib/br_invoices_pdf/nfce/parser/products.rb +39 -0
- data/lib/br_invoices_pdf/nfce/parser/totals.rb +25 -0
- data/lib/br_invoices_pdf/nfce/parser.rb +33 -0
- data/lib/br_invoices_pdf/nfce/renderer/base_renderer.rb +22 -0
- data/lib/br_invoices_pdf/nfce/renderer/company_identification.rb +37 -0
- data/lib/br_invoices_pdf/nfce/renderer/customer_identification.rb +47 -0
- data/lib/br_invoices_pdf/nfce/renderer/fiscal_message.rb +46 -0
- data/lib/br_invoices_pdf/nfce/renderer/header.rb +32 -0
- data/lib/br_invoices_pdf/nfce/renderer/payment_forms.rb +73 -0
- data/lib/br_invoices_pdf/nfce/renderer/product_table.rb +23 -0
- data/lib/br_invoices_pdf/nfce/renderer/qr_code.rb +56 -0
- data/lib/br_invoices_pdf/nfce/renderer/taxes_info.rb +28 -0
- data/lib/br_invoices_pdf/nfce/renderer/totals.rb +30 -0
- data/lib/br_invoices_pdf/nfce/renderer.rb +37 -0
- data/lib/br_invoices_pdf/nfce.rb +11 -0
- data/lib/br_invoices_pdf/util/base_renderer.rb +121 -0
- data/lib/br_invoices_pdf/util/enum.rb +20 -0
- data/lib/br_invoices_pdf/util/mount_params.rb +26 -0
- data/lib/br_invoices_pdf/util/nfce_check_urls.rb +102 -0
- data/lib/br_invoices_pdf/util/pdf_renderer.rb +33 -0
- data/lib/br_invoices_pdf/util/product_table.rb +57 -0
- data/lib/br_invoices_pdf/util/xml_locate.rb +21 -0
- data/lib/br_invoices_pdf/version.rb +3 -1
- data/lib/br_invoices_pdf.rb +12 -0
- data/nfce.xml +160 -0
- metadata +32 -4
- data/lib/br_invoices_pdf/cfe/parser/base_parser.rb +0 -19
@@ -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
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module BrInvoicesPdf
|
4
|
+
module Nfce
|
5
|
+
module Parser
|
6
|
+
module Products
|
7
|
+
extend Util::XmlLocate
|
8
|
+
|
9
|
+
module_function
|
10
|
+
|
11
|
+
ROOT_PATH = Util::XmlLocate::ROOT_PATH
|
12
|
+
|
13
|
+
FIELDS = { code: 'cProd',
|
14
|
+
description: 'xProd',
|
15
|
+
quantity: 'qCom',
|
16
|
+
unit_label: 'uCom',
|
17
|
+
unit_value: 'vUnCom',
|
18
|
+
total_value: 'vProd' }.freeze
|
19
|
+
|
20
|
+
def execute(xml)
|
21
|
+
node_products = xml.locate("#{ROOT_PATH}/det")
|
22
|
+
products_params(node_products) if node_products
|
23
|
+
end
|
24
|
+
|
25
|
+
def products_params(node_products)
|
26
|
+
node_products.map(&method(:product_by))
|
27
|
+
end
|
28
|
+
private_class_method :products_params
|
29
|
+
|
30
|
+
def product_by(element)
|
31
|
+
FIELDS
|
32
|
+
.map { |(key, field)| [key, node_locate(element, field).force_encoding('UTF-8')] }
|
33
|
+
.to_h
|
34
|
+
end
|
35
|
+
private_class_method :product_by
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module BrInvoicesPdf
|
4
|
+
module Nfce
|
5
|
+
module Parser
|
6
|
+
module Totals
|
7
|
+
extend Util::XmlLocate
|
8
|
+
|
9
|
+
module_function
|
10
|
+
|
11
|
+
TOTAL_ROOT_PATH = "#{Util::XmlLocate::ROOT_PATH}/total/ICMSTot"
|
12
|
+
|
13
|
+
def execute(xml)
|
14
|
+
{
|
15
|
+
items: Products.execute(xml).count,
|
16
|
+
subtotal: locate_element(xml, "#{TOTAL_ROOT_PATH}/vProd"),
|
17
|
+
discounts: locate_element(xml, "#{TOTAL_ROOT_PATH}/vDesc"),
|
18
|
+
total: locate_element(xml, "#{TOTAL_ROOT_PATH}/vNF"),
|
19
|
+
cashback: '0.00'
|
20
|
+
}
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
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,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module BrInvoicesPdf
|
4
|
+
module Nfce
|
5
|
+
module Renderer
|
6
|
+
module BaseRenderer
|
7
|
+
extend Util::BaseRenderer
|
8
|
+
|
9
|
+
module_function
|
10
|
+
|
11
|
+
ADDRESS_FORMAT = '%s, %s, %s, %s/%s'
|
12
|
+
def format_address(address)
|
13
|
+
ADDRESS_FORMAT % %i(streetname number district city state).map(&address.method(:[]))
|
14
|
+
end
|
15
|
+
|
16
|
+
def format_date(date)
|
17
|
+
date.strftime('%H:%M:%S %d/%m/%Y')
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module BrInvoicesPdf
|
4
|
+
module Nfce
|
5
|
+
module Renderer
|
6
|
+
# :reek:DataClump
|
7
|
+
module CompanyIdentification
|
8
|
+
extend Util::BaseRenderer
|
9
|
+
extend BaseRenderer
|
10
|
+
|
11
|
+
module_function
|
12
|
+
|
13
|
+
def execute(pdf, data)
|
14
|
+
attributes = data[:company]
|
15
|
+
pdf_setup(pdf) do
|
16
|
+
company_params(pdf, attributes)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
# :reek:FeatureEnvy
|
21
|
+
def company_params(pdf, data)
|
22
|
+
pdf.text(data[:name], align: :center)
|
23
|
+
pdf.text(format_address(data[:address]), align: :center)
|
24
|
+
insert_fiscal_numbers(pdf, data)
|
25
|
+
end
|
26
|
+
private_class_method :company_params
|
27
|
+
|
28
|
+
# :reek:FeatureEnvy
|
29
|
+
def insert_fiscal_numbers(pdf, data)
|
30
|
+
pdf.text("CNPJ: #{format_cnpj(data[:cnpj])}", align: :center)
|
31
|
+
pdf.text("Inscrição Estadual: #{data[:state_number]}", align: :center)
|
32
|
+
end
|
33
|
+
private_class_method :insert_fiscal_numbers
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module BrInvoicesPdf
|
4
|
+
module Nfce
|
5
|
+
module Renderer
|
6
|
+
module CustomerIdentification
|
7
|
+
extend Util::BaseRenderer
|
8
|
+
extend BaseRenderer
|
9
|
+
|
10
|
+
module_function
|
11
|
+
|
12
|
+
def execute(pdf, data)
|
13
|
+
box(pdf, [0, pdf.cursor], page_content_width(pdf)) do
|
14
|
+
customer = data[:customer]
|
15
|
+
add_customer_identification(pdf, data, identificator(customer[:identification_type],
|
16
|
+
customer[:identification]))
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def identificator(identification, number)
|
21
|
+
id = identification
|
22
|
+
|
23
|
+
case id
|
24
|
+
when 'CPF'
|
25
|
+
"CPF DO CONSUMIDOR: #{format_cpf(number)}"
|
26
|
+
when 'CNPJ'
|
27
|
+
"CNPJ DO CONSUMIDOR: #{format_cnpj(number)}"
|
28
|
+
when 'idEstrangeiro'
|
29
|
+
"ID. ESTRANGEIRO: #{number}"
|
30
|
+
else
|
31
|
+
'CONSUMIDOR NÃO IDENTIFICADO'
|
32
|
+
end
|
33
|
+
end
|
34
|
+
private_class_method :identificator
|
35
|
+
|
36
|
+
# :reek:FeatureEnvy
|
37
|
+
def add_customer_identification(pdf, data, identificator)
|
38
|
+
address = data[:customer][:address]
|
39
|
+
pdf.text("Consumidor\n\n", style: :italic)
|
40
|
+
pdf.text(identificator, align: :center)
|
41
|
+
pdf.text(format_address(address), align: :center) if address[:streetname]
|
42
|
+
end
|
43
|
+
private_class_method :add_customer_identification
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module BrInvoicesPdf
|
4
|
+
module Nfce
|
5
|
+
module Renderer
|
6
|
+
module FiscalMessage
|
7
|
+
extend Util::BaseRenderer
|
8
|
+
extend BaseRenderer
|
9
|
+
|
10
|
+
module_function
|
11
|
+
|
12
|
+
def execute(pdf, data)
|
13
|
+
box(pdf, [0, pdf.cursor], page_content_width(pdf)) do
|
14
|
+
emission_details(pdf, data)
|
15
|
+
emission_date(pdf, data)
|
16
|
+
consult_key(pdf, data[:emission_details][:access_key])
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def consult_key(pdf, key)
|
21
|
+
pdf.text("CHAVE DE ACESSO:\n#{key.scan(/.{1,4}/).join(' ')}", align: :center)
|
22
|
+
end
|
23
|
+
private_class_method :consult_key
|
24
|
+
|
25
|
+
# :reek:FeatureEnvy
|
26
|
+
def emission_date(pdf, data)
|
27
|
+
details = data[:emission_details]
|
28
|
+
text = "Emissão: #{format_date(details[:emission_timestamp])} - Via Consumidor\n\n"
|
29
|
+
pdf.text(text, align: :center)
|
30
|
+
key_text = "Consulte pela chave de acesso em: #{details[:check_url]} \n\n"
|
31
|
+
pdf.text(key_text, align: :center)
|
32
|
+
end
|
33
|
+
private_class_method :emission_date
|
34
|
+
|
35
|
+
# :reek:FeatureEnvy
|
36
|
+
def emission_details(pdf, data)
|
37
|
+
pdf.text("Mensagem Fiscal\n\n", style: :italic)
|
38
|
+
details = data[:emission_details]
|
39
|
+
text = "Número: #{details[:number]} - Série: #{details[:serie]}\n\n"
|
40
|
+
pdf.text(text, align: :center)
|
41
|
+
end
|
42
|
+
private_class_method :emission_details
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module BrInvoicesPdf
|
4
|
+
module Nfce
|
5
|
+
module Renderer
|
6
|
+
module Header
|
7
|
+
extend Util::BaseRenderer
|
8
|
+
extend BaseRenderer
|
9
|
+
|
10
|
+
module_function
|
11
|
+
|
12
|
+
# :reek:FeatureEnvy
|
13
|
+
def execute(pdf, data)
|
14
|
+
pdf_setup(pdf) do
|
15
|
+
add_header_config(pdf, data)
|
16
|
+
end
|
17
|
+
|
18
|
+
pdf.move_down(5)
|
19
|
+
end
|
20
|
+
|
21
|
+
def add_header_config(pdf, _data)
|
22
|
+
pdf.font('Helvetica', style: :bold)
|
23
|
+
msg = 'DANFE NFC-e - Documento Auxiliar de Nota Fiscal Eletrônica para consumidor final'
|
24
|
+
pdf.text(msg, align: :center)
|
25
|
+
pdf.font('Helvetica', style: :normal, align: :center)
|
26
|
+
pdf.text('Não permite aproveiamento de crédito de ICMS', align: :center)
|
27
|
+
end
|
28
|
+
private_class_method :add_header_config
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module BrInvoicesPdf
|
4
|
+
module Nfce
|
5
|
+
module Renderer
|
6
|
+
module PaymentForms
|
7
|
+
extend Util::BaseRenderer
|
8
|
+
extend BaseRenderer
|
9
|
+
|
10
|
+
module_function
|
11
|
+
|
12
|
+
def execute(pdf, data)
|
13
|
+
execute_payment_form(pdf, choose_table_data(data))
|
14
|
+
end
|
15
|
+
|
16
|
+
def choose_table_data(data)
|
17
|
+
cashback?(data) ? payments_table_data_with_cashback(data) : payments_table_data(data)
|
18
|
+
end
|
19
|
+
|
20
|
+
def cashback?(data)
|
21
|
+
!data[:payments].map { |payment| payment[:cashback] }.compact.empty?
|
22
|
+
end
|
23
|
+
|
24
|
+
def render_table(pdf, table_data, width)
|
25
|
+
pdf.table(table_data, width: width) do |table|
|
26
|
+
format_table(table, table_data)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
private_class_method :render_table
|
30
|
+
|
31
|
+
# :reek:FeatureEnvy
|
32
|
+
def format_table(table, table_data)
|
33
|
+
table.columns([0, 1, 2]).valign = :center
|
34
|
+
table.columns(1).align = :right
|
35
|
+
table_size = table_data.size
|
36
|
+
table.row([0, table_size - 1]).font_style = :bold
|
37
|
+
end
|
38
|
+
private_class_method :format_table
|
39
|
+
|
40
|
+
PAYMENTS_TABLE_BASE_DATA = [['FORMA DE PAGAMENTO', 'VALOR']].freeze
|
41
|
+
def payments_table_data(data)
|
42
|
+
payments_data = mount_payment_data(data)
|
43
|
+
|
44
|
+
add_default_values(payments_data, data)
|
45
|
+
end
|
46
|
+
private_class_method :payments_table_data
|
47
|
+
|
48
|
+
PAYMENTS_TABLE_BASE_DATA_WITH_CASHBACK = [['FORMA DE PAGAMENTO', 'VALOR', 'TROCO']].freeze
|
49
|
+
|
50
|
+
# :reek:FeatureEnvy
|
51
|
+
def payments_table_data_with_cashback(data)
|
52
|
+
payments_data = data[:payments].reduce(PAYMENTS_TABLE_BASE_DATA_WITH_CASHBACK) do |result, cur|
|
53
|
+
result + [[cur[:type], format_currency(cur[:amount]), cur[:cashback]]]
|
54
|
+
end
|
55
|
+
|
56
|
+
add_default_values(payments_data, data)
|
57
|
+
end
|
58
|
+
private_class_method :payments_table_data
|
59
|
+
|
60
|
+
def add_default_values(payments_data, data)
|
61
|
+
totals = format_currency(data[:totals][:total])
|
62
|
+
|
63
|
+
if cashback?(data)
|
64
|
+
payments_data.push(['TOTAL', totals, nil])
|
65
|
+
else
|
66
|
+
payments_data.push(['TOTAL', totals])
|
67
|
+
end
|
68
|
+
end
|
69
|
+
private_class_method :add_default_values
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module BrInvoicesPdf
|
4
|
+
module Nfce
|
5
|
+
module Renderer
|
6
|
+
module ProductTable
|
7
|
+
extend Util::BaseRenderer
|
8
|
+
extend Util::ProductTable
|
9
|
+
extend BaseRenderer
|
10
|
+
|
11
|
+
module_function
|
12
|
+
|
13
|
+
def execute(pdf, data)
|
14
|
+
table_data = product_table_data(data)
|
15
|
+
|
16
|
+
pdf.font_size(6) do
|
17
|
+
format_table(pdf, table_data)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module BrInvoicesPdf
|
4
|
+
module Nfce
|
5
|
+
module Renderer
|
6
|
+
module QrCode
|
7
|
+
extend Util::BaseRenderer
|
8
|
+
extend BaseRenderer
|
9
|
+
|
10
|
+
module_function
|
11
|
+
|
12
|
+
def execute(pdf, data)
|
13
|
+
render_box(pdf) do
|
14
|
+
options = pdf_options(page_paper_width(pdf.page.size))
|
15
|
+
|
16
|
+
generate_qr_code(pdf, data, options)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
# :reek:FeatureEnvy
|
21
|
+
def render_box(pdf)
|
22
|
+
box(pdf, [0, pdf.cursor], page_content_width(pdf)) do
|
23
|
+
pdf.text('QR Code', style: :italic)
|
24
|
+
yield
|
25
|
+
end
|
26
|
+
end
|
27
|
+
private_class_method :render_box
|
28
|
+
|
29
|
+
def pdf_options(page_width)
|
30
|
+
qrcode_size = page_width * 0.65
|
31
|
+
|
32
|
+
{ qrcode_size: qrcode_size, page_width: page_width }
|
33
|
+
end
|
34
|
+
private_class_method :pdf_options
|
35
|
+
|
36
|
+
# :reek:FeatureEnvy
|
37
|
+
def generate_qr_code(pdf, data, options)
|
38
|
+
qrcode_size = options[:qrcode_size]
|
39
|
+
opts = {
|
40
|
+
at: [(options[:page_width] - qrcode_size) / 2, pdf.cursor],
|
41
|
+
width: qrcode_size,
|
42
|
+
height: qrcode_size
|
43
|
+
}
|
44
|
+
insert_image(pdf, generate_qr_code_data(data[:emission_details][:qrcode_url], qrcode_size), opts)
|
45
|
+
end
|
46
|
+
private_class_method :generate_qr_code
|
47
|
+
|
48
|
+
def insert_image(pdf, image, options)
|
49
|
+
pdf.image(image, options)
|
50
|
+
pdf.move_down(options[:height])
|
51
|
+
end
|
52
|
+
private_class_method :insert_image
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module BrInvoicesPdf
|
4
|
+
module Nfce
|
5
|
+
module Renderer
|
6
|
+
module TaxesInfo
|
7
|
+
extend Util::BaseRenderer
|
8
|
+
extend BaseRenderer
|
9
|
+
|
10
|
+
module_function
|
11
|
+
|
12
|
+
def execute(pdf, data)
|
13
|
+
box(pdf, [0, pdf.cursor], page_content_width(pdf)) do
|
14
|
+
tribute_values(pdf, data[:additional_info])
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
# :reek:FeatureEnvy
|
19
|
+
def tribute_values(pdf, taxes)
|
20
|
+
pdf.text("Tributos\n\n", style: :italic)
|
21
|
+
text = "#{taxes}\n\n"
|
22
|
+
pdf.text(text, align: :center)
|
23
|
+
end
|
24
|
+
private_class_method :tribute_values
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module BrInvoicesPdf
|
4
|
+
module Nfce
|
5
|
+
module Renderer
|
6
|
+
module Totals
|
7
|
+
extend Util::BaseRenderer
|
8
|
+
extend BaseRenderer
|
9
|
+
|
10
|
+
module_function
|
11
|
+
|
12
|
+
def execute(pdf, data)
|
13
|
+
insert_box_info(pdf, data)
|
14
|
+
|
15
|
+
pdf.move_down(5)
|
16
|
+
end
|
17
|
+
|
18
|
+
def box_info(data_payment)
|
19
|
+
[
|
20
|
+
['Items', format_currency(data_payment[:items])],
|
21
|
+
['Total bruto', format_currency(data_payment[:subtotal])],
|
22
|
+
['Desconto', format_currency(data_payment[:discounts])],
|
23
|
+
['Total', format_currency(data_payment[:total])]
|
24
|
+
]
|
25
|
+
end
|
26
|
+
private_class_method :box_info
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|