134 lines
4.4 KiB
Ruby
134 lines
4.4 KiB
Ruby
# app/services/pdf/base_pdf.rb
|
|
#
|
|
# Layout base dos PDFs da Gade: cabeçalho preto com logo laranja,
|
|
# rodapé com data de geração. Herdar e implementar #corpo.
|
|
#
|
|
module Pdf
|
|
class BasePdf
|
|
LARANJA = 'F97316'
|
|
PRETO = '0A0A0A'
|
|
CINZA = '6B7280'
|
|
|
|
# Fonte TrueType com suporte total a UTF-8. As fontes embutidas do Prawn
|
|
# (AFM/Helvetica) só aceitam o charset Windows-1252 e estouram
|
|
# Prawn::Errors::IncompatibleStringEncoding em caracteres como "✓".
|
|
FONTS_DIR = Rails.root.join('app', 'assets', 'fonts')
|
|
|
|
def initialize
|
|
# Margem inferior folgada (72) para o rodapé repetido (desenhado em y=20)
|
|
# não sobrepor o conteúdo.
|
|
@pdf = Prawn::Document.new(page_size: 'A4', margin: [40, 40, 72, 40])
|
|
registrar_fonte_utf8
|
|
end
|
|
|
|
def render
|
|
cabecalho
|
|
corpo
|
|
rodape
|
|
@pdf.render
|
|
end
|
|
|
|
private
|
|
|
|
# Registra a família DejaVu Sans (TTF) e a define como fonte padrão.
|
|
# Como os PDFs só usam normal e :bold, mapeamos italic/bold_italic para
|
|
# as variantes existentes, evitando erro caso :italic seja solicitado.
|
|
def registrar_fonte_utf8
|
|
normal = FONTS_DIR.join('DejaVuSans.ttf').to_s
|
|
bold = FONTS_DIR.join('DejaVuSans-Bold.ttf').to_s
|
|
|
|
@pdf.font_families.update(
|
|
'DejaVu' => {
|
|
normal: normal,
|
|
bold: bold,
|
|
italic: normal,
|
|
bold_italic: bold
|
|
}
|
|
)
|
|
@pdf.font 'DejaVu'
|
|
end
|
|
|
|
def cabecalho
|
|
@pdf.fill_color PRETO
|
|
@pdf.fill_rectangle [-40, @pdf.cursor + 40], @pdf.bounds.width + 80, 70
|
|
|
|
@pdf.fill_color LARANJA
|
|
@pdf.fill_rectangle [-40 + 0, @pdf.cursor + 40], 8, 70 # faixa laranja lateral
|
|
|
|
@pdf.fill_color 'FFFFFF'
|
|
@pdf.text_box 'REEM TRANSPORTE',
|
|
at: [10, @pdf.cursor + 20], size: 20, style: :bold
|
|
@pdf.fill_color LARANJA
|
|
@pdf.text_box 'Sistema de Controle de Custos Logísticos',
|
|
at: [10, @pdf.cursor - 4], size: 10
|
|
|
|
@pdf.fill_color '000000'
|
|
@pdf.move_down 55
|
|
end
|
|
|
|
def rodape
|
|
# canvas usa coordenadas absolutas da página, então o rodapé é desenhado
|
|
# DENTRO da margem inferior (y=36), abaixo da área de conteúdo. Antes ele
|
|
# ficava em y=20 do bounds — dentro do fluxo do conteúdo — e o texto da
|
|
# tabela acabava sobrepondo o "documento interno".
|
|
@pdf.repeat(:all) do
|
|
@pdf.canvas do
|
|
@pdf.fill_color CINZA
|
|
@pdf.text_box "Gerado em #{Time.current.strftime('%d/%m/%Y %H:%M')} · Reem Transporte — documento interno",
|
|
at: [40, 36], width: @pdf.bounds.width - 80,
|
|
size: 8, align: :center
|
|
@pdf.fill_color '000000'
|
|
end
|
|
end
|
|
end
|
|
|
|
def moeda(v)
|
|
"R$ #{format('%.2f', v.to_f)}".gsub('.', ',')
|
|
end
|
|
|
|
# Bloco de assinaturas lado a lado: motorista (esquerda) e administrador
|
|
# (direita). Garante espaço criando nova página se o rodapé estiver perto.
|
|
def assinaturas(motorista: nil)
|
|
@pdf.start_new_page if @pdf.cursor < 120
|
|
@pdf.move_down 36
|
|
|
|
metade = (@pdf.bounds.width - 40) / 2.0
|
|
topo = @pdf.cursor
|
|
|
|
@pdf.stroke_color '000000'
|
|
@pdf.line_width 0.7
|
|
@pdf.stroke_horizontal_line 0, metade, at: topo
|
|
@pdf.stroke_horizontal_line metade + 40, @pdf.bounds.width, at: topo
|
|
|
|
@pdf.move_down 8
|
|
linha_nome = @pdf.cursor
|
|
@pdf.fill_color '000000'
|
|
@pdf.text_box(motorista.presence || 'Motorista',
|
|
at: [0, linha_nome], width: metade, size: 9, style: :bold, align: :center)
|
|
@pdf.text_box('Reem Transporte',
|
|
at: [metade + 40, linha_nome], width: metade, size: 9, style: :bold, align: :center)
|
|
|
|
@pdf.move_down 14
|
|
linha_rotulo = @pdf.cursor
|
|
@pdf.fill_color CINZA
|
|
@pdf.text_box('Assinatura do Motorista',
|
|
at: [0, linha_rotulo], width: metade, size: 8, align: :center)
|
|
@pdf.text_box('Assinatura do Administrador',
|
|
at: [metade + 40, linha_rotulo], width: metade, size: 8, align: :center)
|
|
|
|
@pdf.fill_color '000000'
|
|
@pdf.move_down 24
|
|
end
|
|
|
|
def secao(titulo)
|
|
@pdf.move_down 14
|
|
@pdf.fill_color LARANJA
|
|
@pdf.text titulo, size: 13, style: :bold
|
|
@pdf.stroke_color LARANJA
|
|
@pdf.stroke_horizontal_rule
|
|
@pdf.fill_color '000000'
|
|
@pdf.move_down 8
|
|
end
|
|
end
|
|
end
|