require "prawn" require "prawn/qrcode" require "rqrcode" # PDF ticket generator service using Prawn # # Generates PDF tickets with QR codes for event entry validation # Includes event details, venue information, and unique QR code for each ticket class TicketPdfGenerator # Suppress Prawn's internationalization warning for built-in fonts Prawn::Fonts::AFM.hide_m17n_warning = true attr_reader :ticket def initialize(ticket) @ticket = ticket end def generate Prawn::Document.new(page_size: [ 350, 600 ], margin: 20) do |pdf| # Header pdf.fill_color "2D1B69" pdf.font "Helvetica", style: :bold, size: 24 pdf.text "ApéroNight", align: :center pdf.move_down 10 # Event name pdf.fill_color "000000" pdf.font "Helvetica", style: :bold, size: 18 pdf.text ticket.event.name, align: :center pdf.move_down 20 # Ticket info box pdf.stroke_color "E5E7EB" pdf.fill_color "F9FAFB" pdf.rounded_rectangle [ 0, pdf.cursor ], 310, 150, 10 pdf.fill_and_stroke pdf.move_down 10 pdf.fill_color "000000" pdf.font "Helvetica", size: 12 # Customer name pdf.text "Ticket Holder:", style: :bold pdf.text "#{ticket.first_name} #{ticket.last_name}" pdf.move_down 8 # Ticket details pdf.text "Ticket Type:", style: :bold pdf.text ticket.ticket_type.name pdf.move_down 8 pdf.text "Price:", style: :bold pdf.text "€#{ticket.price_euros}" pdf.move_down 8 pdf.text "Date & Time:", style: :bold pdf.text ticket.event.start_time.strftime("%B %d, %Y at %I:%M %p") pdf.move_down 20 # Venue information pdf.fill_color "374151" pdf.font "Helvetica", style: :bold, size: 14 pdf.text "Venue Information" pdf.move_down 8 pdf.font "Helvetica", size: 11 pdf.text ticket.event.venue_name, style: :bold pdf.text ticket.event.venue_address pdf.move_down 20 # QR Code pdf.fill_color "000000" pdf.font "Helvetica", style: :bold, size: 14 pdf.text "Ticket QR Code", align: :center pdf.move_down 10 # Ensure all required data is present before generating QR code if ticket.qr_code.blank? raise "Ticket QR code is missing" end qr_code_data = { ticket_id: ticket.id, qr_code: ticket.qr_code, event_id: ticket.event&.id, user_id: ticket.user&.id }.compact.to_json # Validate QR code data before creating QR code if qr_code_data.blank? || qr_code_data == "{}" raise "QR code data is empty or invalid" end qrcode = RQRCode::QRCode.new(qr_code_data) pdf.print_qr_code(qrcode, extent: 120, align: :center) pdf.move_down 15 # QR code text pdf.font "Helvetica", size: 8 pdf.fill_color "6B7280" pdf.text "QR Code: #{ticket.qr_code[0..7]}...", align: :center # Footer pdf.move_down 30 pdf.stroke_color "E5E7EB" pdf.horizontal_line 0, 310 pdf.move_down 10 pdf.font "Helvetica", size: 8 pdf.fill_color "6B7280" pdf.text "This ticket is valid for one entry only.", align: :center pdf.text "Present this ticket at the venue entrance.", align: :center pdf.move_down 5 pdf.text "Generated on #{Time.current.strftime('%B %d, %Y at %I:%M %p')}", align: :center end.render end end