# frozen_string_literal: true begin require 'rghost' rescue LoadError require 'rubygems' unless ENV['NO_RUBYGEMS'] gem 'rghost' require 'rghost' end begin require 'rghost_barcode' rescue LoadError require 'rubygems' unless ENV['NO_RUBYGEMS'] gem 'rghost_barcode' require 'rghost_barcode' end module Brcobranca module Boleto module Template # Templates para usar com Rghost module Rghost2 extend self include RGhost unless include?(RGhost) RGhost::Config::GS[:external_encoding] = Brcobranca.configuration.external_encoding RGhost::Config::GS[:default_params] << '-dNOSAFER' RGhost::Config::GS[:unit] = Units::Cm # Gera o boleto em usando o formato desejado [:pdf, :jpg, :tif, :png, :ps, :laserjet, ... etc] # # @return [Stream] # @see http://wiki.github.com/shairontoledo/rghost/supported-devices-drivers-and-formats Veja mais formatos na documentação do rghost. # @see Rghost#modelo_generico Recebe os mesmos parâmetros do Rghost#modelo_generico. def to(formato, options = {}) modelo_generico(self, options.merge!(formato: formato)) end # Gera o boleto em usando o formato desejado [:pdf, :jpg, :tif, :png, :ps, :laserjet, ... etc] # # @return [Stream] # @see http://wiki.github.com/shairontoledo/rghost/supported-devices-drivers-and-formats Veja mais formatos na documentação do rghost. # @see Rghost#modelo_generico Recebe os mesmos parâmetros do Rghost#modelo_generico. def lote(boletos, options = {}) modelo_generico_multipage(boletos, options) end # Cria o métodos dinâmicos (to_pdf, to_gif e etc) com todos os fomátos válidos. # # @return [Stream] # @see Rghost#modelo_generico Recebe os mesmos parâmetros do Rghost#modelo_generico. # @example # @boleto.to_pdf #=> boleto gerado no formato pdf def method_missing(m, *args) method = m.to_s if method.start_with?('to_') modelo_generico(self, (args.first || {}).merge!(formato: method[3..])) else super end end private # Retorna um stream pronto para gravação em arquivo. # # @return [Stream] # @param [Boleto] Instância de uma classe de boleto. # @param [Hash] options Opção para a criação do boleto. # @option options [Symbol] :resolucao Resolução em pixels. # @option options [Symbol] :formato Formato desejado [:pdf, :jpg, :tif, :png, :ps, :laserjet, ... etc] def modelo_generico(boleto, options = {}) doc = Document.new paper: [21, 29.7] # A4 template_path = File.join(File.dirname(__FILE__), '..', '..', 'arquivos', 'templates', 'modelo_generico2.eps') raise 'Não foi possível encontrar o template. Verifique o caminho' unless File.exist?(template_path) modelo_recibo_beneficiario(doc, boleto) modelo_generico_template(doc, boleto, template_path) modelo_generico_cabecalho(doc, boleto) modelo_generico_rodape(doc, boleto) # Gerando stream formato = options.delete(:formato) || Brcobranca.configuration.formato resolucao = options.delete(:resolucao) || Brcobranca.configuration.resolucao doc.render_stream(formato.to_sym, resolution: resolucao) end # Retorna um stream para multiplos boletos pronto para gravação em arquivo. # # @return [Stream] # @param [Array] Instâncias de classes de boleto. # @param [Hash] options Opção para a criação do boleto. # @option options [Symbol] :resolucao Resolução em pixels. # @option options [Symbol] :formato Formato desejado [:pdf, :jpg, :tif, :png, :ps, :laserjet, ... etc] def modelo_generico_multipage(boletos, options = {}) doc = Document.new paper: [21, 29.7] # A4 template_path = File.join(File.dirname(__FILE__), '..', '..', 'arquivos', 'templates', 'modelo_generico2.eps') raise 'Não foi possível encontrar o template. Verifique o caminho' unless File.exist?(template_path) boletos.each_with_index do |boleto, index| modelo_generico_template(doc, boleto, template_path) modelo_recibo_beneficiario(doc, boleto) modelo_generico_cabecalho(doc, boleto) modelo_generico_rodape(doc, boleto) # Cria nova página se não for o último boleto doc.next_page unless index == boletos.length - 1 end # Gerando stream formato = options.delete(:formato) || Brcobranca.configuration.formato resolucao = options.delete(:resolucao) || Brcobranca.configuration.resolucao doc.render_stream(formato.to_sym, resolution: resolucao) end # Define o template a ser usado no boleto def modelo_generico_template(doc, _boleto, template_path) doc.define_template(:template, template_path, x: '0.732 cm', y: '3.48 cm') doc.use_template :template doc.define_tags do tag :menor, name: 'LiberationMono', size: 8 tag :menor2, name: 'LiberationMono', size: 6 tag :menor_bold, name: 'Helvetica-Bold', size: 8 tag :medio, name: 'Helvetica-Bold', size: 12 tag :maior, name: 'Helvetica-Bold', size: 13.5 end end # Monta Recibo do Beneficiário def modelo_recibo_beneficiario(doc, boleto) doc.moveto x: 4.28, y: 26.87 doc.show truncar(boleto.cedente, 90), tag: :menor doc.moveto x: 4.28, y: 26.33 doc.show truncar(boleto.sacado, 90), tag: :menor doc.moveto x: 4.28, y: 25.76 doc.show boleto.documento_numero, tag: :menor doc.moveto x: 4.28, y: 25.20 doc.show boleto.nosso_numero_boleto, tag: :menor doc.moveto x: 4.28, y: 24.63 doc.show boleto.data_vencimento.to_s_br, tag: :menor doc.moveto x: 4.28, y: 24.070 doc.show "#{boleto.banco}-#{boleto.banco_dv}", tag: :menor doc.moveto x: 4.28, y: 23.49 doc.show boleto.agencia_conta_boleto, tag: :menor doc.moveto x: 4.28, y: 22.95 doc.show boleto.valor_documento.to_currency, tag: :menor end # Monta Recibo do Pagador boleto def modelo_generico_cabecalho(doc, boleto) monta_logotipo(doc, boleto, 0.782, 19.717, 0.85) doc.moveto x: 4.813, y: 19.801 doc.show "#{boleto.banco}-#{boleto.banco_dv}", tag: :medio doc.moveto x: 0.823, y: 20.942 doc.show boleto.codigo_barras.linha_digitavel, tag: :menor_bold doc.moveto x: 1.121, y: 18.924 doc.show truncar(boleto.cedente, 47), tag: :menor doc.moveto x: 9.9, y: 18.924 doc.show boleto.agencia_conta_boleto.tr(' ', ''), tag: :menor doc.moveto x: 16.423, y: 18.924 doc.show boleto.nosso_numero_boleto, tag: :menor doc.moveto x: 1.121, y: 17.984 doc.show boleto.documento_numero, tag: :menor doc.moveto x: 14.139, y: 18.924 doc.show boleto.quantidade, tag: :menor doc.moveto x: 7.0, y: 17.984 doc.show boleto.documento_cedente.formata_documento.to_s, tag: :menor doc.moveto x: 10.602, y: 17.984 doc.show boleto.data_vencimento.to_s_br, tag: :menor doc.text_area "#{boleto.valor_documento.to_currency}", width: 5.78, text_align: :right, x: 14.12, y: 17.984, tag: :menor doc.moveto x: 1.109, y: 17.089 doc.show truncar(boleto.sacado, 109), tag: :menor end # Monta o corpo e rodapé do layout do boleto def modelo_generico_rodape(doc, boleto) monta_logotipo(doc, boleto, 0.782, 13.9, 0.85) doc.text_area "#{boleto.data_vencimento&.to_s_br}", width: 5.786, text_align: :center, x: 14.47271, y: 13.11587 doc.text_area "#{boleto.agencia_conta_boleto}", width: 5.786, text_align: :center, x: 14.47271, y: 12.26921 doc.text_area "#{boleto.nosso_numero_boleto}", width: 5.786, text_align: :center, x: 14.47271, y: 11.42254 doc.text_area "#{boleto.valor_documento.to_currency}", width: 5.5, text_align: :right, x: 14.47271, y: 10.56926 doc.moveto x: 4.813, y: 13.977 doc.show "#{boleto.banco}-#{boleto.banco_dv}", tag: :medio doc.moveto x: 6.815, y: 13.990 doc.show boleto.codigo_barras.linha_digitavel, tag: :maior doc.moveto x: 1.121, y: 13.2 doc.show boleto.local_pagamento, tag: :menor doc.moveto x: 1.121, y: 12.295 doc.show truncar(boleto.cedente, 54), tag: :menor doc.moveto x: 11.307, y: 12.295 doc.show boleto.documento_cedente.formata_documento.to_s, tag: :menor doc.moveto x: 1.112, y: 11.42 doc.show boleto.data_documento&.to_s_br, tag: :menor doc.moveto x: 4.268, y: 11.42 doc.show boleto.documento_numero, tag: :menor doc.moveto x: 7.471, y: 11.42 doc.show boleto.especie_documento, tag: :menor doc.moveto x: 9.588, y: 11.42 doc.show boleto.aceite, tag: :menor doc.moveto x: 11.660, y: 11.42 doc.show boleto.data_processamento&.to_s_br, tag: :menor doc.moveto x: 4.62056, y: 10.56058 if boleto.variacao doc.show "#{boleto.carteira}-#{boleto.variacao}" else doc.show boleto.carteira end doc.moveto x: 7.26640, y: 10.56058 doc.show boleto.especie monta_instrucoes(doc, boleto, 0.8, 9.8) pagador = "#{truncar(boleto.sacado, 75)} - CPF/CNPJ: #{boleto.sacado_documento.formata_documento}" pagador += "\n#{boleto.sacado_endereco}" if boleto.sacado_endereco doc.text_area pagador, width: 18, text_align: :left, x: 2.04611, y: 5.8, row_height: '0.4 cm' if boleto.avalista && boleto.avalista_documento avalista = "#{truncar(boleto.avalista, 46)} - CPF/CNPJ: #{boleto.avalista_documento.formata_documento}" end if avalista doc.text_area "#{avalista}", width: 12.312, text_align: :left, x: 2.04611, y: 4.3, row_height: '0.4 cm' end # Gerando codigo de barra com rghost_barcode return unless boleto.codigo_barras doc.barcode_interleaved2of5(boleto.codigo_barras, width: '10.3 cm', height: '1.3 cm', x: 1.06, y: 2.12) # FIM Segunda parte do BOLETO end def truncar(string, limite) string = "#{string[0...limite].upcase}..." if string.length > limite string end def monta_instrucoes(doc, boleto, x, y) lista_instrucoes = [ boleto.instrucoes, boleto.instrucao1, boleto.instrucao2, boleto.instrucao3, boleto.instrucao4, boleto.instrucao5, boleto.instrucao6 ].reject(&:blank?) lista_instrucoes = lista_instrucoes.map { |i| "#{i}" } texto_instrucoes = lista_instrucoes.join("\n") doc.text_area texto_instrucoes, width: 13.547, text_align: :left, x: x, y: y, row_height: '0.4 cm' end def monta_logotipo(doc, boleto, x, y, scale) doc.graphic do |g| g.scale(scale, scale) fator = 1 / scale g.image boleto.logotipo, x: (x * fator), y: (y * fator) end end end end end end