# 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' 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]) end def render cabecalho corpo rodape @pdf.render end private 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 60 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