Billing Stripe, link regia mobile e staff solo trasmissione.
Aggiunge fatturazione club, pagina regia condivisibile senza account, roster squadre e rimuove la modalità controller dall'app (v1.1.0). Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
87
backend/app/models/team_roster_member.rb
Normal file
87
backend/app/models/team_roster_member.rb
Normal file
@@ -0,0 +1,87 @@
|
||||
class TeamRosterMember < ApplicationRecord
|
||||
CATEGORIES = %w[staff coach manager player].freeze
|
||||
# Ordine di visualizzazione in pagina organico
|
||||
DISPLAY_ORDER = %w[coach manager player staff].freeze
|
||||
CATEGORY_LABELS = {
|
||||
"staff" => "Staff",
|
||||
"coach" => "Allenatori",
|
||||
"manager" => "Dirigenti",
|
||||
"player" => "Giocatori"
|
||||
}.freeze
|
||||
|
||||
VOLLEYBALL_PLAYER_ROLES = %w[
|
||||
Schiacciatore
|
||||
Opposto
|
||||
Centrale
|
||||
Palleggiatore
|
||||
Libero
|
||||
Universale
|
||||
].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
|
||||
CATEGORY_LABELS[category] || 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 "Allenatore"
|
||||
when "manager" then "Dirigente"
|
||||
when "staff" then "Staff"
|
||||
when "player" then jersey_number.present? ? "Giocatore ##{jersey_number}" : "Giocatore"
|
||||
else category
|
||||
end
|
||||
end
|
||||
|
||||
def player_role_label_valid
|
||||
return if role_label.in?(VOLLEYBALL_PLAYER_ROLES)
|
||||
|
||||
errors.add(:role_label, "non è un ruolo pallavolo valido")
|
||||
end
|
||||
|
||||
def photo_file_type
|
||||
return if photo_file.content_type.in?(%w[image/png image/jpeg image/webp])
|
||||
|
||||
errors.add(:photo_file, "deve essere PNG, JPEG o WebP")
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user