module Tournaments class Create KNOCKOUT_ROUNDS = { 16 => %w[round_of_16 quarterfinal semifinal final], 8 => %w[quarterfinal semifinal final], 4 => %w[semifinal final], 2 => %w[final] }.freeze ROUND_LABELS = { "round_of_16" => "Ottavi", "quarterfinal" => "Quarti", "semifinal" => "Semifinali", "final" => "Finale", "third_place" => "Finale 3° posto" }.freeze def self.call(club:, attrs:) new(club: club, attrs: attrs).call end def initialize(club:, attrs:) @club = club @attrs = attrs end def call Tournaments::Entitlements.new(@club).assert_creatable! tournament = @club.tournaments.build(filtered_attrs) tournament.sport_key = Sports::Catalog.normalize_key(tournament.sport_key.presence || @club.sport) Tournament.transaction do tournament.save! attach_logo!(tournament) Tournaments::EnsureBroadcastTeam.call(tournament) create_default_groups!(tournament) create_knockout_rounds!(tournament) end tournament end private def filtered_attrs @attrs.to_h.symbolize_keys.slice( :name, :sport_key, :venue, :starts_on, :ends_on, :format_kind, :description, :knockout_size, :courts ).tap do |h| h[:courts] = parse_courts(h[:courts]) if h.key?(:courts) h[:knockout_size] = h[:knockout_size].to_i if h[:knockout_size].present? h[:knockout_size] = nil if h[:knockout_size].to_i <= 0 end end def parse_courts(value) case value when Array then value else value.to_s.split(/[\n,]/) end end def attach_logo!(tournament) file = @attrs.to_h.symbolize_keys[:logo_file] tournament.logo_file.attach(file) if file.present? end def create_default_groups!(tournament) return unless tournament.uses_groups? return if tournament.groups.exists? ["Girone A", "Girone B"].each_with_index do |name, idx| tournament.groups.create!(name: name, position: idx) end end def create_knockout_rounds!(tournament) return unless tournament.uses_knockout? return if tournament.rounds.exists? size = tournament.knockout_size.presence || 4 kinds = KNOCKOUT_ROUNDS[size] || KNOCKOUT_ROUNDS[4] kinds.each_with_index do |kind, idx| tournament.rounds.create!(kind: kind, name: ROUND_LABELS[kind], position: idx) end end end end