Files
aperonight/app/controllers/tickets_controller.rb
2025-09-06 01:44:48 +02:00

127 lines
4.2 KiB
Ruby

# Tickets controller - handles ticket viewing and downloads with SEO-friendly URLs
#
# This controller manages individual ticket display and downloads
# Uses event-slug-ticket-id format for SEO-friendly URLs
class TicketsController < ApplicationController
before_action :authenticate_user!
before_action :set_ticket_from_seo_params, only: [:show, :view, :download, :retry_payment]
# Display ticket details
def show
@event = @ticket.event
end
# Display ticket in PDF-like format
def view
@event = @ticket.event
end
# Download PDF ticket - only accessible by ticket owner
# User must be authenticated to download ticket
def download
# Generate PDF using Grover
begin
Rails.logger.info "Starting PDF generation for ticket ID: #{@ticket.id}"
# Render the HTML template
html = render_to_string(
partial: "tickets/pdf_ticket",
layout: false,
locals: { ticket: @ticket }
)
Rails.logger.info "HTML template rendered successfully, length: #{html.length}"
# Configure Grover options for PDF generation
pdf_options = {
format: 'A4',
margin: {
top: '0.5in',
bottom: '0.5in',
left: '0.5in',
right: '0.5in'
},
print_background: true,
display_header_footer: false,
prefer_css_page_size: true,
launch_args: ["--no-sandbox", "--disable-setuid-sandbox"] # For better compatibility
}
# Generate PDF
pdf = Grover.new(html, pdf_options).to_pdf
Rails.logger.info "PDF generation completed for ticket ID: #{@ticket.id}"
# Send PDF as download with SEO-friendly filename
send_data pdf,
filename: "billet-#{@ticket.event.slug}-#{@ticket.id}.pdf",
type: 'application/pdf',
disposition: 'attachment'
rescue => e
Rails.logger.error "PDF generation failed for ticket ID: #{@ticket.id} - Error: #{e.message}"
Rails.logger.error e.backtrace.join("\n")
redirect_to view_ticket_path(event_slug: @ticket.event.slug, ticket_id: @ticket.id),
alert: "Erreur lors de la génération du PDF. Veuillez réessayer."
end
end
# Redirect retry payment to order system
def retry_payment
# Look for draft order for this ticket's event
order = current_user.orders.find_by(event: @ticket.event, status: "draft")
if order&.can_retry_payment?
year = order.event.start_time.year
month = format("%02d", order.event.start_time.month)
redirect_to event_checkout_path(year: year, month: month, slug: order.event.slug)
else
redirect_to seo_event_path(@ticket.event),
alert: "Aucune commande disponible pour un nouveau paiement"
end
end
# Legacy redirects for backward compatibility
def payment_success
redirect_to booking_payment_success_path(session_id: params[:session_id])
end
def payment_cancel
redirect_to booking_payment_cancelled_path
end
private
def set_ticket_from_seo_params
# Parse event_slug and ticket_id from the SEO-friendly format: event-slug-123
slug_and_id = params[:event_slug_ticket_id] || "#{params[:event_slug]}-#{params[:ticket_id]}"
# Split by last dash to separate event slug from ticket ID
parts = slug_and_id.split('-')
ticket_id = parts.pop
event_slug = parts.join('-')
# Find ticket and ensure it belongs to current user
@ticket = Ticket.joins(order: :user)
.includes(:event, :ticket_type, order: :user)
.joins(:event)
.where(
tickets: { id: ticket_id },
orders: { user_id: current_user.id },
events: { slug: event_slug }
)
.first
unless @ticket
redirect_to dashboard_path, alert: "Billet non trouvé ou vous n'avez pas l'autorisation d'accéder à ce billet"
end
end
# Generate SEO-friendly path for an event
def seo_event_path(event)
year = event.start_time.year
month = format("%02d", event.start_time.month)
event_path(year: year, month: month, slug: event.slug)
end
helper_method :seo_event_path
end