style: correct coding style with rubocop linter
This commit is contained in:
@@ -5,8 +5,8 @@ module Api
|
||||
module V1
|
||||
class EventsController < ApiController
|
||||
# Skip API key authentication for store_cart action (used by frontend forms)
|
||||
skip_before_action :authenticate_api_key, only: [:store_cart]
|
||||
|
||||
skip_before_action :authenticate_api_key, only: [ :store_cart ]
|
||||
|
||||
# Charge l'évén avant certaines actions pour réduire les duplications
|
||||
before_action :set_event, only: [ :show, :update, :destroy, :store_cart ]
|
||||
|
||||
|
||||
@@ -10,9 +10,9 @@ module StripeConcern
|
||||
# but kept for backward compatibility
|
||||
def initialize_stripe
|
||||
return false unless stripe_configured?
|
||||
|
||||
|
||||
# Stripe is already initialized at application startup
|
||||
Rails.logger.debug "Stripe already initialized at application startup"
|
||||
true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -3,8 +3,7 @@
|
||||
# This controller manages all events. It load events for homepage
|
||||
# and display for pagination.
|
||||
class EventsController < ApplicationController
|
||||
|
||||
before_action :authenticate_user!, only: [ ]
|
||||
before_action :authenticate_user!, only: []
|
||||
before_action :set_event, only: [ :show ]
|
||||
|
||||
# Display all events
|
||||
@@ -27,5 +26,4 @@ class EventsController < ApplicationController
|
||||
def set_event
|
||||
@event = Event.includes(:ticket_types).find(params[:id])
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -4,12 +4,12 @@
|
||||
# Orders group multiple tickets together for better transaction management
|
||||
class OrdersController < ApplicationController
|
||||
before_action :authenticate_user!
|
||||
before_action :set_order, only: [:show, :checkout, :retry_payment, :increment_payment_attempt]
|
||||
before_action :set_event, only: [:new, :create]
|
||||
before_action :set_order, only: [ :show, :checkout, :retry_payment, :increment_payment_attempt ]
|
||||
before_action :set_event, only: [ :new, :create ]
|
||||
|
||||
# Display new order form with name collection
|
||||
#
|
||||
# On this page user can see order summary and complete the tickets details
|
||||
# On this page user can see order summary and complete the tickets details
|
||||
# (first name and last name) for each ticket ordered
|
||||
def new
|
||||
@cart_data = session[:pending_cart] || {}
|
||||
@@ -52,7 +52,7 @@ class OrdersController < ApplicationController
|
||||
end
|
||||
|
||||
success = false
|
||||
|
||||
|
||||
ActiveRecord::Base.transaction do
|
||||
@order = current_user.orders.create!(event: @event, status: "draft")
|
||||
|
||||
@@ -60,7 +60,7 @@ class OrdersController < ApplicationController
|
||||
next if ticket_attrs[:first_name].blank? || ticket_attrs[:last_name].blank?
|
||||
|
||||
ticket_type = @event.ticket_types.find(ticket_attrs[:ticket_type_id])
|
||||
|
||||
|
||||
ticket = @order.tickets.build(
|
||||
ticket_type: ticket_type,
|
||||
first_name: ticket_attrs[:first_name],
|
||||
@@ -82,7 +82,7 @@ class OrdersController < ApplicationController
|
||||
raise ActiveRecord::Rollback
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
# Handle redirects outside transaction
|
||||
if success
|
||||
session[:draft_order_id] = @order.id
|
||||
@@ -260,7 +260,7 @@ class OrdersController < ApplicationController
|
||||
end
|
||||
|
||||
Stripe::Checkout::Session.create(
|
||||
payment_method_types: ["card"],
|
||||
payment_method_types: [ "card" ],
|
||||
line_items: line_items,
|
||||
mode: "payment",
|
||||
success_url: order_payment_success_url + "?session_id={CHECKOUT_SESSION_ID}",
|
||||
|
||||
@@ -20,8 +20,8 @@ class PagesController < ApplicationController
|
||||
# Metrics for dashboard cards
|
||||
@booked_events = current_user.orders.joins(tickets: { ticket_type: :event })
|
||||
.where(events: { state: :published })
|
||||
.where(orders: { status: ['paid', 'completed'] })
|
||||
.sum('1')
|
||||
.where(orders: { status: [ "paid", "completed" ] })
|
||||
.sum("1")
|
||||
@events_today = Event.published.where("DATE(start_time) = ?", Date.current).count
|
||||
@events_tomorrow = Event.published.where("DATE(start_time) = ?", Date.current + 1).count
|
||||
@upcoming_events = Event.published.upcoming.count
|
||||
@@ -33,7 +33,7 @@ class PagesController < ApplicationController
|
||||
.limit(5)
|
||||
|
||||
# Draft orders that can be retried
|
||||
@draft_orders = current_user.orders.includes(tickets: [:ticket_type, :event])
|
||||
@draft_orders = current_user.orders.includes(tickets: [ :ticket_type, :event ])
|
||||
.can_retry_payment
|
||||
.order(:expires_at)
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
class Promoter::EventsController < ApplicationController
|
||||
before_action :authenticate_user!
|
||||
before_action :ensure_can_manage_events!
|
||||
before_action :set_event, only: [:show, :edit, :update, :destroy, :publish, :unpublish, :cancel, :mark_sold_out]
|
||||
before_action :set_event, only: [ :show, :edit, :update, :destroy, :publish, :unpublish, :cancel, :mark_sold_out ]
|
||||
|
||||
# Display all events for the current promoter
|
||||
def index
|
||||
@@ -25,9 +25,9 @@ class Promoter::EventsController < ApplicationController
|
||||
# Create a new event
|
||||
def create
|
||||
@event = current_user.events.build(event_params)
|
||||
|
||||
|
||||
if @event.save
|
||||
redirect_to promoter_event_path(@event), notice: 'Event créé avec succès!'
|
||||
redirect_to promoter_event_path(@event), notice: "Event créé avec succès!"
|
||||
else
|
||||
render :new, status: :unprocessable_entity
|
||||
end
|
||||
@@ -41,7 +41,7 @@ class Promoter::EventsController < ApplicationController
|
||||
# Update an existing event
|
||||
def update
|
||||
if @event.update(event_params)
|
||||
redirect_to promoter_event_path(@event), notice: 'Event mis à jour avec succès!'
|
||||
redirect_to promoter_event_path(@event), notice: "Event mis à jour avec succès!"
|
||||
else
|
||||
render :edit, status: :unprocessable_entity
|
||||
end
|
||||
@@ -50,16 +50,16 @@ class Promoter::EventsController < ApplicationController
|
||||
# Delete an event
|
||||
def destroy
|
||||
@event.destroy
|
||||
redirect_to promoter_events_path, notice: 'Event supprimé avec succès!'
|
||||
redirect_to promoter_events_path, notice: "Event supprimé avec succès!"
|
||||
end
|
||||
|
||||
# Publish an event (make it visible to public)
|
||||
def publish
|
||||
if @event.draft?
|
||||
@event.update(state: :published)
|
||||
redirect_to promoter_event_path(@event), notice: 'Event publié avec succès!'
|
||||
redirect_to promoter_event_path(@event), notice: "Event publié avec succès!"
|
||||
else
|
||||
redirect_to promoter_event_path(@event), alert: 'Cet event ne peut pas être publié.'
|
||||
redirect_to promoter_event_path(@event), alert: "Cet event ne peut pas être publié."
|
||||
end
|
||||
end
|
||||
|
||||
@@ -67,9 +67,9 @@ class Promoter::EventsController < ApplicationController
|
||||
def unpublish
|
||||
if @event.published?
|
||||
@event.update(state: :draft)
|
||||
redirect_to promoter_event_path(@event), notice: 'Event dépublié avec succès!'
|
||||
redirect_to promoter_event_path(@event), notice: "Event dépublié avec succès!"
|
||||
else
|
||||
redirect_to promoter_event_path(@event), alert: 'Cet event ne peut pas être dépublié.'
|
||||
redirect_to promoter_event_path(@event), alert: "Cet event ne peut pas être dépublié."
|
||||
end
|
||||
end
|
||||
|
||||
@@ -77,9 +77,9 @@ class Promoter::EventsController < ApplicationController
|
||||
def cancel
|
||||
if @event.published?
|
||||
@event.update(state: :canceled)
|
||||
redirect_to promoter_event_path(@event), notice: 'Event annulé avec succès!'
|
||||
redirect_to promoter_event_path(@event), notice: "Event annulé avec succès!"
|
||||
else
|
||||
redirect_to promoter_event_path(@event), alert: 'Cet event ne peut pas être annulé.'
|
||||
redirect_to promoter_event_path(@event), alert: "Cet event ne peut pas être annulé."
|
||||
end
|
||||
end
|
||||
|
||||
@@ -87,9 +87,9 @@ class Promoter::EventsController < ApplicationController
|
||||
def mark_sold_out
|
||||
if @event.published?
|
||||
@event.update(state: :sold_out)
|
||||
redirect_to promoter_event_path(@event), notice: 'Event marqué comme complet!'
|
||||
redirect_to promoter_event_path(@event), notice: "Event marqué comme complet!"
|
||||
else
|
||||
redirect_to promoter_event_path(@event), alert: 'Cet event ne peut pas être marqué comme complet.'
|
||||
redirect_to promoter_event_path(@event), alert: "Cet event ne peut pas être marqué comme complet."
|
||||
end
|
||||
end
|
||||
|
||||
@@ -97,14 +97,14 @@ class Promoter::EventsController < ApplicationController
|
||||
|
||||
def ensure_can_manage_events!
|
||||
unless current_user.can_manage_events?
|
||||
redirect_to dashboard_path, alert: 'Vous n\'avez pas les permissions nécessaires pour gérer des événements.'
|
||||
redirect_to dashboard_path, alert: "Vous n'avez pas les permissions nécessaires pour gérer des événements."
|
||||
end
|
||||
end
|
||||
|
||||
def set_event
|
||||
@event = current_user.events.find(params[:id])
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
redirect_to promoter_events_path, alert: 'Event non trouvé ou vous n\'avez pas accès à cet event.'
|
||||
redirect_to promoter_events_path, alert: "Event non trouvé ou vous n'avez pas accès à cet event."
|
||||
end
|
||||
|
||||
def event_params
|
||||
@@ -114,4 +114,4 @@ class Promoter::EventsController < ApplicationController
|
||||
:start_time, :end_time, :featured
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -6,7 +6,7 @@ class Promoter::TicketTypesController < ApplicationController
|
||||
before_action :authenticate_user!
|
||||
before_action :ensure_can_manage_events!
|
||||
before_action :set_event
|
||||
before_action :set_ticket_type, only: [:show, :edit, :update, :destroy]
|
||||
before_action :set_ticket_type, only: [ :show, :edit, :update, :destroy ]
|
||||
|
||||
# Display all ticket types for an event
|
||||
def index
|
||||
@@ -30,9 +30,9 @@ class Promoter::TicketTypesController < ApplicationController
|
||||
# Create a new ticket type
|
||||
def create
|
||||
@ticket_type = @event.ticket_types.build(ticket_type_params)
|
||||
|
||||
|
||||
if @ticket_type.save
|
||||
redirect_to promoter_event_ticket_types_path(@event), notice: 'Type de billet créé avec succès!'
|
||||
redirect_to promoter_event_ticket_types_path(@event), notice: "Type de billet créé avec succès!"
|
||||
else
|
||||
render :new, status: :unprocessable_entity
|
||||
end
|
||||
@@ -46,7 +46,7 @@ class Promoter::TicketTypesController < ApplicationController
|
||||
# Update an existing ticket type
|
||||
def update
|
||||
if @ticket_type.update(ticket_type_params)
|
||||
redirect_to promoter_event_ticket_type_path(@event, @ticket_type), notice: 'Type de billet mis à jour avec succès!'
|
||||
redirect_to promoter_event_ticket_type_path(@event, @ticket_type), notice: "Type de billet mis à jour avec succès!"
|
||||
else
|
||||
render :edit, status: :unprocessable_entity
|
||||
end
|
||||
@@ -55,10 +55,10 @@ class Promoter::TicketTypesController < ApplicationController
|
||||
# Delete a ticket type
|
||||
def destroy
|
||||
if @ticket_type.tickets.any?
|
||||
redirect_to promoter_event_ticket_types_path(@event), alert: 'Impossible de supprimer ce type de billet car des billets ont déjà été vendus.'
|
||||
redirect_to promoter_event_ticket_types_path(@event), alert: "Impossible de supprimer ce type de billet car des billets ont déjà été vendus."
|
||||
else
|
||||
@ticket_type.destroy
|
||||
redirect_to promoter_event_ticket_types_path(@event), notice: 'Type de billet supprimé avec succès!'
|
||||
redirect_to promoter_event_ticket_types_path(@event), notice: "Type de billet supprimé avec succès!"
|
||||
end
|
||||
end
|
||||
|
||||
@@ -67,11 +67,11 @@ class Promoter::TicketTypesController < ApplicationController
|
||||
original = @event.ticket_types.find(params[:id])
|
||||
@ticket_type = original.dup
|
||||
@ticket_type.name = "#{original.name} (Copie)"
|
||||
|
||||
|
||||
if @ticket_type.save
|
||||
redirect_to edit_promoter_event_ticket_type_path(@event, @ticket_type), notice: 'Type de billet dupliqué avec succès!'
|
||||
redirect_to edit_promoter_event_ticket_type_path(@event, @ticket_type), notice: "Type de billet dupliqué avec succès!"
|
||||
else
|
||||
redirect_to promoter_event_ticket_types_path(@event), alert: 'Erreur lors de la duplication.'
|
||||
redirect_to promoter_event_ticket_types_path(@event), alert: "Erreur lors de la duplication."
|
||||
end
|
||||
end
|
||||
|
||||
@@ -79,20 +79,20 @@ class Promoter::TicketTypesController < ApplicationController
|
||||
|
||||
def ensure_can_manage_events!
|
||||
unless current_user.can_manage_events?
|
||||
redirect_to dashboard_path, alert: 'Vous n\'avez pas les permissions nécessaires pour gérer des événements.'
|
||||
redirect_to dashboard_path, alert: "Vous n'avez pas les permissions nécessaires pour gérer des événements."
|
||||
end
|
||||
end
|
||||
|
||||
def set_event
|
||||
@event = current_user.events.find(params[:event_id])
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
redirect_to promoter_events_path, alert: 'Event non trouvé ou vous n\'avez pas accès à cet event.'
|
||||
redirect_to promoter_events_path, alert: "Event non trouvé ou vous n'avez pas accès à cet event."
|
||||
end
|
||||
|
||||
def set_ticket_type
|
||||
@ticket_type = @event.ticket_types.find(params[:id])
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
redirect_to promoter_event_ticket_types_path(@event), alert: 'Type de billet non trouvé.'
|
||||
redirect_to promoter_event_ticket_types_path(@event), alert: "Type de billet non trouvé."
|
||||
end
|
||||
|
||||
def ticket_type_params
|
||||
@@ -101,4 +101,4 @@ class Promoter::TicketTypesController < ApplicationController
|
||||
:sale_start_at, :sale_end_at, :minimum_age, :requires_id
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -36,10 +36,10 @@ class TicketsController < ApplicationController
|
||||
# Redirect retry payment to order system
|
||||
def retry_payment
|
||||
@event = Event.includes(:ticket_types).find(params[:id])
|
||||
|
||||
|
||||
# Look for draft order for this event
|
||||
order = current_user.orders.find_by(event: @event, status: "draft")
|
||||
|
||||
|
||||
if order&.can_retry_payment?
|
||||
redirect_to retry_payment_order_path(order)
|
||||
else
|
||||
@@ -58,15 +58,15 @@ class TicketsController < ApplicationController
|
||||
|
||||
def set_event
|
||||
event_id = params[:id] || session[:event_id]
|
||||
|
||||
|
||||
Rails.logger.debug "TicketsController#set_event - params[:id]: #{params[:id].inspect}, session[:event_id]: #{session[:event_id].inspect}"
|
||||
|
||||
|
||||
unless event_id
|
||||
Rails.logger.error "TicketsController#set_event - No event ID found"
|
||||
redirect_to events_path, alert: "Aucun événement spécifié"
|
||||
return
|
||||
end
|
||||
|
||||
|
||||
@event = Event.includes(:ticket_types).find(event_id)
|
||||
Rails.logger.debug "TicketsController#set_event - Found event: #{@event.id} - #{@event.name}"
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
|
||||
@@ -6,7 +6,7 @@ module ApplicationHelper
|
||||
|
||||
# Include flash message helpers
|
||||
include FlashMessagesHelper
|
||||
|
||||
|
||||
# Include Stripe helper
|
||||
include StripeHelper
|
||||
end
|
||||
|
||||
@@ -1,28 +1,28 @@
|
||||
module LucideHelper
|
||||
# Create a Lucide icon element
|
||||
#
|
||||
#
|
||||
# @param name [String] The name of the Lucide icon
|
||||
# @param options [Hash] Additional options
|
||||
# @option options [String] :class Additional CSS classes
|
||||
# @option options [String] :size Size class (e.g., 'w-4 h-4', 'w-6 h-6')
|
||||
# @option options [Hash] :data Additional data attributes
|
||||
#
|
||||
#
|
||||
# @return [String] HTML string for the icon
|
||||
#
|
||||
# Usage:
|
||||
# lucide_icon('user')
|
||||
# lucide_icon('user')
|
||||
# lucide_icon('check-circle', class: 'text-green-500', size: 'w-5 h-5')
|
||||
# lucide_icon('menu', data: { action: 'click->header#toggleMenu' })
|
||||
def lucide_icon(name, options = {})
|
||||
css_classes = ["lucide-icon"]
|
||||
css_classes = [ "lucide-icon" ]
|
||||
css_classes << options[:size] if options[:size]
|
||||
css_classes << options[:class] if options[:class]
|
||||
|
||||
|
||||
data_attributes = { lucide: name }
|
||||
data_attributes.merge!(options[:data]) if options[:data]
|
||||
|
||||
content_tag :i, "",
|
||||
class: css_classes.join(" "),
|
||||
|
||||
content_tag :i, "",
|
||||
class: css_classes.join(" "),
|
||||
data: data_attributes,
|
||||
**options.except(:class, :size, :data)
|
||||
end
|
||||
@@ -35,23 +35,23 @@ module LucideHelper
|
||||
# @option options [String] :class Additional CSS classes for button
|
||||
# @option options [String] :icon_class Additional CSS classes for icon
|
||||
# @option options [String] :icon_size Size class for icon
|
||||
#
|
||||
#
|
||||
# Usage:
|
||||
# lucide_button('plus', text: 'Add Item', class: 'btn btn-primary')
|
||||
# lucide_button('trash-2', class: 'btn-danger', data: { confirm: 'Are you sure?' })
|
||||
def lucide_button(name, options = {})
|
||||
text = options.delete(:text)
|
||||
icon_class = options.delete(:icon_class)
|
||||
icon_size = options.delete(:icon_size) || 'w-4 h-4'
|
||||
|
||||
icon_size = options.delete(:icon_size) || "w-4 h-4"
|
||||
|
||||
icon = lucide_icon(name, class: icon_class, size: icon_size)
|
||||
|
||||
|
||||
content = if text.present?
|
||||
safe_join([icon, " ", text])
|
||||
else
|
||||
safe_join([ icon, " ", text ])
|
||||
else
|
||||
icon
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
content_tag :button, content, options
|
||||
end
|
||||
|
||||
@@ -60,23 +60,23 @@ module LucideHelper
|
||||
# @param name [String] The name of the Lucide icon
|
||||
# @param url [String] The URL for the link
|
||||
# @param options [Hash] Link options
|
||||
#
|
||||
#
|
||||
# Usage:
|
||||
# lucide_link('edit', edit_user_path(user), text: 'Edit')
|
||||
# lucide_link('external-link', 'https://example.com', text: 'Visit', target: '_blank')
|
||||
def lucide_link(name, url, options = {})
|
||||
text = options.delete(:text)
|
||||
icon_class = options.delete(:icon_class)
|
||||
icon_size = options.delete(:icon_size) || 'w-4 h-4'
|
||||
|
||||
icon_size = options.delete(:icon_size) || "w-4 h-4"
|
||||
|
||||
icon = lucide_icon(name, class: icon_class, size: icon_size)
|
||||
|
||||
|
||||
content = if text.present?
|
||||
safe_join([icon, " ", text])
|
||||
else
|
||||
safe_join([ icon, " ", text ])
|
||||
else
|
||||
icon
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
link_to content, url, options
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -3,10 +3,10 @@ module StripeHelper
|
||||
def safe_stripe_call(&block)
|
||||
# Check if Stripe is properly configured
|
||||
return nil unless Rails.application.config.stripe[:secret_key].present?
|
||||
|
||||
|
||||
# Stripe is now initialized at application startup
|
||||
Rails.logger.debug "Using globally initialized Stripe"
|
||||
|
||||
|
||||
begin
|
||||
yield if block_given?
|
||||
rescue Stripe::StripeError => e
|
||||
@@ -14,4 +14,4 @@ module StripeHelper
|
||||
nil
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -3,7 +3,7 @@ class CleanupExpiredDraftsJob < ApplicationJob
|
||||
|
||||
def perform
|
||||
expired_count = 0
|
||||
|
||||
|
||||
Ticket.expired_drafts.find_each do |ticket|
|
||||
Rails.logger.info "Expiring draft ticket #{ticket.id} for user #{ticket.user_id}"
|
||||
ticket.expire_if_overdue!
|
||||
@@ -12,4 +12,4 @@ class CleanupExpiredDraftsJob < ApplicationJob
|
||||
|
||||
Rails.logger.info "Expired #{expired_count} draft tickets" if expired_count > 0
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -4,9 +4,9 @@ class ExpiredOrdersCleanupJob < ApplicationJob
|
||||
def perform
|
||||
# Find and expire all draft orders that have passed their expiry time
|
||||
expired_orders = Order.expired_drafts
|
||||
|
||||
|
||||
Rails.logger.info "Found #{expired_orders.count} expired orders to process"
|
||||
|
||||
|
||||
expired_orders.find_each do |order|
|
||||
begin
|
||||
order.expire_if_overdue!
|
||||
@@ -17,7 +17,7 @@ class ExpiredOrdersCleanupJob < ApplicationJob
|
||||
next
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
Rails.logger.info "Completed expired orders cleanup job"
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,21 +1,21 @@
|
||||
class TicketMailer < ApplicationMailer
|
||||
default from: 'notifications@aperonight.com'
|
||||
default from: "notifications@aperonight.com"
|
||||
|
||||
def purchase_confirmation(ticket)
|
||||
@ticket = ticket
|
||||
@user = ticket.user
|
||||
@event = ticket.event
|
||||
|
||||
|
||||
# Generate PDF attachment
|
||||
pdf = @ticket.to_pdf
|
||||
attachments["ticket-#{@event.name.parameterize}-#{@ticket.qr_code[0..7]}.pdf"] = {
|
||||
mime_type: 'application/pdf',
|
||||
mime_type: "application/pdf",
|
||||
content: pdf
|
||||
}
|
||||
|
||||
|
||||
mail(
|
||||
to: @user.email,
|
||||
subject: "Confirmation d'achat - #{@event.name}"
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -48,5 +48,4 @@ class Event < ApplicationRecord
|
||||
|
||||
# Scope for published events ordered by start time
|
||||
scope :upcoming, -> { published.where("start_time >= ?", Time.current).order(start_time: :asc) }
|
||||
|
||||
end
|
||||
|
||||
@@ -90,4 +90,4 @@ class Order < ApplicationRecord
|
||||
def draft?
|
||||
status == "draft"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -12,7 +12,7 @@ class TicketType < ApplicationRecord
|
||||
validates :sale_end_at, presence: true
|
||||
validates :minimum_age, numericality: { only_integer: true, greater_than_or_equal_to: 0, less_than_or_equal_to: 120 }, allow_nil: true
|
||||
validates :event_id, presence: true
|
||||
validates :requires_id, inclusion: { in: [true, false] }
|
||||
validates :requires_id, inclusion: { in: [ true, false ] }
|
||||
|
||||
# Custom validations
|
||||
validate :sale_end_after_start
|
||||
@@ -22,7 +22,7 @@ class TicketType < ApplicationRecord
|
||||
scope :available_now, -> { where("sale_start_at <= ? AND sale_end_at >= ?", Time.current, Time.current) }
|
||||
scope :upcoming, -> { where("sale_start_at > ?", Time.current) }
|
||||
scope :expired, -> { where("sale_end_at < ?", Time.current) }
|
||||
|
||||
|
||||
# Helper methods
|
||||
def price_euros
|
||||
return 0.0 if price_cents.nil?
|
||||
@@ -45,7 +45,7 @@ class TicketType < ApplicationRecord
|
||||
|
||||
def available_quantity
|
||||
return 0 if quantity.nil?
|
||||
[quantity - tickets.count, 0].max
|
||||
[ quantity - tickets.count, 0 ].max
|
||||
end
|
||||
|
||||
def sales_status
|
||||
@@ -53,7 +53,7 @@ class TicketType < ApplicationRecord
|
||||
return :expired if sale_end_at < Time.current
|
||||
return :upcoming if sale_start_at > Time.current
|
||||
return :sold_out if sold_out?
|
||||
return :available
|
||||
:available
|
||||
end
|
||||
|
||||
def total_potential_revenue
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
require 'prawn'
|
||||
require 'prawn/qrcode'
|
||||
require 'rqrcode'
|
||||
require "prawn"
|
||||
require "prawn/qrcode"
|
||||
require "rqrcode"
|
||||
|
||||
class TicketPdfGenerator
|
||||
attr_reader :ticket
|
||||
@@ -10,7 +10,7 @@ class TicketPdfGenerator
|
||||
end
|
||||
|
||||
def generate
|
||||
Prawn::Document.new(page_size: [350, 600], margin: 20) do |pdf|
|
||||
Prawn::Document.new(page_size: [ 350, 600 ], margin: 20) do |pdf|
|
||||
# Header
|
||||
pdf.fill_color "2D1B69"
|
||||
pdf.font "Helvetica", style: :bold, size: 24
|
||||
@@ -26,7 +26,7 @@ class TicketPdfGenerator
|
||||
# Ticket info box
|
||||
pdf.stroke_color "E5E7EB"
|
||||
pdf.fill_color "F9FAFB"
|
||||
pdf.rounded_rectangle [0, pdf.cursor], 310, 120, 10
|
||||
pdf.rounded_rectangle [ 0, pdf.cursor ], 310, 120, 10
|
||||
pdf.fill_and_stroke
|
||||
|
||||
pdf.move_down 10
|
||||
@@ -82,7 +82,7 @@ class TicketPdfGenerator
|
||||
|
||||
qrcode = RQRCode::QRCode.new(qr_code_data)
|
||||
pdf.print_qr_code(qrcode, extent: 120, align: :center)
|
||||
|
||||
|
||||
pdf.move_down 15
|
||||
|
||||
# QR code text
|
||||
@@ -104,4 +104,4 @@ class TicketPdfGenerator
|
||||
pdf.text "Generated on #{Time.current.strftime('%B %d, %Y at %I:%M %p')}", align: :center
|
||||
end.render
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user