Remove unused code and dependencies
- Removed unused JavaScript controllers (shadcn_test, featured_event, event_form, ticket_type_form) - Removed unused React components (button.jsx and utils.js) - Removed duplicate env.example file - Removed unused Alpine.js dependencies from package.json - Updated controller registrations and dependency files - Added REFACTORING_SUMMARY.md with details of changes - Added new file: app/controllers/api/v1/orders_controller.rb
This commit is contained in:
279
app/controllers/api/v1/orders_controller.rb
Normal file
279
app/controllers/api/v1/orders_controller.rb
Normal file
@@ -0,0 +1,279 @@
|
||||
# API controller for order management
|
||||
# Provides RESTful endpoints for order operations
|
||||
|
||||
module Api
|
||||
module V1
|
||||
class OrdersController < ApiController
|
||||
before_action :authenticate_user!
|
||||
before_action :set_order, only: [ :show, :checkout, :retry_payment, :increment_payment_attempt ]
|
||||
before_action :set_event, only: [ :new, :create ]
|
||||
|
||||
# GET /api/v1/orders/new
|
||||
# Returns data needed for new order form
|
||||
def new
|
||||
cart_data = params[:cart_data] || session[:pending_cart] || {}
|
||||
|
||||
if cart_data.empty?
|
||||
render json: { error: "Veuillez d'abord sélectionner vos billets sur la page de l'événement" }, status: :bad_request
|
||||
return
|
||||
end
|
||||
|
||||
tickets_needing_names = []
|
||||
cart_data.each do |ticket_type_id, item|
|
||||
ticket_type = @event.ticket_types.find_by(id: ticket_type_id)
|
||||
next unless ticket_type
|
||||
|
||||
quantity = item["quantity"].to_i
|
||||
next if quantity <= 0
|
||||
|
||||
quantity.times do |i|
|
||||
tickets_needing_names << {
|
||||
ticket_type_id: ticket_type.id,
|
||||
ticket_type_name: ticket_type.name,
|
||||
ticket_type_price: ticket_type.price_cents,
|
||||
index: i
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
render json: { tickets_needing_names: tickets_needing_names }, status: :ok
|
||||
end
|
||||
|
||||
# POST /api/v1/orders
|
||||
# Creates a new order with tickets
|
||||
def create
|
||||
cart_data = params[:cart_data] || session[:pending_cart] || {}
|
||||
|
||||
if cart_data.empty?
|
||||
render json: { error: "Aucun billet sélectionné" }, status: :bad_request
|
||||
return
|
||||
end
|
||||
|
||||
success = false
|
||||
|
||||
ActiveRecord::Base.transaction do
|
||||
@order = current_user.orders.create!(event: @event, status: "draft")
|
||||
|
||||
order_params[:tickets_attributes]&.each do |index, ticket_attrs|
|
||||
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],
|
||||
last_name: ticket_attrs[:last_name],
|
||||
status: "draft"
|
||||
)
|
||||
|
||||
unless ticket.save
|
||||
render json: { error: "Erreur lors de la création des billets: #{ticket.errors.full_messages.join(', ')}" }, status: :unprocessable_entity
|
||||
raise ActiveRecord::Rollback
|
||||
end
|
||||
end
|
||||
|
||||
if @order.tickets.present?
|
||||
@order.calculate_total!
|
||||
success = true
|
||||
else
|
||||
render json: { error: "Aucun billet valide créé" }, status: :unprocessable_entity
|
||||
raise ActiveRecord::Rollback
|
||||
end
|
||||
end
|
||||
|
||||
if success
|
||||
session[:draft_order_id] = @order.id
|
||||
session.delete(:pending_cart)
|
||||
render json: { order: @order, redirect_to: checkout_order_path(@order) }, status: :created
|
||||
end
|
||||
rescue => e
|
||||
error_message = e.message.present? ? e.message : "Erreur inconnue"
|
||||
render json: { error: "Une erreur est survenue: #{error_message}" }, status: :internal_server_error
|
||||
end
|
||||
|
||||
# GET /api/v1/orders/:id
|
||||
# Returns order summary
|
||||
def show
|
||||
tickets = @order.tickets.includes(:ticket_type)
|
||||
render json: { order: @order, tickets: tickets }, status: :ok
|
||||
end
|
||||
|
||||
# GET /api/v1/orders/:id/checkout
|
||||
# Returns checkout data for an order
|
||||
def checkout
|
||||
if @order.expired?
|
||||
@order.expire_if_overdue!
|
||||
render json: { error: "Votre commande a expiré. Veuillez recommencer." }, status: :gone
|
||||
return
|
||||
end
|
||||
|
||||
tickets = @order.tickets.includes(:ticket_type)
|
||||
total_amount = @order.total_amount_cents
|
||||
expiring_soon = @order.expiring_soon?
|
||||
|
||||
checkout_session = nil
|
||||
if Rails.application.config.stripe[:secret_key].present?
|
||||
begin
|
||||
checkout_session = create_stripe_session
|
||||
rescue => e
|
||||
error_message = e.message.present? ? e.message : "Erreur Stripe inconnue"
|
||||
Rails.logger.error "Stripe checkout session creation failed: #{error_message}"
|
||||
render json: { error: "Erreur lors de la création de la session de paiement" }, status: :internal_server_error
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
render json: {
|
||||
order: @order,
|
||||
tickets: tickets,
|
||||
total_amount: total_amount,
|
||||
expiring_soon: expiring_soon,
|
||||
checkout_session: checkout_session
|
||||
}, status: :ok
|
||||
end
|
||||
|
||||
# PATCH /api/v1/orders/:id/increment_payment_attempt
|
||||
# Increments payment attempt counter
|
||||
def increment_payment_attempt
|
||||
@order.increment_payment_attempt!
|
||||
render json: { success: true, attempts: @order.payment_attempts }, status: :ok
|
||||
end
|
||||
|
||||
# POST /api/v1/orders/:id/retry_payment
|
||||
# Allows retrying payment for failed orders
|
||||
def retry_payment
|
||||
unless @order.can_retry_payment?
|
||||
render json: { error: "Cette commande ne peut plus être payée" }, status: :forbidden
|
||||
return
|
||||
end
|
||||
|
||||
render json: { redirect_to: checkout_order_path(@order) }, status: :ok
|
||||
end
|
||||
|
||||
# GET /api/v1/orders/payment_success
|
||||
# Handles successful payment confirmation
|
||||
def payment_success
|
||||
session_id = params[:session_id]
|
||||
|
||||
stripe_configured = Rails.application.config.stripe[:secret_key].present?
|
||||
Rails.logger.debug "Payment success - Stripe configured: #{stripe_configured}"
|
||||
|
||||
unless stripe_configured
|
||||
render json: { error: "Le système de paiement n'est pas correctement configuré. Veuillez contacter l'administrateur." }, status: :service_unavailable
|
||||
return
|
||||
end
|
||||
|
||||
begin
|
||||
stripe_session = Stripe::Checkout::Session.retrieve(session_id)
|
||||
|
||||
if stripe_session.payment_status == "paid"
|
||||
order_id = stripe_session.metadata["order_id"]
|
||||
|
||||
unless order_id.present?
|
||||
render json: { error: "Informations de commande manquantes" }, status: :bad_request
|
||||
return
|
||||
end
|
||||
|
||||
@order = current_user.orders.includes(tickets: :ticket_type).find(order_id)
|
||||
@order.mark_as_paid!
|
||||
|
||||
begin
|
||||
StripeInvoiceGenerationJob.perform_later(@order.id)
|
||||
Rails.logger.info "Scheduled Stripe invoice generation for order #{@order.id}"
|
||||
rescue => e
|
||||
Rails.logger.error "Failed to schedule invoice generation for order #{@order.id}: #{e.message}"
|
||||
end
|
||||
|
||||
@order.tickets.each do |ticket|
|
||||
begin
|
||||
TicketMailer.purchase_confirmation(ticket).deliver_now
|
||||
rescue => e
|
||||
Rails.logger.error "Failed to send confirmation email for ticket #{ticket.id}: #{e.message}"
|
||||
end
|
||||
end
|
||||
|
||||
session.delete(:pending_cart)
|
||||
session.delete(:ticket_names)
|
||||
session.delete(:draft_order_id)
|
||||
|
||||
render json: { order: @order, tickets: @order.tickets }, status: :ok
|
||||
else
|
||||
render json: { error: "Le paiement n'a pas été complété avec succès" }, status: :payment_required
|
||||
end
|
||||
rescue Stripe::StripeError => e
|
||||
error_message = e.message.present? ? e.message : "Erreur Stripe inconnue"
|
||||
render json: { error: "Erreur lors du traitement de votre confirmation de paiement : #{error_message}" }, status: :bad_request
|
||||
rescue => e
|
||||
error_message = e.message.present? ? e.message : "Erreur inconnue"
|
||||
Rails.logger.error "Payment success error: #{e.class} - #{error_message}"
|
||||
render json: { error: "Une erreur inattendue s'est produite : #{error_message}" }, status: :internal_server_error
|
||||
end
|
||||
end
|
||||
|
||||
# POST /api/v1/orders/payment_cancel
|
||||
# Handles payment cancellation
|
||||
def payment_cancel
|
||||
order_id = params[:order_id] || session[:draft_order_id]
|
||||
|
||||
if order_id.present?
|
||||
order = current_user.orders.find_by(id: order_id, status: "draft")
|
||||
|
||||
if order&.can_retry_payment?
|
||||
render json: { message: "Le paiement a été annulé. Vous pouvez réessayer.", redirect_to: checkout_order_path(order) }, status: :ok
|
||||
else
|
||||
session.delete(:draft_order_id)
|
||||
render json: { message: "Le paiement a été annulé et votre commande a expiré." }, status: :gone
|
||||
end
|
||||
else
|
||||
render json: { message: "Le paiement a été annulé" }, status: :ok
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def set_order
|
||||
@order = current_user.orders.includes(:tickets, :event).find(params[:id])
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
render json: { error: "Commande non trouvée" }, status: :not_found
|
||||
end
|
||||
|
||||
def set_event
|
||||
@event = Event.includes(:ticket_types).find(params[:id])
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
render json: { error: "Événement non trouvé" }, status: :not_found
|
||||
end
|
||||
|
||||
def order_params
|
||||
params.permit(tickets_attributes: [ :ticket_type_id, :first_name, :last_name ])
|
||||
end
|
||||
|
||||
def create_stripe_session
|
||||
line_items = @order.tickets.map do |ticket|
|
||||
{
|
||||
price_data: {
|
||||
currency: "eur",
|
||||
product_data: {
|
||||
name: "#{@order.event.name} - #{ticket.ticket_type.name}",
|
||||
description: ticket.ticket_type.description
|
||||
},
|
||||
unit_amount: ticket.price_cents
|
||||
},
|
||||
quantity: 1
|
||||
}
|
||||
end
|
||||
|
||||
Stripe::Checkout::Session.create(
|
||||
payment_method_types: [ "card" ],
|
||||
line_items: line_items,
|
||||
mode: "payment",
|
||||
success_url: order_payment_success_url + "?session_id={CHECKOUT_SESSION_ID}",
|
||||
cancel_url: order_payment_cancel_url,
|
||||
metadata: {
|
||||
order_id: @order.id,
|
||||
user_id: current_user.id
|
||||
}
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user