class TeamRosterMember < ApplicationRecord CATEGORIES = %w[staff coach manager player].freeze # Ordine di visualizzazione in pagina organico DISPLAY_ORDER = %w[coach manager player staff].freeze def self.category_label(category) I18n.t("roster.category.#{category}", default: category.to_s.capitalize) end VOLLEYBALL_PLAYER_ROLES = Sports::PlayerRoles::BY_BOARD["volley"].freeze belongs_to :team has_one_attached :photo_file validates :full_name, presence: true validates :category, inclusion: { in: CATEGORIES } validates :jersey_number, numericality: { only_integer: true, greater_than: 0, less_than: 100 }, allow_nil: true validate :photo_file_type, if: -> { photo_file.attached? } validate :player_role_label_valid, if: -> { category == "player" && role_label.present? } before_validation :assign_position, on: :create scope :ordered, -> { order(:position, :created_at) } scope :by_category, ->(cat) { where(category: cat).ordered } def category_label self.class.category_label(category) end def initials parts = full_name.to_s.split(/\s+/).reject(&:blank?) return "?" if parts.empty? parts.first(2).map { |p| p[0] }.join.upcase end def photo_url return unless photo_file.attached? Rails.application.routes.url_helpers.rails_blob_path(photo_file, only_path: true) end def display_role role_label.presence || default_role_label end private def assign_position return if position.positive? || team.blank? max_pos = team.roster_members.where(category: category).maximum(:position) || -1 self.position = max_pos + 1 end def default_role_label case category when "coach" then I18n.t("roster.role.coach") when "manager" then I18n.t("roster.role.manager") when "staff" then I18n.t("roster.role.staff") when "player" jersey_number.present? ? I18n.t("roster.role.player_numbered", number: jersey_number) : I18n.t("roster.role.player") else category end end def player_role_label_valid allowed = Sports::PlayerRoles.for_team(team) return if role_label.in?(allowed) errors.add(:role_label, I18n.t("roster.errors.role_invalid")) end def photo_file_type return if photo_file.content_type.in?(%w[image/png image/jpeg image/webp]) errors.add(:photo_file, I18n.t("roster.errors.photo_invalid_type")) end end