## Backend Implementation

Enhanced TicketType model with helper methods and better validations

So the full context is:

## Backend Implementation
- Enhanced TicketType model with helper methods and better validations
- New Promoter::TicketTypesController with full authorization
- Sales status tracking (draft, available, upcoming, expired, sold_out)
- New Promoter::TicketTypesController with full authorization
- Safe calculation methods preventing nil value errors
- Sales status tracking (draft, available, upcoming, expired, sold_out)

## Frontend Features
- Modern responsive UI with Tailwind CSS styling
- Interactive forms with Stimulus controller for dynamic calculations
- Revenue calculators showing potential, current, and remaining revenue
- Status indicators with appropriate colors and icons
- Buyer analytics and purchase history display

## JavaScript Enhancements
- New TicketTypeFormController for dynamic pricing calculations
- Real-time total updates as users type price/quantity
- Proper French currency formatting
- Form validation for minimum quantities based on existing sales

## Bug Fixes
 Fixed nil value errors in price_euros method when price_cents is nil
 Added defensive programming for all calculation methods
 Graceful handling of incomplete ticket types during creation
 Proper default values for new ticket type instances

## Files Added/Modified
- app/controllers/promoter/ticket_types_controller.rb (new)
- app/javascript/controllers/ticket_type_form_controller.js (new)
- app/views/promoter/ticket_types/*.html.erb (4 new view files)
- app/models/ticket_type.rb (enhanced with helper methods)
- config/routes.rb (added nested ticket_types routes)
- db/migrate/*_add_requires_id_to_ticket_types.rb (new migration)

## Integration
- Seamless integration with existing event management system
- Updated promoter event show page with ticket management link
- Proper scoping ensuring promoters only manage their own tickets
- Compatible with existing ticket purchasing and checkout flow
This commit is contained in:
kbe
2025-09-01 00:03:35 +02:00
parent aa5dccb508
commit e838e91162
12 changed files with 1057 additions and 3 deletions

View File

@@ -0,0 +1,104 @@
# Promoter Ticket Types Controller
#
# Handles ticket type (bundle) management for promoters
# Allows promoters to create, edit, delete and manage ticket types for their events
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]
# Display all ticket types for an event
def index
@ticket_types = @event.ticket_types.order(:created_at)
end
# Display a specific ticket type
def show
# Ticket type is set by set_ticket_type callback
end
# Show form to create a new ticket type
def new
@ticket_type = @event.ticket_types.build
# Set default values
@ticket_type.sale_start_at = Time.current
@ticket_type.sale_end_at = @event.start_time || 1.week.from_now
@ticket_type.requires_id = false
end
# 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!'
else
render :new, status: :unprocessable_entity
end
end
# Show form to edit an existing ticket type
def edit
# Ticket type is set by set_ticket_type callback
end
# 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!'
else
render :edit, status: :unprocessable_entity
end
end
# 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.'
else
@ticket_type.destroy
redirect_to promoter_event_ticket_types_path(@event), notice: 'Type de billet supprimé avec succès!'
end
end
# Duplicate an existing ticket type
def duplicate
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!'
else
redirect_to promoter_event_ticket_types_path(@event), alert: 'Erreur lors de la duplication.'
end
end
private
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.'
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.'
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é.'
end
def ticket_type_params
params.require(:ticket_type).permit(
:name, :description, :price_euros, :quantity,
:sale_start_at, :sale_end_at, :minimum_age, :requires_id
)
end
end