127 lines
4.2 KiB
Ruby
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 |