develop #3

Merged
kbe merged 227 commits from develop into main 2025-09-16 14:35:23 +00:00
6 changed files with 119 additions and 1 deletions
Showing only changes of commit aa68885b84 - Show all commits

View File

@@ -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, :duplicate ]
# Display all events for the current promoter
def index
@@ -93,6 +93,17 @@ class Promoter::EventsController < ApplicationController
end
end
# Duplicate an event and all its ticket types
def duplicate
@new_event = @event.duplicate
if @new_event
redirect_to edit_promoter_event_path(@new_event), notice: "Événement dupliqué avec succès! Vous pouvez maintenant modifier les détails de l'événement copié."
else
redirect_to promoter_event_path(@event), alert: "Erreur lors de la duplication de l'événement."
end
end
private
def ensure_can_manage_events!

View File

@@ -102,6 +102,33 @@ class Event < ApplicationRecord
!!allow_booking_during_event
end
# Duplicate an event with all its ticket types
def duplicate
# Duplicate the event
new_event = self.dup
new_event.name = "Copie de #{name}"
new_event.slug = "#{slug}-copy-#{Time.current.to_i}"
new_event.state = :draft
new_event.created_at = Time.current
new_event.updated_at = Time.current
Event.transaction do
if new_event.save
# Duplicate all ticket types
ticket_types.each do |ticket_type|
new_ticket_type = ticket_type.dup
new_ticket_type.event = new_event
new_ticket_type.save!
end
new_event
else
nil
end
end
rescue
nil
end
private
# Determine if we should perform server-side geocoding

View File

@@ -39,6 +39,11 @@
Modifier
<% end %>
<%= button_to duplicate_promoter_event_path(@event), method: :post, class: "w-full sm:w-auto inline-flex items-center justify-center px-4 py-2 bg-blue-600 text-white font-medium rounded-lg hover:bg-blue-700 transition-colors duration-200" do %>
<i data-lucide="copy" class="w-4 h-4 mr-2"></i>
Dupliquer
<% end %>
<% if @event.draft? %>
<% if @event.ticket_types.blank? %>
<%= button_to publish_promoter_event_path(@event), method: :patch, disabled: true, class: "w-full sm:w-auto inline-flex items-center justify-center px-4 py-2 bg-gray-400 text-white font-medium rounded-lg cursor-not-allowed transition-colors duration-200", title: "Vous devez créer au moins un type de billet avant de publier" do %>

View File

@@ -81,6 +81,7 @@ Rails.application.routes.draw do
patch :unpublish
patch :cancel
patch :mark_sold_out
post :duplicate
end
# Nested ticket types routes

View File

@@ -26,5 +26,55 @@ class Promoter::EventsControllerTest < ActionDispatch::IntegrationTest
assert_not_includes assigns(:events), other_event
end
test "should duplicate an event with ticket types" do
sign_in @promoter
# Create ticket types for the event
ticket_type1 = TicketType.create!(
name: "Standard Ticket",
description: "A standard ticket for the event with all the basic access",
price_cents: 2000,
quantity: 100,
sale_start_at: 1.day.ago,
sale_end_at: @event.start_time - 1.hour,
event: @event
)
ticket_type2 = TicketType.create!(
name: "VIP Ticket",
description: "A VIP ticket for the event with special access",
price_cents: 5000,
quantity: 50,
sale_start_at: 1.day.ago,
sale_end_at: @event.start_time - 1.hour,
event: @event
)
# Verify that ticket types were created successfully
assert ticket_type1.valid?
assert ticket_type2.valid?
# Duplicate the event
assert_difference('Event.count', 1) do
post duplicate_promoter_event_path(@event)
end
# Check that the new event was created
assert_redirected_to edit_promoter_event_path(Event.last)
assert_equal "Événement dupliqué avec succès! Vous pouvez maintenant modifier les détails de l'événement copié.", flash[:notice]
# Check that the new event has the correct attributes
new_event = Event.last
assert_equal "Copie de #{@event.name}", new_event.name
assert_equal "draft", new_event.state
assert_equal @event.venue_name, new_event.venue_name
assert_equal @event.venue_address, new_event.venue_address
# Check that ticket types were duplicated
assert_equal 2, new_event.ticket_types.count
assert_equal "Standard Ticket", new_event.ticket_types.find_by(name: "Standard Ticket").name
assert_equal "VIP Ticket", new_event.ticket_types.find_by(name: "VIP Ticket").name
end
# Add tests for new, create, etc. as needed
end

View File

@@ -271,4 +271,28 @@ class EventTest < ActiveSupport::TestCase
event = Event.new
assert_not event.allow_booking_during_event?
end
test "should duplicate event with ticket types" do
user = User.create!(email: "test@example.com", password: "password123", password_confirmation: "password123")
event = Event.create!(name: "Original Event", slug: "original", description: "A description that is sufficiently long", venue_name: "v", venue_address: "a", user: user, latitude: 48.0, longitude: 2.0, start_time: 1.week.from_now, state: :published)
# Create ticket types
ticket_type1 = TicketType.create!(name: "Standard", description: "A standard ticket for the event", price_cents: 2000, quantity: 100, sale_start_at: 1.day.ago, sale_end_at: event.start_time - 1.hour, event: event)
ticket_type2 = TicketType.create!(name: "VIP", description: "A VIP ticket for the event", price_cents: 5000, quantity: 50, sale_start_at: 1.day.ago, sale_end_at: event.start_time - 1.hour, event: event)
# Duplicate the event
duplicated_event = event.duplicate
# Check that duplication was successful
assert_not_nil duplicated_event
assert_equal "Copie de #{event.name}", duplicated_event.name
assert_equal "draft", duplicated_event.state
assert_equal event.venue_name, duplicated_event.venue_name
assert_equal event.venue_address, duplicated_event.venue_address
# Check that ticket types were duplicated
assert_equal 2, duplicated_event.ticket_types.count
assert_equal "Standard", duplicated_event.ticket_types.find_by(name: "Standard").name
assert_equal "VIP", duplicated_event.ticket_types.find_by(name: "VIP").name
end
end