Skip to content

Instantly share code, notes, and snippets.

@romuloceccon
Created April 21, 2011 19:18
Show Gist options
  • Save romuloceccon/935279 to your computer and use it in GitHub Desktop.
Save romuloceccon/935279 to your computer and use it in GitHub Desktop.
# coding: utf-8
require 'rubygems'
require 'prawn'
require 'benchmark'
class Danfe
# Largura mínima da barra deve ser de 6 cm / 297 = 0,02 cm = 0,57 pt. A largura que usaremos
# será 0,70 pt = 0,025 cm = 7,33 cm / 297.
BAR_WIDTH = 0.7
PAGE_SIZE = 'A4'
MARGIN = [20, 20, 20, 20]
MAX_WIDTH = Prawn::Document::PageGeometry::SIZES[PAGE_SIZE][0] - (MARGIN[1] + MARGIN[3])
MAX_HEIGTH = Prawn::Document::PageGeometry::SIZES[PAGE_SIZE][1] - (MARGIN[0] + MARGIN[2])
LINE_WIDTH = 0.3
TEXT_BOX_RADIUS = 2
TEXT_BOX_HEIGTH = 20
LABEL_SIZE = 6
TEXT_SIZE = 10
SECTION_SPACING = LABEL_SIZE + 4
class Code128C
START_CODE_C = 105
STOP_CODE = 106
MODULO = 103
TABLE = [
[2, 1, 2, 2, 2, 2],
[2, 2, 2, 1, 2, 2],
[2, 2, 2, 2, 2, 1],
[1, 2, 1, 2, 2, 3],
[1, 2, 1, 3, 2, 2],
[1, 3, 1, 2, 2, 2],
[1, 2, 2, 2, 1, 3],
[1, 2, 2, 3, 1, 2],
[1, 3, 2, 2, 1, 2],
[2, 2, 1, 2, 1, 3],
[2, 2, 1, 3, 1, 2],
[2, 3, 1, 2, 1, 2],
[1, 1, 2, 2, 3, 2],
[1, 2, 2, 1, 3, 2],
[1, 2, 2, 2, 3, 1],
[1, 1, 3, 2, 2, 2],
[1, 2, 3, 1, 2, 2],
[1, 2, 3, 2, 2, 1],
[2, 2, 3, 2, 1, 1],
[2, 2, 1, 1, 3, 2],
[2, 2, 1, 2, 3, 1],
[2, 1, 3, 2, 1, 2],
[2, 2, 3, 1, 1, 2],
[3, 1, 2, 1, 3, 1],
[3, 1, 1, 2, 2, 2],
[3, 2, 1, 1, 2, 2],
[3, 2, 1, 2, 2, 1],
[3, 1, 2, 2, 1, 2],
[3, 2, 2, 1, 1, 2],
[3, 2, 2, 2, 1, 1],
[2, 1, 2, 1, 2, 3],
[2, 1, 2, 3, 2, 1],
[2, 3, 2, 1, 2, 1],
[1, 1, 1, 3, 2, 3],
[1, 3, 1, 1, 2, 3],
[1, 3, 1, 3, 2, 1],
[1, 1, 2, 3, 1, 3],
[1, 3, 2, 1, 1, 3],
[1, 3, 2, 3, 1, 1],
[2, 1, 1, 3, 1, 3],
[2, 3, 1, 1, 1, 3],
[2, 3, 1, 3, 1, 1],
[1, 1, 2, 1, 3, 3],
[1, 1, 2, 3, 3, 1],
[1, 3, 2, 1, 3, 1],
[1, 1, 3, 1, 2, 3],
[1, 1, 3, 3, 2, 1],
[1, 3, 3, 1, 2, 1],
[3, 1, 3, 1, 2, 1],
[2, 1, 1, 3, 3, 1],
[2, 3, 1, 1, 3, 1],
[2, 1, 3, 1, 1, 3],
[2, 1, 3, 3, 1, 1],
[2, 1, 3, 1, 3, 1],
[3, 1, 1, 1, 2, 3],
[3, 1, 1, 3, 2, 1],
[3, 3, 1, 1, 2, 1],
[3, 1, 2, 1, 1, 3],
[3, 1, 2, 3, 1, 1],
[3, 3, 2, 1, 1, 1],
[3, 1, 4, 1, 1, 1],
[2, 2, 1, 4, 1, 1],
[4, 3, 1, 1, 1, 1],
[1, 1, 1, 2, 2, 4],
[1, 1, 1, 4, 2, 2],
[1, 2, 1, 1, 2, 4],
[1, 2, 1, 4, 2, 1],
[1, 4, 1, 1, 2, 2],
[1, 4, 1, 2, 2, 1],
[1, 1, 2, 2, 1, 4],
[1, 1, 2, 4, 1, 2],
[1, 2, 2, 1, 1, 4],
[1, 2, 2, 4, 1, 1],
[1, 4, 2, 1, 1, 2],
[1, 4, 2, 2, 1, 1],
[2, 4, 1, 2, 1, 1],
[2, 2, 1, 1, 1, 4],
[4, 1, 3, 1, 1, 1],
[2, 4, 1, 1, 1, 2],
[1, 3, 4, 1, 1, 1],
[1, 1, 1, 2, 4, 2],
[1, 2, 1, 1, 4, 2],
[1, 2, 1, 2, 4, 1],
[1, 1, 4, 2, 1, 2],
[1, 2, 4, 1, 1, 2],
[1, 2, 4, 2, 1, 1],
[4, 1, 1, 2, 1, 2],
[4, 2, 1, 1, 1, 2],
[4, 2, 1, 2, 1, 1],
[2, 1, 2, 1, 4, 1],
[2, 1, 4, 1, 2, 1],
[4, 1, 2, 1, 2, 1],
[1, 1, 1, 1, 4, 3],
[1, 1, 1, 3, 4, 1],
[1, 3, 1, 1, 4, 1],
[1, 1, 4, 1, 1, 3],
[1, 1, 4, 3, 1, 1],
[4, 1, 1, 1, 1, 3],
[4, 1, 1, 3, 1, 1],
[1, 1, 3, 1, 4, 1],
[1, 1, 4, 1, 3, 1],
[3, 1, 1, 1, 4, 1],
[4, 1, 1, 1, 3, 1],
[2, 1, 1, 4, 1, 2],
[2, 1, 1, 2, 1, 4],
[2, 1, 1, 2, 3, 2],
[2, 3, 3, 1, 1, 1, 2]
]
def self.to_code_128c(str)
arr = str.scan(/\d{2}/).map { |x| x.to_i }
arr.unshift(START_CODE_C)
sum = START_CODE_C
arr.each_with_index { |x, i| sum += x * i }
arr << sum % MODULO
arr << STOP_CODE
arr.map { |x| TABLE[x] }.flatten
end
def self.draw_bar_code_128c(str, options)
min_width = options[:min_width]
total_width = options[:total_width]
start_pos = options[:start_pos]
bar_code = to_code_128c(str)
seg_count = bar_code.inject { |a, b| a + b }
x = start_pos + (total_width - seg_count * min_width) / 2.0
bar = true
bar_code.each do |w|
if bar
yield(x, w * min_width)
end
x += w * min_width
bar = !bar
end
end
end
class Layout
attr_reader :pdf
attr_accessor :x
public
def initialize
@pdf = Prawn::Document.new(:page_size => PAGE_SIZE, :margin => MARGIN)
@pdf.font('Times-Roman')
@pdf.line_width = LINE_WIDTH
@x = 0
@pdf.move_down(MARGIN[2])
end
def start_new_page
@pdf.start_new_page
@pdf.move_down(MARGIN[2])
end
def write(file_name)
@pdf.close_and_stroke
@pdf.render_file(file_name)
end
def text_box_with_box(label, text, width, height = nil, options = {})
@pdf.rounded_rectangle([@x, y], width, height || TEXT_BOX_HEIGTH, TEXT_BOX_RADIUS)
@pdf.text_box(label, :size => LABEL_SIZE, :at => [@x + 2, y - 2], :width => width - 2,
:height => LABEL_SIZE, :valign => :top)
h_text = height.nil? ? TEXT_SIZE : height - LABEL_SIZE - 4
@pdf.text_box(text, { :size => TEXT_SIZE, :at => [@x + 2, y - LABEL_SIZE - 4],
:width => width - 2, :height => h_text, :valign => :top }.merge(options))
@x += width
end
def header_cell(text, width, align = :left)
t = Prawn::Text::Box.new(text, :size => LABEL_SIZE, :at => [@x + 1, y],
:width => abs_width(width) - 2, :align => align, :document => @pdf)
t.render
@x += abs_width(width)
t.height
end
def cell(text, width, align = :left, options = {})
dry_run = options.delete(:dry_run)
t = Prawn::Text::Box.new(text, options.merge({ :at => [@x + 1, y],
:width => abs_width(width) - 2, :align => align, :document => @pdf }))
t.render(:dry_run => dry_run)
@x += abs_width(width) unless dry_run
t.height
end
def text_box(text, params = {})
t = Prawn::Text::Box.new(text, params.merge({ :document => @pdf }))
t.render
t.height
end
def receipt_box(label, content, start, stop)
unless content.empty?
@pdf.text_box(content, :size => 10, :at => [MAX_WIDTH * start, y - 21],
:width => MAX_WIDTH * (stop - start), :align => :center)
end
@pdf.text_box(label, :size => 6, :at => [MAX_WIDTH * start, y - 33],
:width => MAX_WIDTH * (stop - start), :align => :center)
@pdf.horizontal_line(MAX_WIDTH * start, MAX_WIDTH * stop, :at => y - 30)
end
def cell_break
@x = 0
@pdf.move_down(10)
end
def space(width)
@x += width
end
def line_break
@x = 0
@pdf.move_down(TEXT_BOX_HEIGTH)
end
def row
@x = 0
@pdf.pad_bottom(TEXT_BOX_HEIGTH) do
yield Row.new(self)
end
end
def section(name, options = {})
at = options[:at]
old_y = y
@pdf.move_cursor_to(at - MARGIN[2]) if at
begin
@x = 0
@pdf.pad_bottom(SECTION_SPACING) do
@pdf.text_box(name, :size => LABEL_SIZE, :style => :bold, :at => [0, y - 4],
:width => MAX_WIDTH, :height => LABEL_SIZE, :valign => :top)
end
yield
ensure
@pdf.move_cursor_to(old_y) if at
end
end
def abs_width(x)
x / 100.0 * MAX_WIDTH
end
def y
@pdf.y
end
def move_down(v)
@pdf.move_down(v)
end
def table(headers, data, widths, align, cell_options = {}, table_options = {})
move_down(2)
y0 = y
h = 0
@x = 0
widths.each_with_index do |w, i|
h = [header_cell(headers[i], w, :center), h].max
end
heigth_calc = table_options[:heigth_calc]
min_y = table_options[:min_y] || 0.0
while !data.empty?
r = data.first
if heigth_calc
h_calc = cell(r[heigth_calc], widths[heigth_calc], align[heigth_calc], cell_options.merge({ :dry_run => true }))
#print y - (h + 1 + 3 + h_calc + 1), ' < ', min_y, "\n"
if y - (h + 1 + 3 + h_calc + 1) < min_y
break
end
end
@pdf.pad_top(h + 1) do
@pdf.horizontal_line(0, abs_width(100), :at => y)
end
move_down(3)
h = 0
@x = 0
widths.each_with_index do |w, i|
h = [cell(r[i] || '', w, align[i], cell_options), h].max
end
data.shift
end
move_down(h + 1)
y1 = y
@pdf.stroke do
widths.inject do |sum, x|
@pdf.vertical_line(y0 + 2, y1, :at => abs_width(sum))
sum + x
end
@pdf.rounded_rectangle([0, y0 + 2], MAX_WIDTH, y0 - y1 + 2, TEXT_BOX_RADIUS)
end
#puts y
end
class Row
def initialize(layout)
@layout = layout
end
def text_box_with_box(relative_width, label, text)
@layout.text_box_with_box(label, text, abs_width(relative_width))
end
def space(relative_width)
@layout.space(abs_width(relative_width))
end
private
def abs_width(relative_width)
if relative_width == :max
MAX_WIDTH - @layout.x
else
relative_width / 100.0 * MAX_WIDTH
end
end
end
end
def initialize(data)
@layout = Layout.new
@page_infos = []
@data = data
@chave = data[:chave_nfe_formatada]
@bar_code_box_width = 2 + @layout.pdf.width_of(@chave, :size => 9, :style => :bold)
@formulario_seguranca = !@data[:formulario_seguranca].to_i.zero?
@fs_warning_height = @formulario_seguranca ? 20 : 0
end
def columnize_array(arr, count)
lines = (arr.count + count - 1) / count
item_len = arr.first.count
(0...lines).map do |line|
(0...count).map { |i| arr[i * count + line] || [nil] * item_len }.flatten
end
end
def draw_header
hs = 83
hq = hp = nil
@layout.pdf.stroke do
@page_infos[@layout.pdf.page_number - 1] = { :center_box_top => @layout.y }
emitente_box_width = MAX_WIDTH * (1 - 0.02 - 0.20) - @bar_code_box_width
@layout.pdf.rounded_rectangle([0, @layout.y], emitente_box_width, hs - 2,
TEXT_BOX_RADIUS)
logo_width = 72
img = Prawn::Images::PNG.new(File.binread(@data[:nome_logo]))
@layout.pdf.image(@data[:nome_logo], :at => [(logo_width - img.width * 0.24) / 2.0,
@layout.y - (hs - 2 - img.height * 0.24) / 2.0], :scale => 0.24)
i1 = @layout.y - 4
i1 -= @layout.text_box(@data[:nome_emitente], :style => :bold, :size => 12,
:at => [logo_width, i1], :width => emitente_box_width - logo_width, :align => :left)
i1 -= 6
i1 -= @layout.text_box(@data[:dados_emitente],
:style => :bold, :size => 8, :at => [logo_width, i1], :width => emitente_box_width - logo_width, :align => :left)
i1 -= 2
hx = hs + 6 + 2 * TEXT_BOX_HEIGTH
@layout.pdf.rounded_rectangle([MAX_WIDTH - @bar_code_box_width, @layout.y],
@bar_code_box_width, hx, TEXT_BOX_RADIUS)
hq = @layout.y - (hx - 2 * TEXT_BOX_HEIGTH) / 2
@layout.pdf.horizontal_line(MAX_WIDTH - @bar_code_box_width, MAX_WIDTH, :at => hq)
@layout.text_box("CHAVE DE ACESSO", :size => LABEL_SIZE,
:at => [MAX_WIDTH - @bar_code_box_width + 2, hq - 2])
@layout.text_box(@chave, :size => 9, :style => :bold,
:at => [MAX_WIDTH - @bar_code_box_width, hq - 10], :width => @bar_code_box_width, :align => :center)
@layout.pdf.horizontal_line(MAX_WIDTH - @bar_code_box_width, MAX_WIDTH, :at => hq - TEXT_BOX_HEIGTH)
unless @formulario_seguranca
@layout.text_box("Consulta de autenticidade no portal nacional\nda NF-e (www.nfe.fazenda.gov.br/portal)\nou no site da Sefaz Autorizadora",
:size => 9, :style => :bold, :width => @bar_code_box_width, :align => :center,
:valign => :center, :at => [MAX_WIDTH - @bar_code_box_width, hq - TEXT_BOX_HEIGTH],
:height => (hx - 2 * TEXT_BOX_HEIGTH) / 2)
end
hp = @layout.y - (hx - TEXT_BOX_HEIGTH)
@layout.pdf.horizontal_line(MAX_WIDTH - @bar_code_box_width, MAX_WIDTH, :at => hp)
@layout.text_box(@data[:titulo_dados_nfe], :size => LABEL_SIZE,
:at => [MAX_WIDTH - @bar_code_box_width + 2, hp - 2])
@layout.text_box(@data[:conteudo_dados_nfe], :size => 9, :style => :bold,
:at => [MAX_WIDTH - @bar_code_box_width, hp - 10], :width => @bar_code_box_width, :align => :center)
end
bar_code_height = @layout.y - hq
bar_code_y0 = hq + bar_code_height * 0.85
bar_code_y1 = hq + bar_code_height * 0.15
Code128C.draw_bar_code_128c(@chave, :min_width => BAR_WIDTH, :total_width => @bar_code_box_width,
:start_pos => MAX_WIDTH - @bar_code_box_width) do |x, w|
@layout.pdf.stroke do
@layout.pdf.line_width = w
@layout.pdf.vertical_line(bar_code_y0, bar_code_y1, :at => x + w / 2.0)
end
end
bar_code_y0 = hp + bar_code_height * 0.85
bar_code_y1 = hp + bar_code_height * 0.15
if @formulario_seguranca
Code128C.draw_bar_code_128c(@data[:conteudo_dados_nfe],
:min_width => BAR_WIDTH, :total_width => @bar_code_box_width,
:start_pos => MAX_WIDTH - @bar_code_box_width) do |x, w|
@layout.pdf.stroke do
@layout.pdf.line_width = w
@layout.pdf.vertical_line(bar_code_y0, bar_code_y1, :at => x + w / 2.0)
end
end
end
@layout.pdf.line_width = LINE_WIDTH
@layout.move_down(hs + 6)
natureza_operacao_width = 99 - @bar_code_box_width / MAX_WIDTH * 100
@layout.row do |r|
r.text_box_with_box(natureza_operacao_width, 'NATUREZA DE OPERAÇÃO', @data[:natureza_operacao])
end
@layout.row do |r|
r.text_box_with_box(natureza_operacao_width / 3, 'INSCRIÇÃO ESTADUAL', @data[:inscricao_estadual_emitente])
r.text_box_with_box(natureza_operacao_width / 3, 'INSCR. ESTADUAL DO SUBST.', @data[:inscricao_estadual_st_emitente])
r.text_box_with_box(natureza_operacao_width / 3, 'CNPJ', @data[:cnpj_emitente])
end
end
def draw_center_info
center_info_left = MAX_WIDTH * (1 - 0.21) - @bar_code_box_width
@page_infos.each_with_index do |info, i|
p = i + 1
y = info[:center_box_top]
@layout.pdf.go_to_page(p)
h1 = @layout.text_box("DANFE", :style => :bold, :size => 12, :at => [center_info_left, y],
:width => MAX_WIDTH * 0.2, :align => :center)
h2 = @layout.text_box("DOCUMENTO AUXILIAR DA NOTA FISCAL ELETRÔNICA", :size => 8,
:at => [center_info_left, y - (h1 + 6)], :width => MAX_WIDTH * 0.2,
:align => :center)
hs = h1 + 6 + h2 + 6
[['TIPO:', 'ENTRADA'], ['Nº:', @data[:numero]], ['SÉRIE:', @data[:serie]], ['FOLHA:', "#{p}/#{@layout.pdf.page_count}"]].each do |x|
hi = @layout.text_box(x[0], :size => 10,
:at => [center_info_left, y - hs], :width => MAX_WIDTH * 0.08,
:align => :right)
@layout.text_box(x[1], :style => :bold, :size => 10,
:at => [center_info_left + MAX_WIDTH * 0.09, y - hs],
:width => MAX_WIDTH * 0.11, :align => :left)
hs += hi + 2
end
end
end
def draw
@layout.pdf.stroke do
txt = "Recebemos de #{@data[:nome_emitente]} os produtos e/ou serviços constantes "\
"na Nota Fiscal Eletrônica indicada ao lado."
@layout.pdf.text_box(txt, :size => 8, :at => [MAX_WIDTH * 0.02, @layout.y],
:width => MAX_WIDTH * (0.8 - 0.04 - 0.02), :valign => :top)
@layout.receipt_box('DATA DE RECEBIMENTO', @data[:data_entrada_saida] || @data[:data_emissao], 0.02, 0.20)
@layout.receipt_box('IDENTIFICAÇÃO E ASSINATURA DO RECEBEDOR', '', 0.24, 0.76)
@layout.pdf.text_box("NF-e", :style => :bold, :size => 10, :at => [MAX_WIDTH * 0.8, @layout.y],
:width => MAX_WIDTH * 0.2, :align => :center)
@layout.pdf.text_box("Nº #{@data[:numero]}\nSÉRIE #{@data[:serie]}", :size => 10, :at => [MAX_WIDTH * 0.8, @layout.y - 16],
:width => MAX_WIDTH * 0.2, :align => :center)
@layout.pdf.vertical_line(@layout.y, @layout.y - 44, :at => MAX_WIDTH * 0.8)
end
@layout.pdf.dash(2)
@layout.pdf.stroke do
@layout.pdf.horizontal_line(0, MAX_WIDTH, :at => @layout.y - 44)
end
@layout.pdf.undash
@layout.move_down(44 + SECTION_SPACING)
draw_header
@layout.section('DESTINATÁRIO/REMETENTE') do
@layout.row do |r|
r.text_box_with_box(65, 'NOME/RAZÃO SOCIAL', @data[:nome_destinatario])
r.text_box_with_box(20, 'CNPJ/CPF', @data[:cnpj_destinatario])
r.space(1)
r.text_box_with_box(:max, 'DATA DE EMISSÃO', @data[:data_emissao])
end
@layout.row do |r|
r.text_box_with_box(50, 'ENDEREÇO', @data[:logradouro_destinatario])
r.text_box_with_box(25, 'BAIRRO/DISTRITO', @data[:bairro_destinatario])
r.text_box_with_box(10, 'CEP', @data[:cep_destinatario])
r.space(1)
r.text_box_with_box(:max, 'DATA DE SAÍDA', @data[:data_entrada_saida])
end
@layout.row do |r|
r.text_box_with_box(45, 'MUNICÍPIO', @data[:municipio_destinatario])
r.text_box_with_box(18, 'FONE/FAX', @data[:telefone_destinatario])
r.text_box_with_box(7, 'UF', @data[:uf_destinatario])
r.text_box_with_box(15, 'INSCRIÇÃO ESTADUAL', @data[:inscricao_estadual_destinatario])
r.space(1)
r.text_box_with_box(:max, 'HORA DE SAÍDA', @data[:hora_entrada_saida])
end
end
unless @data[:duplicatas].empty?
@layout.section('FATURA/DUPLICATA') do
duplicatas = @data[:duplicatas].map { |x| [x[:numero], x[:data_vencimento], x[:valor]] }
@layout.table(
['NÚMERO', 'VENCIMENTO', 'VALOR'] * 3,
columnize_array(duplicatas, 3),
[11.11, 11.11, 11.11, 11.11, 11.11, 11.11, 11.11, 11.11, 11.12],
[:center, :center, :right, :center, :center, :right, :center, :center, :right],
:size => LABEL_SIZE)
end
end
@layout.section('CÁLCULO DE IMPOSTO') do
@layout.row do |r|
r.text_box_with_box(20, 'BASE DE CÁLCULO DO ICMS', @data[:icms_base_calculo])
r.text_box_with_box(20, 'VALOR DO ICMS', @data[:icms_valor_total])
r.text_box_with_box(20, 'BASE DE CÁLCULO DO ICMS ST', @data[:icms_base_calculo_st])
r.text_box_with_box(20, 'VALOR DO ICMS ST', @data[:icms_valor_total_st])
r.text_box_with_box(:max, 'VALOR TOTAL DOS PRODUTOS', @data[:valor_produtos])
end
@layout.row do |r|
r.text_box_with_box(16, 'VALOR DO FRETE', @data[:valor_frete])
r.text_box_with_box(16, 'VALOR DO SEGURO', @data[:valor_seguro])
r.text_box_with_box(16, 'DESCONTO', @data[:valor_desconto])
r.text_box_with_box(16, 'OUTRAS DESPESAS', @data[:valor_outras_despesas])
r.text_box_with_box(16, 'VALOR DO IPI', @data[:valor_ipi])
r.text_box_with_box(:max, 'VALOR TOTAL DA NOTA', @data[:valor_total])
end
end
@layout.section('TRANSPORTADOR') do
@layout.row do |r|
r.text_box_with_box(30, 'NOME/RAZÃO SOCIAL', @data[:nome_transportador])
r.text_box_with_box(15, 'FRETE POR CONTA', @data[:modalidade_frete])
r.text_box_with_box(15, 'CÓDIGO ANTT', @data[:veiculo_rntc])
r.text_box_with_box(15, 'PLACA DO VEÍCULO', @data[:veiculo_placa])
r.text_box_with_box(7, 'UF', @data[:veiculo_uf])
r.text_box_with_box(:max, 'CNPJ/CPF', @data[:cnpj_transportador])
end
@layout.row do |r|
r.text_box_with_box(40, 'ENDEREÇO', @data[:endereco_transportador])
r.text_box_with_box(35, 'MUNICÍPIO', @data[:municipio_transportador])
r.text_box_with_box(7, 'UF', @data[:uf_transportador])
r.text_box_with_box(:max, 'INSCRIÇÃO ESTADUAL', @data[:inscricao_estadual_transportador])
end
end
@layout.section('VOLUMES TRANSPORTADOS') do
volumes = @data[:volumes].map { |x| [x[:quantidade], x[:especie], x[:marca], x[:numero],
x[:peso_liquido], x[:peso_bruto], nil] }
@layout.table(
['QUANTIDADE', 'ESPÉCIE', 'MARCA', 'NUMERAÇÃO', 'PESO BRUTO', 'PESO LÍQUIDO', ''],
volumes,
[11.11, 11.11, 11.11, 11.11, 11.11, 11.11, 33.34],
[:right, :left, :left, :left, :right, :right],
:size => LABEL_SIZE)
end
#icms_w = (@layout.pdf.width_of('15,00', :size => 8) + 2) / MAX_WIDTH * 100
#ipi_w = (@layout.pdf.width_of('15,00', :size => 8) + 2) / MAX_WIDTH * 100
reservado_ao_fisco_width = 212
reservado_ao_fisco_height = 84
table_data = @data[:itens].map { |x| [x[:codigo_produto], x[:descricao], x[:codigo_ncm],
x[:icms_item_situacao_tributaria], x[:cfop], x[:unidade_comercial],
x[:quantidade_comercial], x[:valor_unitario_comercial], x[:valor_bruto],
x[:icms_item_base_calculo], x[:icms_item_valor], x[:ipi_item_valor],
x[:icms_item_aliquota], x[:ipi_item_aliquota]] }
@layout.section('DADOS DOS PRODUTOS/SERVIÇOS') do
@layout.table(
['CÓD. PROD.', 'DESCRIÇÃO', 'NCM/SH', 'CST', 'CFOP', 'UNID.', 'QUANT.', 'VALOR UNIT.',
'VALOR TOTAL', 'BC ICMS', 'VALOR ICMS', 'VALOR IPI', 'ALÍQ. ICMS', 'ALÍQ. IPI'],
table_data,
[5, 28, 7, 4, 4, 5, 7, 7, 7, 7, 4, 7, 4, 4],
[:left, :left, :left, :left, :left, :left, :right,
:right, :right, :right, :right, :right, :right, :right],
{ :size => LABEL_SIZE },
{ :heigth_calc => 1, :min_y => reservado_ao_fisco_height + SECTION_SPACING + @fs_warning_height })
end
@layout.section('DADOS ADICIONAIS', :at => reservado_ao_fisco_height + SECTION_SPACING + @fs_warning_height) do
@layout.pdf.stroke do
@layout.text_box_with_box('INFORMAÇÕES ADICIONAIS', @data[:informacoes_adicionais_contribuinte],
MAX_WIDTH - reservado_ao_fisco_width, reservado_ao_fisco_height, :size => LABEL_SIZE)
@layout.text_box_with_box('RESERVADO AO FISCO', '',
reservado_ao_fisco_width, reservado_ao_fisco_height)
end
end
@layout.pdf.text_box("DANFE impresso em contingência devido a problemas técnicos",
:style => :bold, :size => 12, :at => [0, @fs_warning_height], :width => MAX_WIDTH, :valign => :bottom,
:align => :center)
while !table_data.empty?
@layout.start_new_page
draw_header
@layout.section('DADOS DOS PRODUTOS/SERVIÇOS') do
@layout.table(
['CÓD. PROD.', 'DESCRIÇÃO', 'NCM/SH', 'CST', 'CFOP', 'UNID.', 'QUANT.', 'VALOR UNIT.',
'VALOR TOTAL', 'BC ICMS', 'VALOR ICMS', 'VALOR IPI', 'ALÍQ. ICMS', 'ALÍQ. IPI'],
table_data,
[5, 28, 7, 4, 4, 5, 7, 7, 7, 7, 4, 7, 4, 4],
[:left, :left, :left, :left, :left, :left, :right,
:right, :right, :right, :right, :right, :right, :right],
{ :size => LABEL_SIZE },
{ :heigth_calc => 1, :min_y => @fs_warning_height })
end
@layout.pdf.text_box("DANFE impresso em contingência devido a problemas técnicos",
:style => :bold, :size => 12, :at => [0, @fs_warning_height], :width => MAX_WIDTH, :valign => :bottom,
:align => :center)
end
draw_center_info
@layout.write("prawn.pdf")
end
end
$informacoes_adicionais_contribuinte = <<EOS
I - "DOCUMENTO EMITIDO POR ME OU EPP OPTANTE PELO SIMPLES NACIONAL";
II - "NÃO GERA DIREITO A CRÉDITO FISCAL DE ICMS, DE ISS E DE IPI".
ASM-8948 ASM-8994 ASM-8995 ASM-8996 ASM-9112 ASM-9128 ASM-9129 ASM-9130 ASM-9131 ASM-9132 ASM-9133 ASM-9134 ASM-9135 ASM-9136 ASM-9087 ASM-9093 ASM-9097 ASM-9102 ASM-9103 ASM-9104 ASM-9105 ASM-9106 ASM-9107 ASM-9108 ASM-9075 ASM-9076 ASM-9078 ASM-9079 ASM-9081 ASM-9082 ASM-9083 ASM-9084 ASM-9085 ASM-9086 ASM-9062 ASM-9065 ASM-9066 ASM-9067 ASM-9068 ASM-9069 ASM-9071 ASM-9072 ASM-9073 ASM-9074 ASM-9044 ASM-9045 ASM-9046 ASM-9047 ASM-9048 ASM-9049 ASM-9054 ASM-9055 ASM-9057 ASM-9061 ASM-9028 ASM-9029 ASM-9031 ASM-9032 ASM-9034 ASM-9035 ASM-9039 ASM-9040 ASM-9041 ASM-9043 ASM-9015 ASM-9016 ASM-9017 ASM-9018 ASM-9019 ASM-9021 ASM-9024 ASM-9025 ASM-9026 ASM-9027 ASM-9027 ASM-8904 ASM-8939 ASM-8940 ASM-8941 ASM-8942 ASM-8943 ASM-8944 ASM-8945 ASM-8946 ASM-8947 ASM-8795 ASM-8879 ASM-8891 ASM-8892 ASM-8893 ASM-8895 ASM-8897 ASM-8901 ASM-8902 ASM-8903 ASM-8779 ASM-8781 ASM-8782 ASM-8784 ASM-8785 ASM-8786 ASM-8789 ASM-8792 ASM-8793 ASM-8794 ASM-9137 ASM-8766 ASM-8769 ASM-8770 ASM-8771 ASM-8772 ASM-8773 ASM-8774 ASM-8775 ASM-8776
EOS
$campos = {
:nome_logo => 'logo_adega_sul.png',
:chave_nfe => '41110504505771000191550010000004161391758308',
:ambiente => '2',
:chave_nfe_formatada => '4111 0504 5057 7100 0191 5500 1000 0004 1613 9175 8308',
#:formulario_seguranca => '0',
#:titulo_dados_nfe => 'PROTOCOLO DE AUTORIZAÇÃO DE USO',
#:conteudo_dados_nfe => '11090123456789 10/01/2011 10:00:00',
:formulario_seguranca => '1',
:titulo_dados_nfe => 'DADOS DA NF-E',
:conteudo_dados_nfe => '412030889240001800000000004540012257',
:forma_emissao => '1',
:numero => '10200',
:serie => '900',
:nome_emitente => 'Reciclamix Tamandaré Comércio de Materiais Recicláveis Ltda.',
:dados_emitente => "R. Justo Manfron, 1620 - Lamenha\nPequena - Almirante Tamandaré - PR\nCEP: 83.508-185 - Tel.: (41) 3272-1013",
:cnpj_emitente => '10.364.208/0001-43',
:inscricao_estadual_emitente => '9050417546',
:inscricao_estadual_st_emitente => '',
:informacoes_adicionais_contribuinte => $informacoes_adicionais_contribuinte,
:natureza_operacao => 'Venda',
:tipo_documento => '1',
:data_emissao => '10/01/2011',
:data_entrada_saida => '10/01/2011',
:hora_entrada_saida => '0:00:00',
:nome_destinatario => 'ANTONIO GENESIO CHAVES PEREIRA',
:cnpj_destinatario => '09.147.813/0001-83',
:inscricao_estadual_destinatario => '271259213',
:logradouro_destinatario => 'RUA BAHIA, 60 A',
:bairro_destinatario => '18 DO FORTE',
:municipio_destinatario => 'Aracaju',
:uf_destinatario => 'SE',
:cep_destinatario => '49.072-050',
:telefone_destinatario => '',
:valor_produtos => '907,83',
:valor_desconto => '0,01',
:valor_total => '907,82',
:icms_base_calculo => '907,83',
:icms_valor_total => '63,55',
:icms_base_calculo_st => '0,00',
:icms_valor_total_st => '0,00',
:valor_ipi => '0,00',
:valor_outras_despesas => '0,00',
:valor_frete => '0,00',
:valor_seguro => '0,00',
:modalidade_frete => 'Do destinatário',
:nome_transportador => '',
:cnpj_transportador => '',
:inscricao_estadual_transportador => '',
:endereco_transportador => '',
:municipio_transportador => '',
:uf_transportador => '',
:veiculo_placa => '',
:veiculo_uf => '',
:veiculo_rntc => '',
:numero_protocolo => '11090123456789',
:duplicatas => [
{
:numero => '000070-1',
:data_vencimento => '18/03/2010',
:valor => '961,50'
},
{
:numero => '000070-2',
:data_vencimento => '18/03/2010',
:valor => '961,50'
},
{
:numero => '000070-3',
:data_vencimento => '18/03/2010',
:valor => '961,50'
},
{
:numero => '000070-4',
:data_vencimento => '17/01/2011',
:valor => '978,32'
},
{
:numero => '000070-5',
:data_vencimento => '17/01/2011',
:valor => '978,32'
},
{
:numero => '000070-6',
:data_vencimento => '17/01/2011',
:valor => '978,32'
},
{
:numero => '000070-7',
:data_vencimento => '18/03/2010',
:valor => '978,30'
}
],
:volumes => [
{
:quantidade => '1',
:especie => 'CAIXA',
:marca => '',
:numero => '',
:peso_liquido => '',
:peso_bruto => ''
},
{
:quantidade => '4',
:especie => 'PACOTE',
:marca => '',
:numero => '',
:peso_liquido => '',
:peso_bruto => ''
}
],
:itens => [
{
:codigo_produto => 'TN05V',
:codigo_ncm => '39199000',
:valor_unitario_comercial => '2,5217',
:unidade_comercial => 'M',
:quantidade_comercial => '300,00',
:valor_bruto => '756,52',
:cfop => '6102',
:ipi_item_aliquota => '15,00',
:ipi_item_valor => '0,00',
:descricao => 'CARROCERIA ABERTA C/ 5,65M 5101 UN DE COMPR., COLOCADA EM M.BENZ 1620; CHASSI 9BM695014YB236958; PLACA MBY-5669',
:icms_item_situacao_tributaria => '100',
:icms_item_base_calculo => '756,52',
:icms_item_aliquota => '7,00',
:icms_item_valor => '52,96'
}
]
}
m = Benchmark.measure do
danfe = Danfe.new($campos)
danfe.draw
end
puts m
`cmd /c start prawn.pdf`
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment